Chapter 5: Build a Real Test Suite
testng.xml is the master control panel for your test execution. It decides which tests run, in what order, with which parameters, and how many run in parallel. Think of it like a TV remote — same TV, but the remote controls what you watch.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TesterRank Regression Suite"
parallel="classes"
thread-count="3"
verbose="1">
<!-- Global browser parameter -->
<parameter name="browser" value="chrome" />
<!-- Register listeners globally -->
<listeners>
<listener class-name=
"com.testerrank.listeners.TestListener" />
</listeners>
<!-- Banking Portal Tests -->
<test name="Banking Portal">
<classes>
<class name=
"com.testerrank.tests.banking.LoginTests" />
<class name=
"com.testerrank.tests.banking.BankingE2ETests" />
</classes>
</test>
<!-- Shopping Portal Tests -->
<test name="Shopping Portal">
<classes>
<class name=
"com.testerrank.tests.shopping.ShoppingE2ETests" />
</classes>
</test>
</suite><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Smoke Suite">
<listeners>
<listener class-name=
"com.testerrank.listeners.TestListener" />
</listeners>
<test name="Smoke Tests">
<groups>
<run>
<include name="smoke" />
</run>
</groups>
<packages>
<package name="com.testerrank.tests.*" />
</packages>
</test>
</suite><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Parallel Regression"
parallel="classes"
thread-count="4">
<listeners>
<listener class-name=
"com.testerrank.listeners.TestListener" />
</listeners>
<!-- Run banking on Firefox -->
<test name="Banking on Firefox">
<parameter name="browser" value="firefox" />
<groups>
<run>
<include name="regression" />
</run>
</groups>
<packages>
<package name="com.testerrank.tests.banking" />
</packages>
</test>
<!-- Run shopping on Chrome -->
<test name="Shopping on Chrome">
<parameter name="browser" value="chrome" />
<groups>
<run>
<include name="regression" />
</run>
</groups>
<packages>
<package name="com.testerrank.tests.shopping" />
</packages>
</test>
</suite>| parallel="methods" | parallel="classes" |
|---|---|
| Each test method runs in its own thread | Each test class runs in its own thread |
| Fastest execution but most complex | Methods within a class run sequentially |
| Requires ThreadLocal for WebDriver | Safer — class-level setup is thread-safe |
| Shared @BeforeClass can cause issues | Good balance of speed and stability |
| Use when tests are truly independent | Most commonly used in real projects |
<!-- Run specific methods from a class -->
<test name="Selected Banking Tests">
<classes>
<class name="com.testerrank.tests.banking.LoginTests">
<methods>
<include name="testSuccessfulLogin" />
<include name="testLogout" />
<exclude name="testLoginDataDriven" />
</methods>
</class>
</classes>
</test>
<!-- Exclude a group -->
<test name="No Slow Tests">
<groups>
<run>
<include name="regression" />
<exclude name="slow" />
</run>
</groups>
<packages>
<package name="com.testerrank.tests.*" />
</packages>
</test>Q: How do you configure parallel execution in TestNG? What is the difference between parallel="methods" and parallel="classes"?
A: In testng.xml, you set parallel attribute on the suite tag. parallel="classes" runs each test class in a separate thread — methods within a class still run sequentially. parallel="methods" runs each test method in its own thread, which is faster but requires ThreadLocal for WebDriver to avoid thread interference. parallel="tests" runs each <test> block in its own thread. I typically use parallel="classes" with thread-count="3" or "4" because it gives good speed improvement while keeping things manageable. Combined with ThreadLocal in BaseTest, this is safe and reliable.
# Run the master regression suite
mvn test -DsuiteXmlFile=testng.xml
# Run only smoke tests
mvn test -DsuiteXmlFile=testng-smoke.xml
# Run with groups via command line (no XML needed)
mvn test -Dgroups=smoke
# Run a specific test class
mvn test -Dtest="com.testerrank.tests.banking.LoginTests"
# Run a specific method
mvn test -Dtest="LoginTests#testSuccessfulLogin"
# Run in headless Chrome for CI
mvn test -DsuiteXmlFile=testng.xml -Dheadless=true
# Run against staging with Firefox
mvn test -DsuiteXmlFile=testng.xml \
-Dbase.url=https://staging.testerrank.com \
-Dbrowser=firefox -Dheadless=true
# Clean build and run
mvn clean test -DsuiteXmlFile=testng.xmlWhen running tests in parallel, never share WebDriver between threads. Each thread must get its own driver instance via ThreadLocal. Also avoid static mutable state — static counters, shared lists, or static WebDriver references will cause random failures in parallel.
Keep thread-count equal to or less than the number of CPU cores on your machine. Setting thread-count=10 on a 4-core machine just causes thread contention and actually slows things down. In CI, match the thread count to the container resources.
Key Point: testng.xml controls what runs, how it runs, and how fast it runs. Use parallel="classes" with ThreadLocal for safe, fast execution.