03. Test methods, Test classes and Test groups - senthilpazhani/SeleniumComplete GitHub Wiki

Test methods

Test methods are annotated with @Test. Methods annotated with @Test that happen to return a value will be ignored, unless you set allow-return-values to true in your testng.xml.

<suite allow-return-values="true">
or
<test allow-return-values="true">

Working fine when including in suite.

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="AllowReturnValues_TestSuite" allow-return-values="true">
  <test name="AllowReturnValues_test " >
	  <classes>
		<class name="workout.AllowReturnValues"></class>
	  </classes>
   </test>
</suite>

Test groups

Groups are specified in your testng.xml file and can be found either under the <test> or <suite> tag. Groups specified in the <suite> tag apply to all the <test> tags underneath. Note that groups are accumulative in these tags, ie. if you specify group "a" in and "b" in , then both "a" and "b" will be included.

Example 1: It is quite common to have at least two categories of tests:

  • Check-in tests. These tests should be run before you submit new code. They should typically be fast and just make sure no basic functionality was broken.
  • Functional tests. These tests should cover all the functionalities of your software and be run at least once a day, although ideally you would want to run them continuously.

Typically, check-in tests are a subset of functional tests. For example, you could structure your test by saying that your entire test class belongs to the "functest" group, and additionally that a couple of methods belong to the group "checkintest":

public class Test1 {
 @Test(groups = { "functest", "checkintest" })
      public void testMethod1() {
  }
  @Test(groups = {"functest", "checkintest"} )
      public void testMethod2() {
  }
  @Test(groups = { "functest" })
      public void testMethod3() {
  }
}

Invoking TestNG with

<test name="Test1">
  <groups>
    <run>
      <include name="functest"/>
    </run>
  </groups>
  <classes>
    <class name="example1.Test1"/>
  </classes>
</test>

will run all the test methods in that classes, while invoking it with checkintest will only run testMethod1() and testMethod2().

Example 2: Using regular expressions this time. Assume that some of your test methods should not be run on Linux, your test would look like:

@Test
public class Test1 {
  @BeforeClass(alwaysRun=true) //include (alwaysRun=true) otherwise it wont run
  public void beforeClass() {
    System.out.println("Before Class");
  }
  @Test(groups = { "windows.checkintest" })
  public void testWindowsOnly() {
  }
  @Test(groups = {"linux.checkintest"} )
  public void testLinuxOnly() {
  }
   @Test(groups = { "windows.functest" )
  public void testWindowsToo() {
  }
}

You could use the following testng.xml to launch only the Windows methods:

<test name="Test1">
  <groups>
    <run>
      <include name="windows.*"/>
    </run>
  </groups>
  <classes>
    <class name="example1.Test1"/>
  </classes>
</test>

exclude or include individual methods

You can also exclude or include individual methods:

<test name="Test1">
  <classes>
    <class name="example1.Test1">
      <methods>
        <include name=".*enabledTestMethod.*"/>
        <exclude name=".*brokenTestMethod.*"/>
      </methods>
     </class>
  </classes>
</test>

This can come in handy to deactivate a single method without having to recompile anything, but I don't recommend using this technique too much since it makes your testing framework likely to break if you start refactoring your Java code (the regular expressions used in the tags might not match your methods any more).

Groups of groups

Groups can also include other groups. These groups are called "MetaGroups".

For example, you might want to define a group "all" that includes "checkintest" and "functest". "functest" itself will contain the groups "windows" and "linux" while "checkintest" will only contain "windows". Here is how you would define this in your property file:

<test name="Regression1">
  <groups>
    <define name="functest">
      <include name="windows"/>
      <include name="linux"/>
    </define>
    <define name="all">
      <include name="functest"/>
      <include name="checkintest"/>
    </define>
    <run>
      <include name="all"/>
    </run>
  </groups>
  <classes>
    <class name="test.sample.Test1"/>
  </classes>
</test>

Exclusion groups

TestNG allows you to include groups as well as exclude them.

For example, it is quite usual to have tests that temporarily break because of a recent change, and you don't have time to fix the breakage yet. However, you do want to have clean runs of your functional tests, so you need to deactivate these tests but keep in mind they will need to be reactivated.

A simple way to solve this problem is to create a group called "broken" and make these test methods belong to it. For example, in the above example, I know that testMethod2() is now broken so I want to disable it:

@Test(groups = {"checkintest", "broken"} )
public void testMethod2() {
}

All I need to do now is to exclude this group from the run:

<test name="Simple example">
  <groups>
    <run>
      <include name="checkintest"/>
       <exclude name="broken"/>
    </run>
  </groups>
  <classes>
    <class name="example1.Test1"/>
  </classes>
</test>

This way, I will get a clean test run while keeping track of what tests are broken and need to be fixed later.

Note: you can also disable tests on an individual basis by using the "enabled" property available on both @Test and @Before/After annotations.

Partial groups

You can define groups at the class level and then add groups at the method level:

@Test(groups = { "checkin-test" })
public class All {
  @Test(groups = { "func-test" )
  public void method1() { ... }
   public void method2() { ... }
}

In this class, method2() is part of the group "checkin-test", which is defined at the class level, while method1() belongs to both "checkin-test" and "func-test".

⚠️ **GitHub.com Fallback** ⚠️