I have observed behavior in TestNG dependency functionality that I do not fully understand. (In example below TestNG version 5.8 was used.)
Let us have following test class:
1 public class NGTest {
2
3 @Test(groups = {"initA"}, enabled = true)
4 public void initA() {
5 System.out.println("Init A called.");
6 }
7
8 @Test(groups = {"A"}, dependsOnGroups = {"initA"})
9 public void testA() {
10 System.out.println("Test A called.");
11 }
12 }
In class, there are two test methods:
initA - test that is supposed to make initialization of A (e.g. resource A).
testA - test that is supposed to perform test scenario on A; testA depends on initA through groups dependency.
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd">
<suite name="NGTest">
<test name="NGTest">
<groups>
<run>
<include name="initA"/>
<include name="A"/>
</run>
</groups>
<classes>
<class name="testngtest.NGTest"/>
</classes>
</test>
</suite>
When tests are run, the output is, as expected:
Init A called.Let us change line in testng.xml to exclude initA group (<exclude name="initA"/>):
Test A called.
===============================================
NGTest
Total tests run: 2, Failures: 0, Skips: 0
===============================================
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd">
<suite name="NGTest">
<test name="NGTest">
<groups>
<run>
<exclude name="initA"/>
<include name="A"/>
</run>
</groups>
<classes>
<class name="testngtest.NGTest"/>
</classes>
</test>
</suite>
When tests are run, the output is same like in previous example:
Init A called.
Test A called.
===============================================
NGTest
Total tests run: 2, Failures: 0, Skips: 0
===============================================
From documentation to TestNG I would expect that initA is not called (as group is excluded) and testA is skipped, since it depends on successful run of initA. Instead, it looks like when testA is invoked, it forces initA to be called first.
Let us now disable initA test in source code:
1 @Test(groups = {"initA"}, enabled = false)
2 public void initA() {
3 System.out.println("Init A called.");
4 }
When tests are run, the output is like expected:
===============================================
NGTest
Total tests run: 1, Failures: 0, Skips: 1
===============================================
This means disabling test method in source code has "higher priority" than excluding group in testng.xml.
Let us now add @BeforeClass method to the NGTest class and enable initA in source code again.
1 @BeforeClass
2 public void init() {
3 System.out.println("Init called.");
4 }
5
6 @Test(groups = {"initA"}, enabled = true)
7 public void initA() {
8 System.out.println("Init A called.");
9 }
When tests are run, the output is again like expected:
===============================================Only testA is included into tests, but since it depends on initA, it is skipped. Same is archived when adding @BeforeTest or @BeforeSuite. This means that exclude behavior is somehow controlled by presence of @Before... method(s).
NGTest
Total tests run: 1, Failures: 0, Skips: 1
===============================================