0
0
Selenium Javatesting~15 mins

TestNG annotations (@Test, @BeforeMethod, @AfterMethod) in Selenium Java - Deep Dive

Choose your learning style9 modes available
Overview - TestNG annotations (@Test, @BeforeMethod, @AfterMethod)
What is it?
TestNG annotations are special markers in Java code that tell the TestNG testing framework how to run your tests. The @Test annotation marks a method as a test case. @BeforeMethod and @AfterMethod annotations mark methods that run before and after each test method, respectively. These annotations help organize and control the flow of automated tests.
Why it matters
Without these annotations, you would have to manually write code to run tests in order and set up or clean up before and after each test. This would be error-prone and hard to maintain. TestNG annotations automate this process, making tests reliable, repeatable, and easier to manage. This saves time and reduces bugs in software.
Where it fits
Before learning TestNG annotations, you should understand basic Java programming and how to write simple test methods. After mastering these annotations, you can learn more advanced TestNG features like parameterization, groups, and parallel test execution.
Mental Model
Core Idea
TestNG annotations label methods to control when and how tests run, automating setup, execution, and cleanup.
Think of it like...
It's like a cooking recipe where @BeforeMethod is preparing ingredients before cooking, @Test is the actual cooking step, and @AfterMethod is cleaning the kitchen afterward.
┌───────────────┐
│   @BeforeMethod  │
│ (Setup step)  │
└──────┬────────┘
       │
┌──────▼───────┐
│    @Test     │
│ (Test case)  │
└──────┬───────┘
       │
┌──────▼────────┐
│  @AfterMethod │
│ (Cleanup step)│
└───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding @Test Annotation Basics
🤔
Concept: Learn that @Test marks a method as a test case to be run by TestNG.
In TestNG, any method marked with @Test is recognized as a test. When you run your test suite, TestNG automatically finds and executes these methods. For example: public class SampleTest { @Test public void testAddition() { int sum = 2 + 3; assert sum == 5; } } This method will run as a test and pass if the assertion is true.
Result
TestNG runs the testAddition method and reports pass if the assertion holds.
Understanding @Test is the foundation of writing automated tests with TestNG, as it tells the framework what code to test.
2
FoundationRole of @BeforeMethod Annotation
🤔
Concept: @BeforeMethod marks a method to run before each @Test method for setup tasks.
Sometimes tests need preparation before running, like opening a browser or setting test data. Methods marked with @BeforeMethod run before every test method in the class. Example: @BeforeMethod public void setup() { System.out.println("Setup before test"); } @Test public void testOne() { /* test code */ } @Test public void testTwo() { /* test code */ } Here, setup() runs before testOne and again before testTwo.
Result
Output shows 'Setup before test' printed before each test method runs.
Knowing @BeforeMethod automates repetitive setup, preventing duplicated code and ensuring consistent test environments.
3
IntermediateUsing @AfterMethod for Cleanup
🤔Before reading on: do you think @AfterMethod runs once after all tests or after each test? Commit to your answer.
Concept: @AfterMethod marks a method to run after each @Test method for cleanup tasks.
After a test runs, you often need to clean up, like closing a browser or resetting data. Methods with @AfterMethod run after every test method. Example: @AfterMethod public void teardown() { System.out.println("Cleanup after test"); } @Test public void testOne() { /* test code */ } @Test public void testTwo() { /* test code */ } Here, teardown() runs after testOne and again after testTwo.
Result
Output shows 'Cleanup after test' printed after each test method runs.
Understanding @AfterMethod ensures tests do not affect each other by cleaning up, which improves test reliability.
4
IntermediateOrder of Execution with Annotations
🤔Before reading on: do you think all @BeforeMethod methods run first, then all @Test, then all @AfterMethod? Commit to your answer.
Concept: Learn the sequence TestNG follows when running @BeforeMethod, @Test, and @AfterMethod.
TestNG runs methods in this order for each test method: 1. @BeforeMethod 2. @Test 3. @AfterMethod This means setup and cleanup happen around each test individually, not all setups first. For example, for two tests: @BeforeMethod @Test test1 @AfterMethod @BeforeMethod @Test test2 @AfterMethod This keeps tests isolated and predictable.
Result
Each test runs with its own setup and cleanup steps in sequence.
Knowing this order helps design tests that are independent and avoid side effects.
5
IntermediateMultiple @BeforeMethod and @AfterMethod Methods
🤔Before reading on: if you have two @BeforeMethod methods, do you think TestNG runs them in the order they appear in code or randomly? Commit to your answer.
Concept: TestNG allows multiple setup or cleanup methods; their execution order can be controlled.
You can have several methods marked @BeforeMethod or @AfterMethod. By default, TestNG runs them in alphabetical order by method name. You can control order using the 'dependsOnMethods' or 'priority' attributes in other annotations, but not directly on @BeforeMethod/@AfterMethod. Example: @BeforeMethod public void setupA() { System.out.println("Setup A"); } @BeforeMethod public void setupB() { System.out.println("Setup B"); } @Test public void test() {} Output: Setup A Setup B Test runs This helps organize complex setup steps.
Result
All setup methods run before each test, in a predictable order.
Understanding multiple setup/cleanup methods allows modular and reusable test preparation.
6
AdvancedHandling Exceptions in @BeforeMethod and @AfterMethod
🤔Before reading on: if @BeforeMethod throws an exception, do you think the test method still runs? Commit to your answer.
Concept: Learn how TestNG behaves if setup or cleanup methods throw exceptions.
If a @BeforeMethod method throws an exception, TestNG skips the test method because the setup failed. If @AfterMethod throws an exception, TestNG reports it but the test result depends on the test method outcome. Example: @BeforeMethod public void setup() { throw new RuntimeException("Setup failed"); } @Test public void test() { System.out.println("Test runs"); } Here, 'Test runs' will NOT print because setup failed. This behavior prevents running tests in bad states.
Result
TestNG skips tests if setup fails, ensuring invalid tests don't run.
Knowing this prevents confusion when tests don't run and helps write robust setup code.
7
ExpertOptimizing Test Suites with @BeforeMethod and @AfterMethod
🤔Before reading on: do you think running setup/cleanup before and after every test is always the best approach? Commit to your answer.
Concept: Explore advanced strategies to reduce test runtime and improve reliability using these annotations.
Running setup and cleanup before and after every test ensures isolation but can slow down large test suites. Experts sometimes use @BeforeClass and @AfterClass to run setup/cleanup once per class when tests share state safely. However, misuse can cause flaky tests if tests depend on shared state. Balancing isolation and speed is key. Example: @BeforeClass public void globalSetup() { /* runs once */ } @BeforeMethod public void setup() { /* runs before each test */ } Choosing the right annotation depends on test independence and resource cost.
Result
Test suites run faster with shared setup but risk test interference if not managed carefully.
Understanding trade-offs in setup frequency helps design efficient and reliable test suites.
Under the Hood
TestNG uses Java reflection to scan classes for methods annotated with @Test, @BeforeMethod, and @AfterMethod. At runtime, it builds an execution plan that runs setup methods before each test method and cleanup methods after. It manages test lifecycle events internally, handling exceptions and reporting results. This automation removes manual orchestration from the tester.
Why designed this way?
TestNG was designed to improve upon older testing frameworks by providing flexible, annotation-driven control over test execution. Using annotations allows declarative test structure, making tests easier to read and maintain. The per-method setup and cleanup ensure test isolation, a key principle for reliable automated testing.
┌───────────────┐
│ Test Class    │
│ (with methods)│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Reflection    │
│ scans methods │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Execution Plan│
│ (order setup, │
│  test, cleanup)│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Runtime       │
│ runs methods  │
│ handles errors│
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does @BeforeMethod run once before all tests or before each test? Commit to your answer.
Common Belief:Many think @BeforeMethod runs only once before all tests start.
Tap to reveal reality
Reality:@BeforeMethod runs before each individual test method, not just once.
Why it matters:Misunderstanding this causes setup code to be written incorrectly, leading to tests sharing state and causing flaky failures.
Quick: If @AfterMethod throws an exception, does the test still pass? Commit to your answer.
Common Belief:Some believe exceptions in @AfterMethod do not affect test results.
Tap to reveal reality
Reality:Exceptions in @AfterMethod are reported and can cause the test to be marked as failed or skipped depending on the framework configuration.
Why it matters:Ignoring cleanup failures can hide resource leaks or inconsistent test environments, leading to unreliable test suites.
Quick: Can multiple methods have @BeforeMethod in the same class? Commit to your answer.
Common Belief:People often think only one @BeforeMethod is allowed per class.
Tap to reveal reality
Reality:TestNG allows multiple @BeforeMethod methods, and all will run before each test method.
Why it matters:Knowing this enables modular setup code and better organization of complex test preparations.
Quick: Does TestNG guarantee the order of multiple @BeforeMethod methods? Commit to your answer.
Common Belief:Many assume TestNG runs multiple @BeforeMethod methods in the order they appear in code.
Tap to reveal reality
Reality:TestNG runs multiple @BeforeMethod methods in alphabetical order by method name by default, not code order.
Why it matters:Incorrect assumptions about order can cause subtle bugs when setup steps depend on each other.
Expert Zone
1
TestNG's per-method setup and cleanup ensure test isolation but can be optimized with @BeforeClass/@AfterClass when tests share safe state.
2
Handling exceptions in @BeforeMethod properly can prevent entire test suites from failing unexpectedly.
3
Multiple @BeforeMethod/@AfterMethod methods can be combined with dependency annotations for complex setup sequences.
When NOT to use
Use @BeforeMethod and @AfterMethod when tests require fresh setup and cleanup each time. For expensive setup shared by all tests, use @BeforeClass and @AfterClass instead. Avoid @BeforeMethod if setup is slow and tests do not modify shared state.
Production Patterns
In real-world Selenium tests, @BeforeMethod often opens a fresh browser session, @Test runs user actions, and @AfterMethod closes the browser. Teams use multiple @BeforeMethod methods to set environment variables and initialize test data separately. Exception handling in setup prevents false positives in CI pipelines.
Connections
JUnit Annotations
Similar pattern
Understanding TestNG annotations helps grasp JUnit's @Before, @After, and @Test annotations since they serve similar roles in test lifecycle management.
Software Design Patterns - Template Method
Builds-on
TestNG's setup and cleanup methods resemble the Template Method pattern where a fixed sequence calls customizable steps, helping understand structured test flows.
Theater Play Rehearsal Process
Analogous process
Just like actors rehearse scenes with preparation and cleanup before and after each act, tests use @BeforeMethod and @AfterMethod to prepare and reset the environment, ensuring consistent performances.
Common Pitfalls
#1Setup code runs only once, causing tests to share state and fail unpredictably.
Wrong approach:@BeforeClass public void setup() { // opens browser once } @Test public void test1() { /* test code */ } @Test public void test2() { /* test code */ }
Correct approach:@BeforeMethod public void setup() { // opens browser before each test } @Test public void test1() { /* test code */ } @Test public void test2() { /* test code */ }
Root cause:Confusing @BeforeClass (runs once) with @BeforeMethod (runs before each test) leads to shared state and flaky tests.
#2Ignoring exceptions in @BeforeMethod causes tests to run in invalid states.
Wrong approach:@BeforeMethod public void setup() { // code that throws exception but not handled throw new RuntimeException("fail"); } @Test public void test() { /* runs anyway */ }
Correct approach:@BeforeMethod public void setup() { try { // setup code } catch (Exception e) { throw e; // fail fast } } @Test public void test() { /* skipped if setup fails */ }
Root cause:Not understanding that exceptions in setup prevent tests from running leads to confusion and unreliable results.
#3Assuming multiple @BeforeMethod methods run in code order causes setup dependency bugs.
Wrong approach:@BeforeMethod public void setupSecond() { System.out.println("Second"); } @BeforeMethod public void setupFirst() { System.out.println("First"); } @Test public void test() {}
Correct approach:// Rename methods to control order alphabetically @BeforeMethod public void setupAFirst() { System.out.println("First"); } @BeforeMethod public void setupBSecond() { System.out.println("Second"); } @Test public void test() {}
Root cause:Misunderstanding TestNG's alphabetical execution order for multiple setup methods causes unexpected behavior.
Key Takeaways
TestNG annotations like @Test, @BeforeMethod, and @AfterMethod automate test execution flow, making tests easier to write and maintain.
@BeforeMethod and @AfterMethod run before and after each test method, ensuring proper setup and cleanup for test isolation.
Multiple setup or cleanup methods are allowed and run in alphabetical order, which can be controlled by naming or dependencies.
Exceptions in setup methods prevent tests from running, protecting against invalid test states.
Balancing per-test setup with shared setup (@BeforeClass) is key for efficient and reliable test suites.