0
votes

I am building a testing framework using selenium web driver, testng and java. While doing framework POC, I faced a problem. I want to execute some code after each test case, which will delete/reset application to it's base state. This clean up code might be different for each test case.

Let's say I have two modules named A and B. in Module A I have 3 test cases Test1, test2, Test3. I want to run cleanup for every Test case(Test1, Test2 and Test3). Cleanup code for each test case could be different. So using @AfterMethod annotation will not solve my problem.

So how can I design the test class strecture?

I have already tried below approaches.

Approach1:

@Test
public void test1() {
    try {
        System.out.println("test1");
    } catch(Exception e) {
        System.out.println(e);
        takescreenshot();
    } finally {
        System.out.println("clean up for test1");
    }

}

Cons: 1) In every test case I need to follow some defined structure 2) Code repetition. 3) If any error occurs in finally block, testNG report will swallow the original error and shows the error occurred in finally block which is not good.

Approach2: Create a test class for every test case

public class Test2 {

    @BeforeMethod()
    public void preCondition() {
        System.out.println("pre condition");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

    @AfterMethod()
    public void postCondition() {
        System.out.println("post condition");
    }

}

Cons: 1) Multiple classes needs to be created which is a overhead. 2) variable sharing between test cases connot happen.(i.e. using variable 'var1' in 2 test cases might be difficult as they were in different class)

Approach3: Split modules in to sub-modules/granular level and combine test cases that use common cleanup. @Test public void test2() { System.out.println("create DB with name"); }

@Test
public void test3() {
    System.out.println("create DB with ID");
}

@AfterMethod
public void tearDown() {
    System.out.println("Delete DB");
}

Cons: 1) Splitting in to sub-modules is not possible every time. And tester needs to think carefully while adding new test case to any module thinking that which sub-module it belongs

Which approach would be better? Any different structure/approach you are currently following?

Any best practices to design test class?

2
How is this question related to selenium-webdriver? Am I missing something? - DebanjanB

2 Answers

0
votes

Create a separate class that contains all the methods to perform different cleanup tasks. Invoke these methods accordingly in your test methods' finally block. By this way you can avoid all the cons mentioned above.

0
votes

If you want to be able to clean up your test cases, my best example will be to use either the AfterSuite or AfterClass annotations. This way you can have test class represent features or a test area, and within this test class you can have multiple tests that are all testing the various parts of this feature/test area.

The AfterClass annotation can be defined in each test class where it could use global variables to hold the data you wish to clean up. Then you could have a cleanup class with various different methods that help you clean up the data. Call the methods from the clean up class in your AfterClass method while feeding it the appropriate variables.

The AfterSuite would be the same concept execpt here at this level you would be cleaning up every single data that was generated during your entire suite run. IMO not the most ideal, i usually clean up in the Afterclass.

Here some puesdo code as an example

TestClass:

private AccountUser accountUser;

@AfterClass
public cleanUpAccountUsers() throws Exception {
accountUser.delete();

// or if you have a class that holds a delete functionality for an accountUser then

DataUtils.cleanUpAccountUsers(accountUser);
}

@Test()
public void createAccountUser() {
accountUser = new AccountUser();
// blah blah code for testing account user creation
}

@Test()
public void updateAccountUserInformation() {
// blah blah code to test updating account user information
}

For the example above your tests now can create data in one test and is now accessible in another test. After the test run is complete in using this class the AfterClass will be executed and you can now clean up your data that you generated in this test.