YuWebdesign



TestNG Interview Questions

By YuwebDesign


About TestNG

Since Selenium does not support report generation and test case management, we use TestNG framework with Selenium.

TestNG is an open source unit test framework that supports test driven development.

Purpose for using in test automation: it allows for designing test cases in a more systematic and flexible way.

TestNG Categories of tests

TestNG is designed to cover all categories of tests:

  1. unit,
  2. functional,
  3. end-to-end,
  4. integration, etc…

TestNG is a testing framework designed to simplify a broad range of testing needs,

  1. from unit testing
    • (testing a class in isolation of the others)
  2. to integration testing
      (testing entire systems made of

    • several classes,
    • several packages
    • and even several external frameworks,
      such as application servers).
TestNG Functionalities

TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use, such as:

  1. Various Annotations
  2. parallel execution of tests
  3. Dependency:
    E.g., Dependent methods for application server testing.
  4. report generation
    html reports+additional report features with plugins like ExtentReports or Allure Reports
  5. priority/sequence
  6. grouping
  7. Support for data-driven testing (with @DataProvider).
  8. Support for parameters.
  9. Run your tests in arbitrarily big thread pools with various policies available (all methods in their own thread, one thread per test class, etc…).
  10. Test that your code is multithread safe.
  11. Flexible test configuration.
  12. Powerful execution model (no more TestSuite).
  13. Supported by a variety of tools and plug-ins (Eclipse, IDEA, Maven, etc…).
  14. Embeds BeanShell for further flexibility.
  15. Default JDK functions for runtime and logging (no dependencies).

Writing a test is typically a three-step process:

  1. Write the business logic of your test and insert TestNG annotations in your code.
  2. Add the information about your test (e.g. the class name, the groups you wish to run, etc…) in a testng.xml file or in build.xml.
  3. Run TestNG.

TestNG main concepts:

  1. A suite
    is represented by one XML file.
    It can contain one or more tests and is defined by the ⟨suite⟩ tag.
  2. A test
    is represented by ⟨test⟩
    and can contain one or more TestNG classes.
  3. A TestNG class
    is a Java class that contains at least one TestNG annotation.
    It is represented by the ⟨class⟩ tag
    and can contain one or more test methods.
  4. A test method
    is a Java method annotated by @Test in your source.
  5. A TestNG test can be configured by @BeforeXXX and @AfterXXX annotations
    which allow to perform some Java logic before and after a certain point,
    these points being either of the items listed above.

Feature JUnit4 TestNG
Annotation Support Yes Yes
Suite Test Yes Yes
Ignore Test Yes Yes
Exception Test Yes Yes
Timeout Yes Yes
Parameterized Test
(primitive value)
Yes Yes
Parameterized Test
(object)
No Yes
Dependency Test No Yes
Group Test No
(@Tag identifies groups in JUnit5)
Yes
JUnit vs. TestNG annotations
TestNG JUnit Description
@Test @Test A test method
is a Java method annotated by @Test in your source.
@BeforeClass @BeforeClass Executes before the first test method is invoked in the current class
@AfterClass @AfterClass Executes after all the test methods in the current class
@BeforeMethod @Before Executes before each test method
@AfterMethod @After Executes after each test method
@Test(enabled=false) @ignore annotation to ignore a test
@Test(expectedExceptions = ArithmeticException.class) @Test(expected = ArithmeticException.class) annotation for exception
@Test(timeout = 1000) @Test(timeout = 1000) timeout
@BeforeSuite n/a Executes before all tests in this suite have run
@AfterSuite n/a Executes after all tests in this suite have run
@BeforeTest n/a
(@BeforeEach in JUnit5)
Executes before a test runs
@AfterTest n/a Executes after a test runs
@BeforeGroups n/a Executes before the first test method that belongs to any of the groups is invoked
@AfterGroups n/a Runs after the last test method that belongs to any of the groups
JUnit vs. TestNG Static Methods

JUnit: @BeforeClass and @AfterClass methods have to be declared as static.
TestNG does not have this constraint.

JUnit vs. TestNG Suite Test
  1. Suites are used to execute multiple tests together.
  2. Suites can be created using both TestNG and JUnit4.
  3. However, suites are more powerful in TestNG as it uses very different method for execution of tests.
  4. TestNG uses .xml to bundle all tests at one place.
TestNG JUnit

⟨!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd"⟩
⟨suite name="My test suite"⟩
⟨test name="testing"⟩
⟨classes⟩
⟨class name="com.yuwebdesign.SuiteTest1" /⟩
⟨class name="com.yuwebdesign.SuiteTest2" /⟩
⟨/classes⟩
⟨/test⟩
⟨/suite⟩

package yuwebdesign.junit;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
SuiteTest1.class,
SuiteTest2.class,
})

public class JunitTest {
// This class remains empty, it is used only as a holder for the above annotations
}

JUnit vs. TestNG Ignore Test

Using both, JUnit and TestNG, we can skip a test.

TestNG JUnit
@Test(enabled=false)
public void TestWithException() {
System.out.println("Method should be ignored as it's not ready yet");
}
@Ignore
public void method1() {
System.out.println("Using @Ignore , this execution is ignored");
}
JUnit vs. TestNG Exception Test

Exception testing is available both in TestNG and JUnit4.

TestNG JUnit
@Test(expectedExceptions = ArithmeticException.class)
public void divideByZero() {
Int i = 1/0;
}
@Test(expected = ArithmeticException.class)
public void divideByZero() {
Int i = 1/0;
}
JUnit vs. TestNG Timeout

This feature is implemented both in TestNg and JUnit4.
Timeout is used to terminate a test which takes longer than specified time (in milliseconds).

TestNG JUnit
@Test(timeOut = 1000)  
public void method1() {  
	while (true);  
}
@Test(timeout = 1000)  
public void method1() {  
	while (true);  
}
JUnit vs. TestNG Parameterized Test

Both TestNG and JUnit supports parameterized test but differ in the way they define the parameter value.

JUnit provides an easier and readable approach to test known as Parameterized test.
The “@RunWith” and “@Parameter” annotations are used to provide parameter value for the unit test.
The annotation @Parameters have to return List[].
This parameter will be passed into the class constructor as an argument.

In TestNG, XML file or “@DataProvider” is used to provide a parameter for testing.

Here @Parameters annotation declared in the method, needs a parameter for testing.
The data used as the parameter will provide in TestNG’s XML configuration files.
By doing this, we can reuse a single Test Case with different data sets, and we can get different results.

TestNG JUnit
public class Test1 {

@Test
@Parameters(value="number")
public void parameterTest(int number) {
System.out.println("Parameterized Number is : " + number);
}

}

.xml file:

⟨!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd"⟩
⟨suite name="My test suite"⟩
⟨test name="testing"⟩

⟨parameter name="number" value="2"/⟩

⟨classes⟩
⟨class name="com.yuwebdesign.Test1" /⟩
⟨/classes⟩
⟨/test⟩
⟨/suite⟩

@RunWith(value = Parameterized.class)
public class JunitTest{

privateint number;

public JunitTest6(int number)
{
this.number = number;
}

@Parameters
public static Collection data()
{
Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
returnArrays.asList(data);
}

@Test
public void parameterTest()
{
System.out.println("Parameterized Number is : " + number);
}
}

JUnit 4 and TestNG are similar on the surface.

Major difference in TestNG and JUnit test frameworks is their scope.
JUnit is designed to hone in on a unit of code.

TestNG is meant for high-level testing and complex integration test.
Its flexibility is especially useful with large test suites.

Its flexibility is especially useful with large test suites.
TestNG is more advanced in parameterize testing, dependency testing and suite testing (Grouping concept).

In addition, TestNG also covers the entire core JUnit4 functionality.

Each framework has its strengths, and there’s nothing stopping you from using both in concert.

TestNG configuration file testng.xml

Test Suits and Test Grouping

testng.xml file is where we define the test suites and grouping of test classes in TestNG.

Test suite is basically a collection/group of test cases.

We cannot define a test suite in testing source code,
instead it is represented in an XML file,
because suite is the feature of execution.

For executing the test cases in a suite you have to create a testng.xml file
which contains the name of all the classes and methods
that you want to execute as a part of that execution flow.

Other advantages of using testng.xml file are
  1. It allows execution of multiple test cases from multiple classes
  2. It allows parallel execution
  3. It allows execution of test cases in groups, where a single test can belong to multiple groups

  1. A suite is made of two parts:
    • tests
    • parameters
  2. A test is made of three parts:
    • parameters, which override the suite parameters
    • groups, made of two parts
    • classes, defining which classes are going to be part
      of this test run
  3. groups are made of two parts:
    • Definitions, which allow you to group groups into
      bigger groups

    • Runs, which defines the groups that the methods
      must belong to in order to be run during this test

A suite is the top-level element of a testng.xml file


Atributes Desctiption Example
name The name of this suite (as it will appear in the reports)

TestNG Annotations

Annotations
Annotation Description Example
@BeforeSuite/ @AfterSuite Executes before/after all tests in this suite have run
@BeforeGroups/ @AfterGroups The list of groups that this configuration method will run before/after.
Executes before/after test methods that belong to any of the groups are invoked.
@BeforeClass/ @AfterClass Executes before/after the first/last test method in the current class is invoked.
@BeforeMethod/ @AfterMethod Executes before/after each test method.
@BeforeTest/ @AfterTest Executes before/after any test method belonging to the classes inside the ⟨test⟩ tag is run.

Behaviour of annotations in superclass of a TestNG class

The annotations above will also be honored (inherited) when placed on a superclass of a TestNG class. This is useful for example to centralize test setup for multiple test classes in a common superclass.

In that case, TestNG guarantees that the “@Before” methods are executed in inheritance order (highest superclass first, then going down the inheritance chain), and the “@After” methods in reverse order (going up the inheritance chain).

Attributes
Annotation Description Example
alwaysRun For before methods (beforeSuite, beforeTest, beforeTestClass and beforeTestMethod, but not beforeGroups)
If set to true, this configuration method will be run regardless of what groups it belongs to.

For after methods If set to true, this configuration method will be run even if one or more methods invoked previously failed or was skipped.

dependsOnGroups The list of groups this method depends on.
dependsOnMethods The list of methods this method depends on.
enabled Whether methods on this class/method are enabled.
groups The list of groups this class/method belongs to.

  1. In TestNG, methods can be categorized into groups.
  2. When a particular group is being executed, all the methods in that group will be executed.
  3. We can execute a group by parameterizing it’s name in group attribute of @Test annotation.
@Test(groups={“Car”})
public void drive(){
system.out.println(“Driving the vehicle”);
}

@Test(groups={“Car”})
public void accelerate(){
system.out.println(“Accelerating”);
}
inheritGroups If true, this method will belong to groups specified in the @Test annotation at the class level.
onlyForGroups Only for @BeforeMethod and @AfterMethod.

If specified, then this setup/teardown method will only be invoked if the corresponding test method belongs to one of the listed groups.

Annotation Description Example
@Test Marks a class or a method as part of the test.

A test method is a Java method annotated by @Test in your source.

Attribute Description Example
description The description for this method.
dataProvider The name of the data provider for this test method.
dataProviderClass The class where to look for the data provider. If not specified, the data provider will be looked on the class of the current test method or one of its base classes. If this attribute is specified, the data provider method needs to be static on the specified class.
groups The list of groups this class/method belongs to.

  1. In TestNG, methods can be categorized into groups.
  2. When a particular group is being executed, all the methods in that group will be executed.
  3. We can execute a group by parameterizing it’s name in group attribute of @Test annotation.
@Test(groups={“Car”})
public void drive(){
system.out.println(“Driving the vehicle”);
}

@Test(groups={“Car”})
public void accelerate(){
system.out.println(“Accelerating”);
}
dependsOnGroups The list of groups this method depends on.
dependsOnMethods The list of methods this method depends on.
alwaysRun If set to true, this test method will always be run even if it depends on a method that failed.
enabled Whether methods on this class/method are enabled. @Test(enable=false)
annotation to ignore a test
expectedExceptions The list of exceptions that a test method is expected to throw. If no exception or a different than one on this list is thrown, this test will be marked a failure. @Test(expectedExceptions = ArithmeticException.class)
public void divideByZero() {
Int i = 1/0;
}
timeOut The maximum number of milliseconds this test should take. @Test(timeout = 1000)
invocationTimeOut The maximum number of milliseconds this test should take for the cumulated time of all the invocationcounts. This attribute will be ignored if invocationCount is not specified.
invocationCount The number of times this method should be invoked. @Test(invocationCount=x)
this method should be invoked x number of times
threadPoolSize The size of the thread pool for this method.
threadPoolSize is used for executing suites in parallel. Each suite can be run in a separate thread.

The method will be invoked from multiple threads as specified by invocationCount.
Note: this attribute is ignored if invocationCount is not specified

@Test(threadPoolSize=x) with @Test(invocationCount=x)
To specify how many times @Test method should be invoked from different threads

@Test(threadPoolSize = 3, invocationCount = 10)
public void testServer() {
}
singleThreaded If set to true, all the methods on this test class are guaranteed to run in the same thread, even if the tests are currently being run with parallel=”methods”. This attribute can only be used at the class level and it will be ignored if used at the method level. Note: this attribute used to be called sequential (now deprecated).
priority The priority for this test method. Lower priorities will be scheduled first.
successPercentage The percentage of success expected from this method

If you want to skip a particular test method, then you can set the ‘enabled’ parameter in test annotation to false.

@Test(enabled = false)

By default, the value of ‘enabled’ parameter will be true.
Hence it is not necessary to define the annotation for the “true” case.

Annotations
Annotation Description Example
Attributes
Attribute Description Example

Parameterization in TestNG

What is parameterization in TestNG?

Parameterization
technique of defining values in testng.xml file
and sending them as parameters to the test class.

This technique is especially useful when we need to pass multiple login credentials of various test environments.

Annotation Description Example
@Parameters Describes how to pass parameters to a @Test method. E.g., “myName” is annotated as a parameter.

public class ParameterizedTest1{
 @Test
 @Parameters("myName")
 public void parameterTest(String myName) {
 System.out.println("Parameterized value is : " + myName);
 }
}

To pass parameters using testng.xml file, we need to use ‘parameter’ tag.

⟨?xml version="1.0" encoding="UTF-8"?⟩
⟨!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"⟩
 ⟨suite name=”CustomSuite"⟩
  ⟨test name=”CustomTest”⟩ 
   ⟨parameter name="myName" value=”John"/⟩
    ⟨classes⟩
     ⟨class name="ParameterizedTest1" /⟩
    ⟨/classes⟩ 
  ⟨/test⟩
 ⟨/suite⟩
Attribute Description Example
value The list of variables used to fill the parameters of this method.

Annotation Description Example
@DataProvider
  1. DataProvider is a TestNG feature, which enables us to write DataDriven tests.
  2. Supporting DataDriven testing, means that the same test method can run multiple times with different data-sets.
  3. DataProvider is a way of passing parameters to the test method.
  4. @DataProvider marks a method as supplying data for a test method.
  5. The annotated method must return an Object[][] where each Object[] can be assigned the parameter list of the test method.
  6. To use the DataProvider feature in your tests, you have to declare a method annotated by @DataProvider and then use the said method in the test method using the ‘dataProvider‘ attribute in the Test annotation.
  7. The @Test method that wants to receive data from this DataProvider needs to use a dataProvider name equals to the name of this annotation.
Attributes for @DataProvider
name The name of this data provider.

If it’s not supplied, the name of this data provider will automatically be set to the name of the method.

parallel If set to true, tests generated using this data provider are run in parallel.
Default value is false.
Attributes for @Test
dataProvider The name of the data provider for this test method.
dataProviderClass The class where to look for the data provider. If not specified, the data provider will be looked on the class of the current test method or one of its base classes. If this attribute is specified, the data provider method needs to be static on the specified class.

Yes, the same DataProvider can be used in multiple functions and classes by declaring DataProvider in a separate class and then reusing it in multiple classes.

Assertions

  1. Soft Assertions are customized error handlers provided by TestNG.
  2. Soft Assertions do not throw exceptions when assertion fails, and they simply continue to the next test step.
  3. They are commonly used when we want to perform multiple assertions.
How can you mark a test case as failed by using soft assertion?

To mark a test as failed with soft assertions, call assertAll() method at the end of the test.

Hard assertion (hard validation)

If a hard assertion is getting failed: immediately test case will me marked as failed and test case will be terminated.

Soft assertion (soft validation)

If a soft assertion is getting failed: test case will not be marked as passed as well as next lines will be executed

assertAll()

Used to mark the test case as failed, if any soft assertion is getting failed

Group Tests in TestNG

TestNG Groups Attributes
Attribute Description Example
groups The list of groups this class/method belongs to.

  1. In TestNG, methods can be categorized into groups.
  2. When a particular group is being executed, all the methods in that group will be executed.
  3. We can execute a group by parameterizing it’s name in group attribute of @Test annotation.
@Test(groups={“Car”})
public void drive(){
system.out.println(“Driving the vehicle”);
}

@Test(groups={“Car”})
public void accelerate(){
system.out.println(“Accelerating”);
}
inheritGroups If true, this method will belong to groups specified in the @Test annotation at the class level.
onlyForGroups Only for @BeforeMethod and @AfterMethod.

If specified, then this setup/teardown method will only be invoked if the corresponding test method belongs to one of the listed groups.

dependsOnGroups The list of groups this method depends on.

TestNG Dependencies

Dependency is a feature in TestNG that allows a test method to depend on a single or a group of test methods.

Annotation Attribute Description Syntax
groups The list of groups this class/method belongs to.

  1. In TestNG, methods can be categorized into groups.
  2. When a particular group is being executed, all the methods in that group will be executed.
  3. We can execute a group by parameterizing it’s name in group attribute of @Test annotation.

@Test(groups={“Car”})
public void drive(){
system.out.println(“Driving the vehicle”);
}

@Test(groups={“Car”})
public void accelerate(){
system.out.println(“Accelerating”);
}

dependsOnGroups The list of groups this method depends on.
dependsOnMethods The list of methods this method depends on.

Method dependency only works if the “depend-on-method” is part of the same class or any of the inherited base classes (i.e. while extending a class).

Syntax:

@Test(dependsOnMethods = { “initEnvironmentTest” })

Example:

@Test(groups={“Car”})
public void drive(){
system.out.println(“Driving the vehicle”);
}

@Test(dependsOnMethods={“drive”},groups={cars})
public void changeGear() {
system.out.println("Change Gears”);
}

@Test(dependsOnMethods={“changeGear”},groups={“Car”})
public void accelerate(){
system.out.println(“Accelerating”);
}

alwaysRun If set to true, this test method will always be run even if it depends on a method that failed.

TestNG Listeners

Annotation Description Example
@Listeners Defines listeners on a test class.
Attribute Description Example
value An array of classes that extend org.testng.ITestNGListener.

You might be facing random failures during an automated test run.

These failures might not necessarily be because of product bugs.

These failures can be because of following reasons
  1. Random browser issues
  2. Browser becoming unresponsive
  3. Random machine issues
  4. Server issues like unexpected delay in the response from server
  5. Application not responding properly
  6. Application is very slow
  7. Network is very slow, hence app is very slow
  8. Ajax Component could not be loaded properly
  9. HTML DOM is slow
There are two ways to implement retry logic using TestNG Listener
  1. By specifying retryAnalyzer value in the @Test annotation
  2. By adding Retry analyser during run time by implementing IAnnotationTransformer interfaces

Execution of Multiple Tests

Attribute Description Example
invocationTimeOut The maximum number of milliseconds this test should take for the cumulated time of all the invocationcounts. This attribute will be ignored if invocationCount is not specified.
invocationCount The number of times this method should be invoked. @Test(invocationCount=x)
this method should be invoked x number of times
threadPoolSize The size of the thread pool for this method.
threadPoolSize is used for executing suites in parallel. Each suite can be run in a separate thread.

The method will be invoked from multiple threads as specified by invocationCount.
Note: this attribute is ignored if invocationCount is not specified

@Test(threadPoolSize=x) with @Test(invocationCount=x)
To specify how many times @Test method should be invoked from different threads

@Test(threadPoolSize = 3, invocationCount = 10)
public void testServer() {
}
singleThreaded If set to true, all the methods on this test class are guaranteed to run in the same thread, even if the tests are currently being run with parallel=”methods”. This attribute can only be used at the class level and it will be ignored if used at the method level. Note: this attribute used to be called sequential (now deprecated).

Annotation Description Example
@Factory Marks a method as a factory that returns objects that will be used by TestNG as Test classes. The method must return Object[].


Leave a Reply or Comment

Your email address will not be published. Required fields are marked *