javaselenium-webdrivertestngthread-local

Can we set a Thread Local variable from child class and access it in the parent class in Java?


I have an automation project with two Test classes(child classes) and a TestBase (parent class). In the TestBase I have a threadlocal attribute defined as below.

protected ThreadLocal<ITestContext> iTestContextThreadLocal = new ThreadLocal<>();

In each of the child class I'm setting an attribute called 'feature' into this ThreadLocal attribute. Sample Child class looks like below.

public class RestTests extends TestBase{

    @BeforeClass(alwaysRun = true)
    public void init(ITestContext iTestContext) {
        iTestContext.setAttribute("feature", "Sample - RestTests1");
        iTestContextThreadLocal.set(iTestContext);
        String feature = iTestContextThreadLocal.get().getAttribute("feature").toString();
    }

    @Test
    public void testScenario1(){
        //Automation Code
    }
}

In the TestBase I have an 'AfterMethod' inside which I try to access this value set in child class's before Method.

    @AfterMethod(alwaysRun = true)
    public void test() {
        try {
            ITestContext iTestContext = iTestContextThreadLocal.get();
            String feature = iTestContext.getAttribute("feature").toString();
            System.out.println("***** ThreadLocalAttribute: " + feature);

            //Rest of the code
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Clean up the ThreadLocal variables after method execution
            iTestContextThreadLocal.remove();
        }
    }

The Issue I'm facing is - in parallel Test execution (in both classes and methods) feature set in one class is provided as the output. As an example if I set 'Sample - RestTests1' and 'Sample - RestTests2' as features in my child classes, when I try to access them in TestBase afterMethod using the below code, only one class's feature is given

iTestContext.getAttribute("feature").toString();

How to fix this and get feature set in each class via TestBase's AfterMethod ?

I have tried changing the order of annotations and trying out the solutions in the internet. But no fix is found yet.

Any help is highly appreciated. Thanks in Advance.


Solution

  • If you read, for example, this question on a similar topic, you'll see that there is a problem with TestNG's policy of creating only one instance per test class, and how to reset state if the test should be run in parallell.

    I guess that in your case, you shouldn't have made the init method @BeforeClass, but rather @BeforeMethod, or perhaps @BeforeTest (don't remember the exact names).