TestNG
The Basics
TestNG is an open source Java testing framework which is powerful yet easy to use. TestNG is designed to cover all categories of tests: unit, functional, end-to-end, integration, etc.
Before moving ahead with TestNG, it is important to understand it's basic architecture. Diagram below depicts its architecture at high level.
- Suite - Top level of any TestNG project and is maintained as an XML artifact.
- Test - Representation of Test which can be one or more in a Suite.
- Classes - Also known as a TestNG class, contains one or more test methods.
- Methods - An Optional container for one or more test methods. These test methods contains actual test code.
TestNG executes any test suite, following the order defined by the testng.xml. Test developers can plugin their logic in this flow of execution using special configuration Annotations.
Annotation | Description |
---|---|
@BeforeSuite | The annotated method will be run before all tests in this suite have run. |
@AfterSuite | The annotated method will be run after all tests in this suite have run. |
@AfterTest | The annotated method will be run before any test method belonging to the classes inside the <test> tag is run. |
@BeforeGroups | The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked. |
@AfterGroups | The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked. |
@BeforeClass | The annotated method will be run before the first test method in the current class is invoked. |
@AfterClass | The annotated method will be run after all the test methods in the current class have been run. |
@BeforeMethod | The annotated method will be run before each test method. |
@AfterMethod | The annotated method will be run after each test method. |
Run TestNG Tests for Mobile or Web with seetest.io
Before you proceed with fetching the sample tests:
- If you plan to test a native or hybrid app, upload your app to your project.
- Fetch your access key.
- Find the sample test in our git repository.
- Fork the repository.
- Edit the test and click Run.
TestNG - Further Reading - Advanced Concepts
To start using TestNG, you need its libraries. There are two ways you can do it and actually depends on underlying build mechanism of the test suite.
-
Build and use the library.
If the underlying build system of your project does not have capability of Automatic discovery of dependency (Example: Maven or Gradle), you need to build TestNG source and then use the Jars.$ git clone git://github.com/cbeust/testng.git
$ cd testng
$ ./build-with-gradleThe Jars will be built in the target directory which can be used set in your classpath for the project.
-
Configure the dependency.
If your project uses Gradle or Maven, then TestNG dependency needs to be configured.
Maven: Configure following in pom.xml.
'<repositories>
<repository>
<id>jcenter</id>
<name>bintray</name>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.10</version>
<scope>test</scope>
</dependency>Gradle Configure following in build.gradle.
repositories {
jcenter()
}
dependencies {
compile 'org.testng:testng:6.10'
}
Automated test Using TestNG
TestNG is a feature rich framework but to write a very basic test is a simple task.
-
Write the business logic of the test..
Test Method
package test;
public class HelloWorldTest {
@Test
public void testHelloWorld() {
// write business logic for test
}
}Notice the "@Test" annotation above, this annotation marks a function as test so that TestNG engine runs it as a test without even being configured in testng.xml
-
Create a testng.xml file,
testng.xml
<suite name="Suite1" verbose="1" >
<test name="HelloWorldTest" >
<classes>
<class name="test.HelloWorldTest" />
</classes>
</test> -
Run the TestNG.
Assuming TestNG is set in your classpath, you can use this syntax:
java org.testng.TestNG testng.xml
Mobile and Browser Testing Using TestNG
TestNG at its core is a Java testing framework, but it does not have direct capabilities to test Mobile and Browser based applications. Hence we need Java based libraries in conjunction with TestNG to achieve the same.
Appium and Selenium provide Java based client bindings to interact with Appium/Selenium servers which work on Mobile devices and Browsers.
To use TestNG in conjunction with Appium and Selenium:
-
Download the Java bindings for Appium or configure the Appium or Selenium dependency in the build tool.
If you are using Gradle as build system, configure the dependencies in build.gradle:
repositories {
mavenCentral()
}
dependencies {
compile group: 'io.appium', name: 'java-client', version: '+'
compile group: 'org.testng', name: 'testng', version: '6.9.10'
}Notice the io.appium group.
Best practice is to create the Gradle Project/Maven Project using IntelliJ or Eclipse and configure dependency in build tool.
-
Implement a TestNG class which uses the Appium library.
Typically, you need to first setup or create a Driver instance for testing a Device or Browser. This is done by creating Desired Capabilities and then using it to create the Driver instance.
Create Desired Capabilities:
Desired Capabilities are features which Client requests to Appium/Selenium server.
Desired Capabilities for Mobile
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("appActivity", ".loginActivity");
capabilities.setCapability("appPackage", "com.experitest.ExperiBank/.LoginActivity");In the above example client is requesting specific Android application on an Android Device.
Desired Capabilities for Browser
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability(CapabilityType.BROWSER_NAME, "chrome");In the above example client is requesting a chrome browser on that an Android Device .
Create a Driver with desired capabilities
Create Driver for an Android Device
AndroidDriver driver = new AndroidDriver<AndroidElement>(new URL("https://cloud.seetest.io:443/wd/hub"), capabilities);
First argument is the appium service and second argument is capabilities object.
Similarly, browser application can be tested by creating an instance of RemoveWebDriver object.
Create Driver for Browser
RemoteWebDriver = new RemoteWebDriver (new URL("https://cloud.seetest.io:443/wd/hub"), capabilities);
Driver creation ideally should be done in a function with "@BeforeClass" TestNG annotation since it can be reused in all the test methods.
@BeforeClass
public class EriBankTest {
private DesiredCapabilities capabilities = new DesiredCapabilities();
private AndroidDriver driver = new AndroidDriver<AndroidElement>();
@BeforeClass
public void setup() {
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("appActivity", ".loginActivity");
capabilities.setCapability("appPackage", "com.experitest.ExperiBank/.LoginActivity");
AndroidDriver driver = new AndroidDriver<AndroidElement>(new URL("https://cloud.seetest.io:443/wd/hub"), capabilities);
}
}
-
Implement Test Methods in TestNG class.
Once the Driver is created, it can be used to Locate the elements in Mobile application or Browser and test or automate.
Test Method for a Mobile application:
Test Method for Device Application
@Test
public void testLogin() {
// Locate the elements to test.
driver.findElement(By.xpath("//*[@id='usernameTextField']")).sendKeys(userName);
driver.findElement(By.xpath("//*[@id='passwordTextField']")).sendKeys(password);
driver.findElement(By.xpath("//*[@id='loginButton']")).click();
}Test Method for a Browser:
Test Method for Browser
@Parameters({"title"})
public void testGetTitle(String title) {
driver.get("http://google.com");
Asserts.assert(driver.getTitle(),title);
}
Extending Sample TestNG Project
Now that you have got the sample test from the git repository running, extend it to run for your own application instead of EriBank application to a specific targeted device in the SeeTest Cloud.
-
Open the appium-java-testng project in IntelliJ or Eclipse as Gradle project.
-
Upload your application to a project manually by following the documentation in Native Applications Testing.
-
Modify the relevant <platform>.app.name property insrc/main/java/resources/seetest.properties with the correct application name.
infoNative Applications Testing mentions the application name which can be used as a value for <platform>.app.name property under heading "Upload your Application Manually".
-
Create a class under the package io.appium.testng. Use the template class below to kickstart your testing.
Java Template class for extending tests Expand source
package io.appium.testng;
import io.appium.java_client.remote.MobileCapabilityType;
import org.testng.annotations.Optional;
import org.testng.annotations.Test;
import utils.SeeTestProperties;
public class FirstTest extends TestBase {
/**
* Sets up the default Desired Capabilities.
*/
protected void initDefaultDesiredCapabilities() {
LOGGER.info("Enter initDefaultDesiredCapabilities");
super.initDefaultDesiredCapabilities();
this.setAppCapability(os);
buildDeviceQuery();
LOGGER.info("Exit initDefaultDesiredCapabilities");
}
/**
* sets the application ("app") capability based on the OS and the property which was defined in the seetest.properties file
*
* @param os
*/
private void setAppCapability(@Optional("android") String os) {
String appName = os.equals("android") ?
properties.getProperty(SeeTestProperties.Names.ANDROID_APP_NAME) :
properties.getProperty(SeeTestProperties.Names.IOS_APP_NAME);
appName = String.format("%s%s", "cloud:", appName);
LOGGER.info("Setting up {} as app capability", appName);
dc.setCapability(MobileCapabilityType.APP, appName);
}
private void buildDeviceQuery() {
this.deviceQuery = String.format("%s and %s","@os='" + os + "'", "@serialnumber='LGH990f2578648'");
dc.setCapability(SeeTestCapabilityType.DEVICE_QUERY, this.deviceQuery);
LOGGER.info("Device Query in buildDeviceQuery() - " + this.deviceQuery);
}
@Test()
public void firstTest() {
// add the operations and tests.
}
}infofirstTest function can be added with any functionality you want to test.
-
Edit @serialnumber in buildDeviceQuery function (i.e. @serialnumber='LGH990f2578648') to any Device ID of your choice by following this video.
-
Edit src/main/java/testng.xml to add following reference of the Test class ( <test name="FirstTest">) we introduced before, at Step 3.
testng.xml Expand source
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestNGExample" configfailurepolicy="continue" verbose="2">
<!--<parameter name = "userName" value="company"/>
<test name="AndroidTestNGExample">
<classes>
<class name="io.appium.testng.AndroidTestNGExampleTest">
<parameter name = "userName" value="company"/>
<parameter name = "os" value="android"/>
<methods>
<include name="makePaymentTest" />
<include name="balanceTest" >
<parameter name = "expectedBalance" value="90"/>
</include>
<include name="dummyTest()"/>
</methods>
</class>
</classes>
</test>
<test name="IOSTestNGExample">
<parameter name = "os" value="ios"/>
<classes>
<class name="io.appium.testng.IOSTestNGExampleTest">
<methods>
<include name="makePaymentTest" />
<include name="balanceTest" >
<parameter name = "expectedBalance" value="90"/>
</include>
</methods>
</class>
</classes>
</test>
<test name="WebTestNGexample">
<classes>
<class name="io.appium.testng.WebTestNGExampleTest">
<parameter name = "os" value="android"/>
<methods>
<include name="titleTest" >
<parameter name = "url" value="http://google.com"/>
<parameter name = "title" value="Google"/>
</include>
</methods>
</class>
</classes>
</test>-->
<test name="FirstTest">
<classes>
<class name="io.appium.testng.FirstTest">
<parameter name = "os" value="android"/>
</class>
</classes>
</test>
</suite>
-
Other tests in the testng.xml are commented because they depend on EriBank application.
-
It's important to have right combination of the parameter name ="os" in the testng.xml and Device ID, i.e the value (android or ios) needs to same as the operating system of Device ID.
- Run the modified project using modified testng.xml.