Search code examples
testngparallel-testing

@beforeclass methods get executed in same thread if we put parallel="tests" in the suite xml


I have a test suite where I am using parallelism by using annotation like :

test name="All Regular Tests" parallel="tests" thread-count="30"

Now, let's say we have multiple @test annotation in one class. and it has @beforeclass annotation method as well. So when separate thread will pick the tests from same class, will it execute the @beforeclass methods in both threads or will it share the same data.

Or shall I use parallel="methods", what is the correct way ?

Not able to understand the concept of parallelism.


Solution

  • I can see why you are confused.

    It makes no sense to use parallel="tests" in the test tag. parallel="tests" is dictating that all the defined in the XML are run in different threads. But you are assigning that to a test level, so it will only apply that option for that test.

    You have two options here.

    To put the multithreading option at a suite level, with the "tests" parallelization: <suite name = "ParallelTesting" parallel="tests" thread-count="2">

    Or to put it on the test level, with "method" option: <test name = "Test Parallelism" parallel="method" thread-count="2">

    So:

    • "tests": for each in the XML file.
    • "method": for each @Test method in wherever you put the property (all the @Tests in the suite, all the @Tests in a class, etc.)

    Regarding yout second question, no, it will run the @BeforeClass only once. You can put it to the test very easily:

    XML File: parallel=tests on suite level:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    
    <suite name = "ParallelTesting" parallel="tests" thread-count="2">
    
        <test name = "Test Parallelism 1" >
            <classes>
                <class name = "com.test.testing.test.TestClass"/>
            </classes>
        </test>
    
        <test name = "Test Parallelism 2" >
            <classes>
                <class name = "com.test.testing.test.TestClass2"/>
            </classes>
        </test>
    
    </suite>
    

    Test Class 1:

    public class TestClass {
    
        @BeforeClass
        public void beforeClass() {
            System.out.println("Class 1 - Before Class with Thread Id:- "+ Thread.currentThread().getId());
        }
    
        @Test
        public void testA() {
            System.out.println("Class 1 - Test Case A with Thread Id:- " + Thread.currentThread().getId());
        }
    
        @Test
        public void testB() {
            System.out.println("Class 1 - Test Case B with Thread Id:- " + Thread.currentThread().getId());
        }
    
    }
    

    Test Class 2:

    public class TestClass2 {
    
        @BeforeClass
        public void beforeClass() {
            System.out.println("Class 2 - Before Class with Thread Id:- "+ Thread.currentThread().getId());
        }
    
        @Test
        public void testA() {
            System.out.println("Class 2 - Test Case A with Thread Id:- " + Thread.currentThread().getId());
        }
    
        @Test
        public void testB() {
            System.out.println("Class 2 - Test Case B with Thread Id:- " + Thread.currentThread().getId());
        }
    
    }
    

    Output:

    Class 1 - Before Class with Thread Id:- 12
    Class 2 - Before Class with Thread Id:- 13
    Class 2 - Test Case A with Thread Id:- 13
    Class 1 - Test Case A with Thread Id:- 12
    Class 2 - Test Case B with Thread Id:- 13
    Class 1 - Test Case B with Thread Id:- 12
    
    ===============================================
    ParallelTesting
    Total tests run: 4, Failures: 0, Skips: 0
    ===============================================
    

    The two other variations of parallelization are (using the same classes above):

    XML File: parallel=method on suite level:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    
    <suite name = "ParallelTesting2" parallel="methods" thread-count="2">
    
        <test name = "Test Parallelism 1" >
            <classes>
                <class name = "com.test.testing.test.TestClass"/>
            </classes>
        </test>
    
        <test name = "Test Parallelism 2" >
            <classes>
                <class name = "com.test.testing.test.TestClass2"/>
            </classes>
        </test>
    
    </suite>
    

    Output:

    Class 1 - Before Class with Thread Id:- 12
    Class 1 - Test Case B with Thread Id:- 13
    Class 1 - Test Case A with Thread Id:- 12
    Class 2 - Before Class with Thread Id:- 14
    Class 2 - Test Case A with Thread Id:- 14
    Class 2 - Test Case B with Thread Id:- 15
    

    XML File: parallel=method on test level:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    
    <suite name = "ParallelTesting2" >
    
        <test name = "Test Parallelism 1" parallel="methods" thread-count="2">
            <classes>
                <class name = "com.test.testing.test.TestClass"/>
            </classes>
        </test>
    
        <test name = "Test Parallelism 2" parallel="methods" thread-count="2">
            <classes>
                <class name = "com.test.testing.test.TestClass2"/>
            </classes>
        </test>
    
    </suite>
    

    Output:

    Class 1 - Before Class with Thread Id:- 12
    Class 1 - Test Case A with Thread Id:- 12
    Class 1 - Test Case B with Thread Id:- 13
    Class 2 - Before Class with Thread Id:- 14
    Class 2 - Test Case B with Thread Id:- 15
    Class 2 - Test Case A with Thread Id:- 14
    

    And finally, what I mention it wouldn't make sense to do:

    XML File: parallel=tests on test level:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    
    <suite name = "ParallelTesting2" >
    
        <test name = "Test Parallelism 1" parallel="tests" thread-count="2">
            <classes>
                <class name = "com.test.testing.test.TestClass"/>
            </classes>
        </test>
    
        <test name = "Test Parallelism 2" parallel="tests" thread-count="2">
            <classes>
                <class name = "com.test.testing.test.TestClass2"/>
            </classes>
        </test>
    
    </suite>
    

    Output:

    Class 1 - Before Class with Thread Id:- 1
    Class 1 - Test Case A with Thread Id:- 1
    Class 1 - Test Case B with Thread Id:- 1
    Class 2 - Before Class with Thread Id:- 1
    Class 2 - Test Case A with Thread Id:- 1
    Class 2 - Test Case B with Thread Id:- 1
    


    As you can see in that last example, everything runs on the same thread because you are asking to each test (group of methods) to run tests in parallel.