TestNG Cheat Sheet
Everything you use from TestNG in a Selenium or API framework, on one page. For explanations and full examples, see TestNG Essentials.
Annotation Order ⭐
@BeforeSuite
@BeforeTest (once per <test> in testng.xml)
@BeforeClass
@BeforeMethod
@Test
@AfterMethod
@AfterClass
@AfterTest
@AfterSuite
| Annotation | Runs | Typical use |
|---|---|---|
@BeforeSuite / @AfterSuite |
Once for the whole suite | Load config, start and flush reports |
@BeforeTest / @AfterTest |
Once per <test> block |
Per-browser or per-environment setup |
@BeforeClass / @AfterClass |
Once per test class | Shared class data |
@BeforeMethod / @AfterMethod |
Around every @Test |
Start browser / screenshot on failure and quit |
@BeforeGroups / @AfterGroups |
Around the first/last method of a group | Group-specific setup |
@DataProvider |
Supplies data to a test | Data-driven tests |
@Parameters |
Reads values from testng.xml | Browser, environment |
@Listeners |
Registers listeners on a class | Reporting, screenshots |
@Factory |
Creates test-class instances dynamically | Same class, different data |
Use @AfterMethod(alwaysRun = true) so the browser closes even when a test or setup fails.
@Test Attributes
| Attribute | Example | Effect |
|---|---|---|
priority |
@Test(priority = 1) |
Execution order (lower first) |
groups |
@Test(groups = {"smoke", "regression"}) |
Tags the test |
dependsOnMethods |
@Test(dependsOnMethods = "login") |
Skipped if login fails |
dependsOnGroups |
@Test(dependsOnGroups = "setup") |
Depends on a whole group |
alwaysRun |
@Test(alwaysRun = true) |
Runs even if dependencies failed |
enabled |
@Test(enabled = false) |
Disables the test |
invocationCount |
@Test(invocationCount = 3) |
Runs it 3 times |
timeOut |
@Test(timeOut = 5000) |
Fails after 5 seconds |
dataProvider |
@Test(dataProvider = "users") |
Runs once per data row |
expectedExceptions |
@Test(expectedExceptions = IllegalStateException.class) |
Passes only if that exception is thrown |
retryAnalyzer |
@Test(retryAnalyzer = Retry.class) |
Re-runs on failure |
description |
@Test(description = "Valid login") |
Shown in reports |
Priority Rules
- Default priority is 0; negative values are allowed.
- Lower values run first.
- Equal priorities run in alphabetical method-name order.
- Priority only orders tests. It doesn't skip anything when a test fails.
- Use dependencies when one test genuinely depends on another.
Assertions
Hard Assertions
Hard assertions stop the test at the first failure.
// Hard assertions — stop the test at the first failure
Assert.assertEquals(
actual,
expected,
"Title mismatch"
);
Assert.assertNotEquals(
actual,
unexpected
);
Assert.assertTrue(
condition,
"Button should be enabled"
);
Assert.assertFalse(condition);
Assert.assertNull(object);
Assert.assertNotNull(object);
Assert.fail("Should not reach here");
Soft Assertions
Soft assertions collect failures and report them at the end.
SoftAssert soft = new SoftAssert();
soft.assertEquals(
header.getText(),
"Welcome"
);
soft.assertTrue(
logo.isDisplayed(),
"Logo missing"
);
soft.assertAll();
assertAll() is required. Without it, the test can pass even when soft assertions have failed.
Important: TestNG uses:
Assert.assertEquals(actual, expected);
Getting the order backwards can produce confusing failure messages.
Compare assertion styles across frameworks in the Assertion Explorer.
DataProvider
@DataProvider(name = "loginData", parallel = false)
public Object[][] loginData() {
return new Object[][] {
{"standard_user", "secret_sauce"},
{"locked_out_user", "secret_sauce"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
// runs once per row
}
// Provider in another class — the method must be static
@Test(
dataProvider = "loginData",
dataProviderClass = LoginData.class
)
public void loginFromSharedData(
String username,
String password
) {}
A DataProvider can return:
-
Object[][] -
Iterator<Object[]>
Keep real credentials out of source code. Read them from configuration or environment variables.
Parameters From testng.xml
@Parameters({"browser", "env"})
@BeforeMethod
public void setUp(
@Optional("chrome") String browser,
@Optional("qa") String env
) {}
testng.xml
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="RegressionSuite"
parallel="tests"
thread-count="3">
<listeners>
<listener class-name="com.company.listeners.TestListener"/>
</listeners>
<test name="ChromeTests">
<parameter name="browser" value="chrome"/>
<groups>
<run>
<include name="smoke"/>
<exclude name="wip"/>
</run>
</groups>
<classes>
<class name="com.company.tests.LoginTest"/>
<class name="com.company.tests.CartTest">
<methods>
<include name="addToCart"/>
</methods>
</class>
</classes>
</test>
</suite>
| Attribute | Values |
|---|---|
parallel |
methods, classes, tests, instances |
thread-count |
Maximum threads (default 5) |
preserve-order |
Keep class/method order from the XML (default true) |
verbose |
Console detail level (0–10) |
Parallel runs need one WebDriver per thread — see Parallel Execution & Grid.
Listeners ⭐
| Method | Called when |
|---|---|
onStart(ITestContext) |
A <test> block starts |
onTestStart(ITestResult) |
A test starts |
onTestSuccess |
A test passes |
onTestFailure |
A test fails — take the screenshot here |
onTestSkipped |
A test is skipped |
onFinish(ITestContext) |
A <test> block finishes — flush reports |
Register a listener with:
@Listeners(TestListener.class)
on a class, or in testng.xml as shown above. Registering it in testng.xml can apply it to the suite.
Retry Failed Tests
public class Retry implements IRetryAnalyzer {
private int count = 0;
private static final int MAX = 1;
@Override
public boolean retry(ITestResult result) {
return count++ < MAX;
}
}
Returning true causes TestNG to run the test again.
You can also re-run only the failures from the last run with the generated:
test-output/testng-failed.xml
Retries can hide flaky tests, so log retry occurrences and investigate the underlying cause.
Running From Maven
mvn test
# suite(s) configured in Surefire
mvn test -Dsurefire.suiteXmlFiles=smoke.xml
# a specific testng.xml
mvn test -Dtest=LoginTest
# one class
mvn test -Dtest=LoginTest#validLogin
# one method
mvn test -Dgroups=smoke
# one group
mvn test -Dbrowser=firefox -Denv=staging
# system properties for your config
Surefire writes XML results to:
target/surefire-reports/
These reports can be read by Jenkins.
TestNG's HTML reports go to:
test-output/
when run directly.
More: Maven for Selenium.
Common Tasks
| Task | How |
|---|---|
| Skip a test at runtime | throw new SkipException("reason") |
| Disable a test | @Test(enabled = false) |
| Run only smoke tests | <include name="smoke"/> or -Dgroups=smoke |
| Re-run failures | testng-failed.xml or IRetryAnalyzer |
| Cross-browser runs | One <test> per browser with a browser parameter and parallel="tests" |
| Screenshot on failure | onTestFailure in a listener or @AfterMethod checking ITestResult |
From Real Projects
Across Apkope, Canolog and Testsigma I've done both manual testing and Selenium automation in Java with TestNG, tracked execution in TestRail and defects in Jira, and worked in Agile teams. The topics on this page connect directly to that day-to-day work. Keep groups, priorities and data providers in one place so the suite stays easy to read.
📚 Official documentation: TestNG documentation
FAQs
What is the order of TestNG annotations?
BeforeSuite → BeforeTest → BeforeClass → BeforeMethod → Test → AfterMethod → AfterClass → AfterTest → AfterSuite.
What is the default priority?
The default priority is 0. Lower values run first, and equal priorities run alphabetically by method name.
Hard assert vs soft assert?
A hard assert stops the test at the first failure. A soft assert collects failures and reports them all when assertAll() is called.
How do you run failed tests again?
Run testng-failed.xml, or add an IRetryAnalyzer for automatic retries.
How do you run one group from the command line?
mvn test -Dgroups=smoke