Dependencies are external libraries your project needs. Without Maven, you'd go to 10 different websites, download JAR files, and manually add them to your project. With Maven, you add 5 lines of XML and Maven handles everything — including libraries that your libraries need (transitive dependencies).
Not every library needs to be available at every stage. Scope controls when a dependency is available.
| Scope | Available During | Included in Package | Use For |
|---|---|---|---|
| compile (default) | Compile + Test + Runtime | Yes | selenium-java, apache-poi, webdrivermanager |
| test | Test only | No | testng, allure-testng, junit |
| provided | Compile + Test (not runtime) | No | lombok, servlet-api |
| runtime | Test + Runtime (not compile) | Yes | JDBC drivers, logging implementations |
Q: What is the difference between compile and test scope in Maven?
A: Compile scope (default) makes the dependency available during compilation, testing, and runtime — it's included in the final package. Test scope makes the dependency available only during test compilation and execution — it's NOT included in the final package. We use test scope for TestNG and Allure because they're only needed when running tests, not in the deployed application. Selenium typically uses compile scope because our utility classes in src/main/java might reference it.
<!-- The essential QA automation stack -->
<dependencies>
<!-- Browser Automation -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>
<!-- Auto-download browser drivers -->
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.7.0</version>
</dependency>
<!-- Test framework -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<scope>test</scope>
</dependency>
<!-- Reporting -->
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>2.25.0</version>
<scope>test</scope>
</dependency>
<!-- Excel data-driven testing -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
<!-- API testing -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<!-- Fake test data -->
<dependency>
<groupId>com.github.javafaker</groupId>
<artifactId>javafaker</artifactId>
<version>1.0.2</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.22.1</version>
</dependency>
</dependencies>When you add selenium-java, Maven also downloads 15+ other libraries that Selenium needs internally — like Guava, OkHttp, and browser-specific drivers. These are transitive dependencies. You don't declare them — Maven resolves them automatically.
# See ALL dependencies — including transitive ones
mvn dependency:tree
# Output shows the dependency tree:
# com.testerrank:banking-portal-automation:jar:1.0-SNAPSHOT
# +- org.seleniumhq.selenium:selenium-java:jar:4.18.1:compile
# | +- org.seleniumhq.selenium:selenium-api:jar:4.18.1:compile
# | +- org.seleniumhq.selenium:selenium-chrome-driver:jar:4.18.1:compile
# | +- org.seleniumhq.selenium:selenium-support:jar:4.18.1:compile
# | +- com.google.guava:guava:jar:33.0.0-jre:compile
# | \- ...Sometimes a transitive dependency causes conflicts. You can exclude specific ones:
<!-- Exclude Safari driver if you never test on Safari -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
<exclusions>
<exclusion>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-safari-driver</artifactId>
</exclusion>
</exclusions>
</dependency>Run mvn dependency:tree often. It shows you everything Maven is downloading — including versions of transitive dependencies. This is your first debugging tool when you get "NoSuchMethodError" or "ClassNotFoundException" — it usually means two libraries need different versions of the same dependency.
Key Point: Maven downloads libraries and their sub-dependencies automatically. Use scopes to control when each library is available.