TestNG for Integration Testing

One of our client wanted us to Automate all their manual regression UI Tests using Java and Selenium WebDriver.

JUnit 4 and TestNG are both very popular unit test frameworks in Java. TestNG framework is better candidate for Integration Testing as it provides more features out of the box. Check out the Integration Testing features of TestNG ...

  • Able to choose specific group of tests to run.
  • Ability to run the same test with different types of test data (Data-Driven Tests)
  • Able to change the test data based on the Test environment.
  • Able to run some functional tests in a specific order.
  • Run all the tests as faster as possible.
  • Grouping of Test cases:

    For example, it is common to have at least two categories while doing Test automation.

    • Smoke tests (smokeTest). These tests should be running regression tests. They should typically be fast and just make sure no basic functionality was broken.
    • Regression tests (funcTest). These tests should cover the functionality of your software and be able to run at least once a day, although ideally you would want to run them continuously.
       public class MyTest1 {
        @Test(groups = { "funcTest", "smokeTest" })
        public void testFunctionality1() {
          // ...
        }
        @Test(groups = {"funcTest", "smokeTest"} )
        public void testFunctionality2() {
          // ...
        }
        @Test(groups = { "funcTest" })
        public void testFunctionality3() {
          // ...
        }
      }
      
      // Maven Command to run only Smoke Tests from Command line.
      mvn test -Dgroups=smokeTest
      

      Here Smoke Tests are subset of Regression Tests. So if you want to run only smokeTest methods then run the Maven command. This runs only the first two tests.

  • Passing parameters to test methods:

    Sometimes we need to send parameters to Test methods as tests might need different input data or need to send environment specific details like connection to DB. Here you can use one of the below approaches.
    • @Parameters Annotation Here you can send datasource and environment parameters as system parameters. This helps you send environment specific details.
      @Parameters({ "datasource", "environment" })
      @BeforeMethod
      public void beforeTest(String ds, String environment) {
        m_dataSource = ds;
        m_environment = environment;
      }
      
      # For Different environment, you can run the same tests by pointing to Different Database.
      # For Test environment - like uat
      mvn test -Denvironment=uat -Ddatasource=jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename
      # For Production environment - like prod
      mvn test -Denvironment=prod -Ddatasource=jdbc:oracle:thin:scott/tiger@//myhost2:1521/myservicename2
      
    • @DataProvider Annotation Here the test method 'verifyStringConcat' runs twice for each set data. In Integration tests
      //This method will provide data to any test method
      //that declares that its Data Provider is named "dataProvider1"
      @DataProvider(name = "dataProvider1")
      public Object[][] createData1() {
       return new Object[][] {
         { "KickStartPros", new Integer(1), "KickStartPros 1" },
         { "Monika", new Integer(99), "Monika 99"},
       };
      }
      //This test method declares that its data should be supplied
      //by the Data Provider named "dataProvider1"
      @Test(dataProvider = "dataProvider1")
      public void verifyStringConcat(String input1, Integer input2, Integer expectedOutput) {
       System.out.println(input1 + " " + input2);
       assertEquals(input1 + " " + input2, expectedOutput);
      }
      
      Here the @DataProvider returns data both inputs and expected output for test method. This will print the below result and Test will pass.
      KickStartPros 1
      Monika 99
      
  • Dependencies between test methods:

    Most of the Integration test methods need to be invoked in a certain order.
    • To make sure a certain number of test methods have completed and succeeded before running more test methods.
    • To initialize your tests while wanting this initialization methods to be test methods as well (methods tagged with @Before/After will not be part of the final report).
    • Method Dependency Here 'runShoppingTest' Test runs only after 'serverStartedOk' and 'performAppLogin'
      @Test
      public void serverStartedOk() {}
      @Test(dependsOnMethods = { "serverStartedOk" })
      public void performAppLogin() {}
      @Test(dependsOnMethods = { "performAppLogin" })
      public void runShoppingTest() {}
      
    • Group Dependency
      @Test(groups = { "init" })
      public void serverStartedOk() {}
      @Test(groups = { "init" })
      public void initEnvironment() {}
      @Test(dependsOnGroups = { "init.* })
      public void method1() {}
      
  • Running tests in Parallel:

    Most of the Integration tests can be run in parallel at tests level. This helps to run the complete regression tests faster. Sample testng.xml file below.
            
    <suite name="My suite" parallel="tests" thread-count="3">
      <test name="My Account tests" >
        <classes>
           <class name="com.kickstartpros.test.MyAccountTest" />
        </classes>
      </test>
      <test name="My User Regression Tests">
        <classes>
          <class name="com.kickstartpros.test.UserRoleTest"/>
          <class name="com.kickstartpros.test.UserSecurityAccessTest"/>
        </classes>
      </test>
      <test name="My Checkout Regression Test">
        <classes>
          <class name="com.kickstartpros.test.MyShoppingTest"/>
          <class name="com.kickstartpros.test.MyCartTest"/>
        </classes>
      </test>
    </suite>
    

    TestNG provides a way to add description to the test as part of annotation. Example: @Test(description="My Shopping Add Cart Test 1") which helps to find fail test cases easily.

  • Conclusion

    With all the in-built features it gives lot of built-in features to automate integration tests using TestNG.
    Similar to application code, the test code needs to follow.

    • Architecture and Design patterns like Object Oriented Design, Page Objects for UI Pages, Dependency Management.
    • Meaningful variables, methods, class names & class hierarchy.
    • The test case steps and test flow should be documented within your test code.
    • Behavior-Driven Development
    • Continuous Delivery
    Contact Us to Kick start Automation

No comments :

Post a Comment