Selenium · Browser automation foundations
How do you integrate Selenium with TestNG or JUnit?
Short answer
Use the framework's lifecycle hooks to create a driver before each test and quit it afterward. Keep setup, teardown and configuration in a base class or extension, and let tests contain only intent and assertions.
The runner owns discovery, ordering, parallelism and reporting. Selenium only drives the browser. A base class or extension is the natural place for driver creation, navigation, screenshots on failure and cleanup.
public abstract class BaseTest {
protected WebDriver driver;
@BeforeMethod
public void setUp() {
driver = DriverFactory.create();
}
@AfterMethod(alwaysRun = true)
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
public class LoginTest extends BaseTest {
@Test
public void userCanSignIn() {
new LoginPage(driver).signIn("asha@example.com", "correct-horse");
Assert.assertTrue(driver.getCurrentUrl().contains("/dashboard"));
}
}- TestNG uses @BeforeMethod and @AfterMethod; JUnit 5 uses @BeforeEach and @AfterEach
- alwaysRun or equivalent ensures cleanup runs after a failure
- Screenshots on failure belong in a listener, not in every test
- Parallel configuration belongs in the runner configuration, not in test code
- Keep test data creation explicit so failures are reproducible
A common mistake is a static shared driver. It makes tests interfere through cookies, navigation and window state, and it breaks as soon as parallelism is enabled. One driver per test method is the simplest safe default; use a suite-level driver only for a deliberate, isolated smoke flow.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why is a static driver a problem?
- 2Where do screenshots on failure belong?
- 3How do you ensure teardown runs after a failure?
- 4When would one driver per suite be acceptable?
Say it in the interview
I use the runner's lifecycle hooks to create a driver before each test and quit it after, with cleanup marked to run even after failures. The base class or extension handles driver creation and diagnostics, so tests only express intent and assertions. I avoid static shared drivers because they leak cookies and window state and break under parallelism. Failure screenshots live in a listener so every test benefits without extra code.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Selenium mock interview and get scored feedback on depth, clarity and confidence.