How to Use TestNG Assertions in Selenium Tests
Use TestNG assertions to verify Selenium results in Java, synchronize checks with dynamic pages, and troubleshoot common assertion failures.
Use a TestNG assertion to compare the result Selenium observed with the value your test expects. For dynamic pages, first wait for the expected state, then read and assert it. Selenium drives the browser; TestNG runs the test and records an assertion failure.
This guide uses Java, Selenium WebDriver, and TestNG. It shows assertions for a page title, visible text, and an input value, and explains how to avoid timing-related failures.
1. Add Selenium and TestNG
The following Maven dependencies are sufficient for the example. These version values are illustrative; check the projects’ official documentation for current versions before adopting them.
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>YOUR_SELENIUM_VERSION</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>YOUR_TESTNG_VERSION</version>
<scope>test</scope>
</dependency>
</dependencies>
Configure your build to run TestNG tests, and provide a WebDriver browser driver in the environment. Selenium’s documentation describes TestNG as one Java test runner and also discusses JUnit as another option. See Selenium’s guide to organizing and executing code.
2. Write a Selenium test with TestNG assertions
This example opens a page, submits a search, waits for the results heading, and checks observable outcomes. Replace the example URL and selectors with those for your application.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
import java.time.Duration;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
public class SearchTest {
@Test
public void searchShowsExpectedResults() {
WebDriver driver = new ChromeDriver();
try {
driver.get("https://example.com/search");
WebElement search = driver.findElement(By.name("q"));
search.sendKeys("selenium");
search.submit();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement heading = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector("h1.results-title"))
);
assertEquals(driver.getTitle(), "Search results | Example");
assertTrue(heading.getText().contains("selenium"));
} finally {
driver.quit();
}
}
}
The static imports let you call assertEquals and assertTrue directly. The expected value comes first and the actual value second. When an assertion fails, TestNG reports the test method as failed because the assertion throws an AssertionError.
3. Choose an assertion for the browser result
| What to verify | Read it from Selenium | Example assertion |
|---|---|---|
| Page title | driver.getTitle() |
assertEquals(driver.getTitle(), "Account | Example"); |
| Visible text | element.getText() |
assertTrue(message.getText().contains("Saved")); |
| Input value | element.getAttribute("value") |
assertEquals(email.getAttribute("value"), "dev@example.com"); |
| Visibility | element.isDisplayed() |
assertTrue(success.isDisplayed()); |
Prefer checking a user-visible result of the action: the title after navigation, a confirmation after saving, or a result list after submitting a search. Comparing expected and actual values makes failures easier to diagnose. For more complex comparisons, TestNG’s documentation demonstrates using JUnit’s Assert API as well; choose an assertion library that fits your project and keep the expected and observed values clear. See TestNG documentation.
4. Wait for dynamic pages before asserting
A navigation call can return before client-side JavaScript has rendered the state your test needs. If the test reads too early, the assertion may see an old title, missing text, or an element that is not ready. Selenium describes this as a timing race and recommends waiting for a specific condition.
- Perform the browser action, such as clicking Submit.
- Wait for the condition that represents the completed result.
- Read the relevant title, text, or value.
- Assert that the observed value matches the expectation.
For example, wait for visible confirmation text:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement confirmation = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("save-confirmation"))
);
assertEquals(confirmation.getText(), "Changes saved");
Other useful expected conditions include element presence, text visibility, and title content. Choose the condition that signals the result you intend to verify. A fixed sleep can waste time when a page is fast and still fail when it is slow. Selenium’s waiting strategies guide explains explicit waits and their conditions.
Do not mix implicit and explicit waits
An implicit wait applies globally to element location calls; Selenium documents its default as zero. Explicit waits poll for a particular condition. Selenium warns that combining the two can make timeout behavior unpredictable. Prefer explicit waits for the relevant state and avoid setting a nonzero implicit wait in the same test suite.
5. Java assert versus assertion methods
Java’s language-level assert statement is different from TestNG’s assertion methods:
assert actualTitle.equals(expectedTitle) : "Unexpected page title";
If this language-level statement seems not to run, check that the JVM was started with assertions enabled using -ea. TestNG’s documentation calls out this requirement. TestNG assertion methods such as assertEquals do not depend on the Java assert keyword being enabled.
Use the assertion style supported by your project conventions. In either case, synchronize with the page first and check an outcome that represents the browser action.
6. Troubleshooting common failures
| Symptom | Likely cause | Fix |
|---|---|---|
| Assertion fails with an old title or missing text | The page has not reached the expected state. | Wait for a condition tied to the result, then read and assert. |
NoSuchElementException before the assertion |
The locator was queried before the element existed, or the locator is incorrect. | Verify the selector against the current page and wait for presence or visibility as appropriate. |
Java assert appears to do nothing |
The JVM may not have assertions enabled. | Run with -ea, or use TestNG assertion methods. |
| Text comparison fails despite looking right | The page may include extra whitespace, different capitalization, or additional text. | Inspect the actual string in the test report; normalize only the differences your requirement allows. |
| Waits time out inconsistently | Implicit and explicit waits may be combined, or the condition does not describe the true ready state. | Use one clear explicit condition and avoid mixing wait strategies. |
| Browser remains open after a failed assertion | Driver cleanup did not run after the failure. | Put driver.quit() in a finally block or your test framework’s teardown method. |
7. Reliability, runtime, and cost
- Reliability: assert stable outcomes and wait for the state that proves the action completed. Avoid guessed pauses and overly broad checks that can pass for the wrong reason.
- Runtime: explicit waits poll until their condition succeeds or the timeout expires. Keep timeouts appropriate to the application and use conditions that become true as soon as the desired state is ready.
- Parallel runs: Selenium identifies parallel execution and parameterized tests among TestNG’s features. Ensure each parallel test has its own browser session and does not depend on shared mutable state.
- Cost: Selenium and TestNG are software dependencies; this example adds no screenshot service. Browser infrastructure and CI execution may have costs determined by your environment.
8. Capture a screenshot when an assertion fails
A screenshot can help explain what the browser displayed when a check failed. With Selenium, capture it before quitting the driver:
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
File image = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(image.toPath(), Path.of("failure.png"));
In a test framework, put failure capture in your reporting or teardown flow so it runs when needed and save the artifact with the test result. For a browser capture without managing a WebDriver session, ScreenshotNeo provides a website screenshot API and MCP server.
9. Or skip the browser setup
If the goal is to capture how a page looks, ScreenshotNeo takes a URL in one request and returns an image or PDF. This does not replace a Selenium assertion: use Selenium and TestNG to verify application behavior, and use a screenshot capture when you need a visual artifact.
See the ScreenshotNeo API documentation for options. cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up free for 1,000 screenshots a month, with no card required.
10. FAQ
Does TestNG drive the browser?
No. Selenium WebDriver performs browser actions and exposes observed state. TestNG runs the test and reports its outcome.
Can I assert a page title in Selenium?
Yes. Read it with driver.getTitle(), wait for the expected title if navigation is asynchronous, and compare it with an assertion.
Why does a passing browser action still lead to a failed assertion?
The action may have completed while the page is still updating. Wait for the resulting state before checking it.
Is TestNG the only Java test runner for Selenium?
No. Selenium’s documentation also identifies JUnit as a Java test-runner option.


