CI/CD Tools
TestNG XML Generator for Parallel & Cross-Browser Suites
Build a valid testng.xml without memorising the DTD. Pick a
parallel mode and thread count, tick the browsers for cross-browser
<test> blocks, filter by smoke or regression groups, add
listeners and parameters — then copy or download the suite file. The preview updates live,
and everything runs in your browser.
Why hand-written testng.xml files break
The TestNG DTD is strict about element order: inside a <test> block,
<parameter> comes before <groups>, which comes before
<classes> or <packages> — get it wrong and IntelliJ
flags the file or the run silently ignores your filters. Add the confusion between
thread-count and data-provider-thread-count, the missing
DOCTYPE that disables IDE validation, and browser parameters placed at suite
level (where they can never run browsers in parallel), and most hand-written suite files
carry at least one of these defects. This generator encodes the correct structure so the
file you download is the file you would write after reading the TestNG documentation end
to end.
What it generates
- Parallel execution —
parallel="methods|classes|tests|instances"with a matchingthread-count, plus optionaldata-provider-thread-count,verbose,time-outandpreserve-order. - Cross-browser blocks — one
<test>per browser (Chrome, Firefox, Edge, Safari) with a<parameter name="browser">each, the pattern that actually parallelises browsers. - Group filtering —
<include>and<exclude>under<groups><run>for smoke, regression, sanity or any custom group. - Fine-grained targeting — classes, whole packages, or single methods via
<methods><include>. - Listeners & parameters —
<listeners>for reporters/retry analyzers and suite-level<parameter>entries forbaseUrl,envor a GridhubUrl. - Valid XML, always — DOCTYPE header, DTD-ordered elements and escaped attribute values.
TestNG parallel modes at a glance
| Mode | What runs in parallel | Typical use |
|---|---|---|
methods | Every @Test method | Fastest wall-clock time; needs fully thread-safe tests |
classes | Each test class (methods inside stay sequential) | Safe default when classes share state internally |
tests | Each <test> block in the XML | Cross-browser and cross-environment suites |
instances | Instances created by @Factory | Data-driven suites built from factories |
omitted / none | Nothing — sequential run | Debugging, ordered end-to-end flows |
The cross-browser pattern that actually runs in parallel
A single suite-level browser parameter can only ever start one browser. The pattern that
works is parallel="tests" with one <test> block per browser,
each carrying its own parameter — exactly what the Cross-Browser preset produces:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Cross Browser Suite" parallel="tests" thread-count="3">
<test name="Chrome Tests">
<parameter name="browser" value="chrome"/>
<classes>
<class name="com.example.tests.LoginTest"/>
</classes>
</test>
<test name="Firefox Tests">
<parameter name="browser" value="firefox"/>
<classes>
<class name="com.example.tests.LoginTest"/>
</classes>
</test>
<test name="Edge Tests">
<parameter name="browser" value="edge"/>
<classes>
<class name="com.example.tests.LoginTest"/>
</classes>
</test>
</suite> Reading the browser parameter in your test code
Pair the generated XML with a base class that turns the parameter into a driver.
@Optional keeps the class runnable outside the suite file, and
alwaysRun = true makes setup fire even when group filters are active:
public class CrossBrowserBase {
protected WebDriver driver;
@BeforeMethod(alwaysRun = true)
@Parameters("browser")
public void setUp(@Optional("chrome") String browser) {
driver = DriverFactory.create(browser); // chrome, firefox, edge, safari
}
@AfterMethod(alwaysRun = true)
public void tearDown() {
if (driver != null) driver.quit();
}
}
If you are building the framework around this file, our
REST Assured + TestNG framework write-up
covers the thread-safety decisions — immutable specs and ThreadLocal reporting — that make
parallel="methods" boring in a good way.
How to use it
- Pick a preset (Cross-Browser, Smoke, Regression, Parallel Methods or Selenium Grid) or configure from scratch.
- Adjust the parallel mode, thread count, browsers, groups and classes — the preview updates as you type.
- Click Copy or Download to get
testng.xml. - Put it next to
pom.xml, wire it into Maven Surefire (snippet included) or right-click-run it in your IDE.
Frequently asked questions
How do I create a testng.xml file for parallel execution?
Add the parallel and thread-count attributes to the <suite> tag, for example <suite name="Suite" parallel="methods" thread-count="4">. parallel decides what TestNG distributes across threads (methods, classes, tests or instances) and thread-count sets the size of the thread pool. This generator emits both, plus the DOCTYPE line that lets IDEs validate the file, and keeps the element order the TestNG DTD expects — parameters before groups before classes inside each <test>.
What is the difference between thread-count and data-provider-thread-count?
thread-count sizes the pool TestNG uses for parallel="methods", "classes" or "tests" — regular test execution. data-provider-thread-count sizes a separate pool used only for tests fed by a @DataProvider(parallel = true); its default is 10. They are independent: a suite can run classes on 4 threads while a parallel data provider fans its rows out on 10 threads at the same time.
How do I run the same tests in Chrome, Firefox and Edge with one testng.xml?
Create one <test> block per browser, give each block a <parameter name="browser" value="chrome"/> (then firefox, edge and so on), and set parallel="tests" on the suite so every block gets its own thread. In your code, read the value with @Parameters("browser") on your @BeforeMethod and start the matching driver. Tick the browsers in the generator and it writes the blocks, parameters and a matching thread count for you.
How do I build smoke and regression suites with TestNG groups?
Tag tests with @Test(groups = {"smoke"}) or groups = {"regression"}, then filter in the XML with <groups><run><include name="smoke"/></run></groups>. Excludes such as <exclude name="wip"/> remove flaky or in-progress tests, and an exclude always beats an include for the same group. Most teams keep separate files — smoke.xml and regression.xml — and point each CI pipeline stage at the right one.
What do parallel="methods", "classes", "tests" and "instances" mean?
methods runs every @Test method concurrently — the fastest mode, but it requires fully thread-safe test code. classes gives each test class its own thread while the methods inside it stay sequential. tests parallelises whole <test> blocks, which is the mode cross-browser suites need. instances parallelises test instances created via @Factory. When the attribute is omitted (or set to none) everything runs sequentially, and thread-count is ignored.
Where does testng.xml go and how do I run it?
Put it at the project root next to pom.xml, or under src/test/resources. Run it from IntelliJ IDEA or Eclipse by right-clicking the file, from Maven by listing it in the Surefire plugin’s <suiteXmlFiles> (this page includes a copy-ready snippet), or from Gradle with useTestNG { suites "testng.xml" }. The generator itself runs entirely in your browser — class names, group names and parameters are never uploaded anywhere.