Creating Test Classes Using TestNG | Part 8

 

So far we have been using a single test class (LoginPageTest.java) with main method to execute all the tests. Now, we will break that class into different classes containing separate tests. These tests would then be executed using TestNG.

Recall the three tests from the first tutorial:

  1. Is the landing page displayed?
  2. Verify if the user is able to search for a particular product?
  3. Validate if the user is able to sign in successfully?

Following diagram outlines how the existing test class (LoginPageTest.java) will be segregated to create 3 new test classes:

 

Refactor Test Class

 

Test1, Test2 and Test3 denotes the new test classes to be created out of exsiting single test class. The names of these test classes are LandingPageTest.java, ProductSearchPageTest.java and SignInPageTest.java respectively.

Each test class will contain 1 method, and this method is the test.

 

Move the existing LoginPageTest.java class to some other location as we will create a new test class with same name.

 

 

Test1 – LandingPageTest.java

 

This test class will verify if landing page is displayed or not. This test does not depend on any other page, hence we will use only LandingPage object reference in this test.

Inside com.appliedselenium.tests package, create a new class LandingPageTest.javaCreate a new method isLandingPageDisplayed() and use the @Test TestNG annotation to indicate that this method is a test. 

Import the org.testng.annotations.Test package to use the @Test annotation. Copy and paste the code (as show in above figure) inside the new test method as following:

 

package com.appliedselenium.tests;

import org.testng.annotations.Test;

import com.appliedselenium.pages.LandingPage;

public class LandingPageTest{
    
    
    @Test
    
    public void isLandingPageDisplayed() {
        
        LandingPage landingPage = new LandingPage();
        
        // Verify the titles
        if (landingPage.getTitle().equals("My Store")) {
            System.out.println("Title Matched - Test Passes");
        } else {
            System.out.println("Title doesn't match - Test Failed");
        }
        
    }

}

 

 

Test2 – ProductSearchPageTest.java

 

Create another test class ProductSearchPageTest.java inside the same package and add a method isProductSearched(). This method too should be associated with @Test TestNG annotation.

To search a product, user first has to search for a product on landing page and then the product is displayed on product page. Hence instances from LandingPage.java and ProductSearchPage.java would be used.

The code for this test class is as follows:

 

package com.appliedselenium.tests;

import org.testng.annotations.Test;

import com.appliedselenium.pages.LandingPage;
import com.appliedselenium.pages.ProductSearchPage;

public class ProductSearchPageTest {

    @Test
    public void isProductSearched() {
        ProductSearchPage pr;
        LandingPage landingPage = new LandingPage();
        // Navigate to Product Search page
        landingPage.searchProduct();

        // Instantiate ProductSearchPage class object
        pr = new ProductSearchPage();

        // Verify the text
        if (pr.getProductSearchResult().contains("Printed Summer Dress")) {
            System.out.println("Product Found");
        } else {
            System.out.println("Product Search Failed");
        }

    }

}

 

 

Test3 – SignInPageTest.java

 

Create a new class SignInPageTest.java and add a method verifySignIn()This will also contain @Test TestNG annotation. A user has to click on Sign in link at the landing page which will present them with a sign in page. After successful login, user should be navigated to application home page.

This class should contain the instance of classes LandingPage.java, SignInPage.java and HomePage.java respectively.

Following is the code for SignInPageTest.java test:

 

package com.appliedselenium.tests;

import org.testng.annotations.Test;

import com.appliedselenium.pages.HomePage;
import com.appliedselenium.pages.LandingPage;
import com.appliedselenium.pages.SignInPage;

public class SignInPageTest {

    
    @Test
    public void verifySignIn() {
        LandingPage landingPage = new LandingPage();
        SignInPage inPage;
        HomePage homePage;
        
        // Click on Sign In button
                landingPage.clickOnSignIn();

                inPage = new SignInPage();
                inPage.userSignIn("abc11001@xyz.com", "abcxyz");

                homePage = new HomePage();

                if (homePage.verifyCorrectLogin().equals("abc xyz")) {
                    System.out.println("Login Successful");
                } else {
                    System.out.println("Login Failed");
                }

    }
}

 

 

Creating DriverTest.java class

 

Other than these test classes, we also need to:

  • Set up all the configurations (Log4j, driver initialization, config and or.properties etc.) before browser is invoked.
  • Invoke the desired browser and navigate to AUT.
  • Close the browser instance after execution of all the tests.

One (bad) option is to perform all above operations in each class. This also includes driver instance initialization in the test classes. However, we have already discussed in previous tutorials that the test classes should be free from driver instance variables. Also, this approach will kill the code reusability.

Above pre-requisites have already been covered (except for closing the browser) in BasePage.java class. To include the quit browser logic, add the following method to BasePage.java class.

 

public static void quit_it() {
        driver.close();
    }

 

Inside the package com.appliedselenium.tests add another class DriverTest.javaThis class will contain 2 methods:

  • beforeTest()This method will invoke the constructor of BasePage.java class, thus loading all the configurations and invoking the browser with AUT URL. 
  • tearDown() – This method will call the above created quit_it() from BasePage.java class.

 

package com.appliedselenium.tests;

import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;

import com.appliedselenium.pages.BasePage;

public class DriverTest {
    
    @BeforeTest
    public void beforeTest() {
        new BasePage();
    }

    @AfterTest
    public void tearDown() {
        BasePage.quit_it();
    }
    
}

 

Every test class will extend DriverTest.java class, so that every method in BasePage.java is available to each test class. This will also help in keeping the test classes free from driver instance variable.

Update all the three test classes with “extends DriverTestkeyword.

 

TestNG annotation in DriverTest.java

 

@BeforeTest TestNG annotation is used for beforeTest (). This indicates that this method will be executed before all @Test only once. 

 

Also Read: Learn TestNG Annotations

Click HERE

 

tearDown() in @AfterTest TestNG annotation will be executed after all the @Test are executed.

 

Generate TestNG XML file

 

To execute the tests, testng.xml file is required. Right click on project’s root folder -> TestNG – > Convert to TestNG

 

convert to testng

 

This will open Refactor pop up window containing the classes in XML format. 

 

 

Click on Next button to accept the default values. A new file testng.xml should get created  at root level. Class DriverTest.java is not a test class and is already inherited to other test classes, remove it and the testng.xml file is ready.

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Test">
    <classes>
      <class name="com.appliedselenium.tests.LandingPageTest"/>
       <class name="com.appliedselenium.tests.ProductSearchPageTest"/>
          <class name="com.appliedselenium.tests.SignInPageTest"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

 

To execute the tests, right click on testng.xml -> Run As -> TestNG SuiteThe browser will open once, all tests should get executed one by one and finally the browser is closed.

In next tutorial, we will implement listeners, screen shot, report (extent report) etc. To facilitate the reporting and taking screen shot, test classes should contain Assert instead of if-else block for verification steps. 

Let’s update all the test classes with Assert class methods.

 

Implementing Assert Class

 

We already learnt about hard assert and soft assert. This tutorial will implement hard assert. 

 

LandingPageTest.java

 

Update the test class as following, changes are highlighted in bold:

 

package com.appliedselenium.tests;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.appliedselenium.pages.LandingPage;

public class LandingPageTest extends DriverTest{
    
    
    @Test
    
    public void isLandingPageDisplayed() {
        
        LandingPage landingPage = new LandingPage();
        String expectedTitle = "My Store";
        
        // Verify the titles
        Assert.assertEquals(landingPage.getTitle(), expectedTitle, "Expected Title is "+expectedTitle+ " but acutal is "+landingPage.getTitle());
        /*if (landingPage.getTitle().equals("My Store")) {
            System.out.println("Title Matched - Test Passes");
        } else {
            System.out.println("Title doesn't match - Test Failed");
        }
        */
    }

}

 

The expected value is stored in a variable expectedTitle of type String. Assert.assertEquals() accepts 3 variables:

  1. Actual value
  2. Expected Value
  3. A message which is printed when the assertion/ validation fails

Similarly, do this for rest of the test classes.

 

ProductSearchPageTest.java

 

 

package com.appliedselenium.tests;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.appliedselenium.pages.LandingPage;
import com.appliedselenium.pages.ProductSearchPage;

public class ProductSearchPageTest extends DriverTest {

    @Test
    public void isProductSearched() {
        ProductSearchPage pr;
        String productResult = "Printed Summer Dress";
        LandingPage landingPage = new LandingPage();
        // Navigate to Product Search page
        landingPage.searchProduct();

        // Instantiate ProductSearchPage class object
        pr = new ProductSearchPage();

        // Verify the text
        Assert.assertEquals(pr.getProductSearchResult(), productResult, "Expected Title is "+productResult+ " but acutal is "+pr.getProductSearchResult());
        /*if (pr.getProductSearchResult().contains("Printed Summer Dress")) {
            System.out.println("Product Found");
        } else {
            System.out.println("Product Search Failed");
        }*/

    }

}

 

 

SignInPageTest.java

 

 

package com.appliedselenium.tests;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.appliedselenium.pages.HomePage;
import com.appliedselenium.pages.LandingPage;
import com.appliedselenium.pages.SignInPage;

public class SignInPageTest extends DriverTest{

    
    @Test
    public void verifySignIn() {
        LandingPage landingPage = new LandingPage();
        SignInPage inPage;
        HomePage homePage;
        String expectedTitle = "abc xyz";
        
        // Click on Sign In button
                landingPage.clickOnSignIn();

                inPage = new SignInPage();
                inPage.userSignIn("abc11001@xyz.com", "abcxyz");

                homePage = new HomePage();
                
                Assert.assertEquals(homePage.verifyCorrectLogin(), expectedTitle, "Expected Title is "+expectedTitle+ " but acutal is "+homePage.verifyCorrectLogin());
/*
                if (homePage.verifyCorrectLogin().equals("abc xyz")) {
                    System.out.println("Login Successful");
                } else {
                    System.out.println("Login Failed");
                }
*/
    }
}

 

Run the testng.xml file as TestNG Suite and all the tests should get executed.

See you in the next tutorial.

 

Author: Dhawal Joshi

A post-graduate in MCA, ISTQB & ITIL certified QA with more than 8 years of experience in QA working with a CMMI Level 5 organization as System Analyst. I started my automation journey with HP UFT(formerly known as QTP) and for the past few years, I am using Selenium for automation. I also have experience in Android Application Development, Java, HTML, and VBScript. When I am not working, I like to spend time with my family, cooking and learning new developments in IT.

9 thoughts on “Creating Test Classes Using TestNG | Part 8

  1. Hi suppose in your above class “LandingPageTest.java”, more than one @Test annotation is there, say i.e 3 ‘@Test’ annotations are there your code will get log in & log out 3 times?
    And my second question is, can we continue/write all steps/actions under one ‘@Test’ annotaion? or should have more than one @Test annotation. I know it sound strange question but yes i am somewhat confused.

    1. Ans 1: No. If you only copy-paste the same @Test (with different method name) and try to execute, it won’t work. We have to modify our code if we want to logout and login. In the exisitng code, if the test is pass, then next web page is loaded and you’ll loose the reference of LandingPage.

      Ans 2: 1 @Test annotation/method represents one manual test case. If you look into any manual test case, it consists of many test steps with validation at each step. In automation we translate each manual test step into code. Thus you must use different @Test annotations/methods for each manual test case.

  2. Hey will you please check my code and reply.
    public class PatientSearchTest extends StartBrowser {
    @BeforeMethod
    public void loginintoApp( )
    {
    TC1 tc = new TC1();
    tc.testLogin();

    }
    @Test
    public void Test1() {
    System.out.println(“I am in Test 1”);
    }
    @Test
    public void Test2() {
    System.out.println(“I am in Test 2”);
    }
    @AfterMethod()
    public void tearDown(){
    driver.quit();
    }
    }
    Output: I am in Test 1
    FAILED CONFIGURATION: @BeforeMethod loginintoApp
    org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
    SKIPPED CONFIGURATION: @AfterMethod tearDown
    PASSED: Test1
    SKIPPED: Test2

    1. Please share your whole project, including the testng.xml file.

      I would encourage you to learn GIT and maintain an online repository for all of your projects. This would also be helpful in situations, like this, where you need to share your project with others. Focus more on command line git (bash), it is widely used in industry for code management.

  3. Sorry i can not share my project as have to follow company’s security policy. I know then it would be a great and easy solution for my issues. But i can’t.
    As per you your first Ans1 -yes agreed have to write it down different code say i.e @Test1 –verifying title, @Test2—Verifying Logo @Test3 clicking and filling up form. Different methods will be there.
    Should it login and logout for each and every test annotation. To do that @BeforeMethod–Login activity happening then @Test and then @AfterMethod — where calling driver.quit() method.
    But running only first @Test and skipping remaining @Test.

    1. If you do not want to logout/logout for every @Test in a class, do the following:
      1. Write the @Test methods in such a way that second test should handle where first test was finished.
      2. You can control the @Before and @After using @BeforeTest and @AfterTest annotations

      Again, it all depends on functionality and test cases. You can control the execution behavior as per your requirement.

  4. Thank you so much. Tried with @Before/After Method but getting an error. Any way thanks a lot as per your suggestion will try. I need to change my entire framework structure i guess.
    Thanks.

  5. Hi, I do have a one more question. Say for example to execute one @Test annotation around 15 @FindBy annotations are there and written 15 different methods/actions for it. should i write it down all actions/methods under same heading. or should be individual action/method. I have mentioned as below and then individually all these methods calling one after another in testclass. Please see the below code.
    public void clearPatientSearchRecords()
    {
    clearPatientSearch.click();
    log.info(“Clcked on Search button”); }
    public void selectFirstOption() {
    firstOption.click(); }
    public void selectSecondOption() {
    secondOption.click(); }

    public void clickOnViewDetails() {
    btnViewDetails.click(); }
    public void clickOnCancel() {
    clickCancel.click(); }
    public void clickOnEditPatient() {
    editPatient.click(); }
    public void clickOnFaceSheetOption() {
    clickFaceSheet.click();
    } public void clickOnClinicalOption() {
    clickClinical.click(); }
    public void clickOnRiskProfile() {
    clickRiskProfile.click(); }
    public void clickOnCareGaps() {
    clickCareGaps.click(); }

    public void clickOnCloseButton() {
    clickCloseButton.click(); }
    public void clickAndClearRecords() {
    clearRecords.click(); }
    And in Test class i am defining as below:
    @Test
    public void PatientSearchTest() throws Exception
    {
    ExtentTestManager.getTest().log(Status.INFO,”Hey i am in Patient Search Test”);
    Thread.sleep(2000);
    //waithelper.waitForElement(, 30, 5);
    ps.hoverTest();
    ps.clickContractOptionTextbox();
    ps.selectContractOption();
    ps.enterPatientName(“Peggy Uehara”);
    Thread.sleep(2500);
    ps.selectFirstOption();
    ps.selectSecondOption();
    Thread.sleep(1500);
    ps.clickOnViewDetails();
    ps.clickOnEditPatient();
    Thread.sleep(4000);
    ps.clickOnCancel();
    Thread.sleep(2000);
    ps.clickOnFaceSheetOption();
    Thread.sleep(7000);
    ps.clickOnClinicalOption();
    Thread.sleep(4000);
    ps.clickOnRiskProfile();
    Thread.sleep(4000);
    ps.clickOnCareGaps();
    Thread.sleep(4000);
    ps.clickOnCloseButton();
    ps.clickAndClearRecords();
    }

    Or should i write it down as below all the methods together under one heading. and then call single method in testpage.
    public HomePage login(String un, String pwd) {
    username.sendKeys(un);
    password.sendKeys(pwd);
    loginBtn.click();
    return new HomePageNaveen();
    }

Leave a Reply

Your e-mail address will not be published. Required fields are marked *