@Test annotation with selenium

@Test annotation makes a method to run as the base for the TestNG annotations; method annotated with @test will hold the test logic of the business and assertions.

Every @Test annotated method should correspond to a manual test case; sometimes, some teams may map every @test with a requirement.

The below code runs the @Test first, and it opens the chercher tech website.

public class TestJenkins {
	@Test
	public void openCherCherTech() {
		System.setProperty("webdriver.chrome.driver", "D:PATHchromedriver.exe");

		WebDriver driver = new ChromeDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		System.out.println("open cherCher Tech");
		driver.get("https://chercher.tech");
	}
}

@Test method has a couple of properties that make the @Test more flexible for the execution of the TestNG suite. We will try to cover as much as possible; properties are used like below.

@Test(property = value)

Perform API testing using Rest Assured with Selenium webdriver

Enable / Disable in TestNG

In some situations, you may need to avoid the execution of some of the tests or set of tests present in a specific test class.

For example, there might be a situation where you might have written skeleton code while development for that feature is still in development or the feature is already broken so you know it will fail because of which you might want to ignore those test cases from the suite or from the test class.

When you set enabled=false to test method, then that method will not be part of the test suite, so test result will not have any information regarding these methods. This method will not be considered as skipped

We can Disable the test cases using two ways:

  • @Test Property
  • Using testng.xml (we will discuss later)

@Test(enabled=false) :

When we denote any test method with the property of enabled with a false value, then that method will not be part of test execution, and TestNG will skip such methods.

public class TestJenkins {
	@Test(enabled = false)
	public void openCherCherTech() {
		System.out.println("DisabledTest");
	}
	@Test(enabled = true)
	public void openGoogle() {
		System.out.println("Test with Enable=true");
	}
	@Test
	public void openGoogleWithoutEnable() {
		System.out.println("Test without enable property");
	}
}


enabled-property-int-testng-method

Things to note about the enabled property :

  • By default, TestNG considers enabled=true, if you don't provide one
  • @Test denoted with enabled=false will be ignored from suite not skipped
  • It is an optional parameter
  • It is not mandatory for TestNG to run enabled=true methods, when these methods depend on other methods

Create Headless Firefox Browser in Selenium webdriver

Description of the test

We can provide a description of methods when we want to understand the purpose of the test.

You should use description property to set the description of the property.

public class TestJenkins {
	@Test(description="This test is to demonstrate the purpose of the test")
	public void openCherCherTech() {
		System.out.println("@test with description");
	}
}


The following image is from the TestNG report on the test-output folder. description-test-method-testng

Method Overloading in Selenium and java

priority with @Test in TestNG

Priority is nothing but how much importance we give to a particular thing. Similar to this, TestNg also provides priority to its test methods.

Based on the priority of the test method, the execution occurs.

Let's execute below code and check the output; these program methods don't have any priorities defined

public class TestJenkins {
	@Test
	public void cherCherTech()
	{
		System.out.println("cherCherTech");
	}
	@Test
	public void google()
	{
		System.out.println("google");
	}
	@Test
	public void yahoo()
	{
		System.out.println("yahoo");
	}
}

without-priority-testng

In the above output, you can see all the methods are executed according to alphabetical order, but this is how we should write our test cases as well.

@Test methods should not have any dependencies with other @Test methods, and this is a good design of test methods.

But in practical use most of us don't write our code like that, aren't you ?

In some situations, we might need to write the depend on other methods, or we may want to execute our methods according to an order (which is also a kind of dependency) to achieve a good result.

In such cases, you cannot write all your test methods in alphabetical order, or it may not be feasible for that.

You can also do another funny way like prefixing every method with test001_name(), test002_name() so on, but don't you think, it will haunt you if you want to introduce another method in between methods.

To avoid such kind of issues, TestNG provides a property called priority for @Tests to sequence them or to provide importance to them.

@Test(priority=3) :

Priority is a numeric integer(negative also) constant value; we cannot use a variable in place of priority

Syntax:@Test(priority = 2)
Syntax :@Test(priority = -2)
Wrong :@Test(priority = 2.2)
public class TestJenkins {
	@Test(priority = 5)
	public void cherCherTech()
	{
		System.out.println("cherCherTech with priority 5");
	}
	@Test(priority = 0)
	public void google()
	{
		System.out.println("google with priority 0");
	}
	@Test(priority = -3)
	public void yahoo()
	{
		System.out.println("yahoo with priority -3");
	}
	@Test
	public void bing()
	{
		System.out.println("bing without priority");
	}
}


priority-testng-selenium

The Conclusion from the above result of priority :

  • Priority could be negative, zero, Positive
  • Least priority gets most importance like minus 3 get more importance than plus 5 and minus 3 method gets executed
  • By default TestNG provides zero priority to all @Tests and providing priority is not mandatory
  • When two @Test shares the same priority number then execution happens in alphabetical order only among them

Invocation properties

There are two invocation properties in TestNG:

  • invocationCount
  • invocationTimeOut
  • skipFailedInvocations

invocationCount :

Sometimes you might need to invoke the same method, again and again, to make sure the method doesn't fail or to create data.

invocationCount property helps the user to invoke a particular method with a given number of times.

public class TestJenkins {
	@Test(invocationCount = 3)
	public void cherCherTech()
	{
		System.out.println("cherCherTech");
	}
}


invocation-count-testng

Invocation Timeout in TestNG :

invocationTimeOut is the maximum number of milliseconds that the total number of invocations on this test method should take.

For Example, if invocationTimeOut is set 30 seconds and invocationCount is set to 10 times, then this method should complete all 10 invocations within 30 seconds; otherwise, the test will be marked as a fail.

This annotation will be ignored if the attribute invocationCount is not specified on this method.

public class TestJenkins {
	@Test(invocationCount = 10, invocationTimeOut = 30000)
	public void cherCherTech()
	{
		System.out.println("cherCherTech");
	}
}


invocation-timout-testng

skipFailedInvocations in TestNG :

If true and invocationCount is specified with a value > 1, then all invocations after a failure will be marked as a SKIP instead of a FAIL.

this method will be ignored if invocationTimeOut is specified in the @Test.

public class TestJenkins {
	@Test(invocationCount = 7, skipFailedInvocations=true)
	public void cherCherTech()
	{
		System.out.println("cherCherTech");
		fail("failing to show skipinvocations");
	}
}


skipinvocations-testng

threadPoolSize :

threadPoolSize is denotes how many threads should invoke a specific function.

The threadPoolSize method will be invoked from multiple threads as specified by the invocationCount.

Note: this attribute is ignored if invocationCount is not specified

In the below program, we are expecting 7 Thread to invoke the method.

public class TestJenkins {
	@Test(invocationCount = 7, threadPoolSize=7)
	public void cherCherTech()
	{
		System.out.println("Thread Name : " +Thread.currentThread().getName());
	}
}


The output of the threadPoolSize program

[RemoteTestNG] detected TestNG version 6.14.2
Thread Name : TestNG-methods-3
Thread Name : TestNG-methods-4
Thread Name : TestNG-methods-7
Thread Name : TestNG-methods-6
Thread Name : TestNG-methods-2
Thread Name : TestNG-methods-1
Thread Name : TestNG-methods-5

Ways to select a dropdown option in selenium

timeOut() in TestNG

timeOut is nothing but sets the time limit for the execution of the method; if the method execution is not completed within the given time, then the test method will be considered as fail and marks so.

TestNG allows the user to configure a time period to wait for a test to execute completely. A timeout can be configured in two ways:

  • @Test level : This will be applicable for the said test method and will override the time period if configured at the suite level
  • testng.xml level : This will be applicable for all the tests in the said TestNG test suite

timeOut units are measured in terms of Milli-seconds

public class TestJenkins {
	// 5 seconds max
	@Test(timeOut=5000)
	public void cherCherTech() throws Exception
	{
		// sleep for 10 seconds
		Thread.sleep(10000);
		System.out.println("will take more than 10 seconds");
	}
	// 5 seconds max
	@Test(timeOut=5000)
	public void cherCherTechNoSleep() throws Exception
	{
		System.out.println("will be completed withing 5 seconds");
	}
}


timeout-in-testng

Timeout in testng.xml level :

You can set the timeout for the total suite in the testng.xml like below. time-out="500"

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">

<suite name="Suite" time-out="3000">
  <test thread-count="5" name="Test">
    <classes>
      <class name="test.TestJenkins"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
public class TestJenkins {
	@Test
	public void cherCherTech() throws InterruptedException
	{
		System.out.println("timeout exception");
		// sleep for 5 seconds but we have given 3 seconds of time-out
		Thread.sleep(5000);
	}
}


timeout-testng-xml

Expected Exceptions in TestNG

Sometimes we might have scenarios where we expect an exception as a result; In such cases, we have to verify that an exception is being thrown by the program during execution.

For Example, you have deleted a product from the list to verify whether the product is not there; you can try to find the product, but as the product is not there so it should throw a NoSuchElementException in selenium.

TestNG provides a way to handle such exceptions; we need to set the property of the expectedException to the required exception.

public class TestJenkins {
	@Test(expectedExceptions = ArithmeticException.class)
	public void cherCherTechThrowException()
	{
		throw new ArithmeticException("for demo purpose only");
	}

	@Test(expectedExceptions = ArithmeticException.class)
	public void cherCherTechDifferentException()
	{
		throw new ArrayIndexOutOfBoundsException("Throw different exception than expected one");
	}
	@Test(expectedExceptions = ArithmeticException.class)
	public void cherCherTechNoException()
	{
		System.out.println("this method don't throw any exception");
	}
}


expected-exceptions-testng

Handle Multiple Expected Exceptions :

We can write an array of exceptions when we are expecting anyone of given exceptions.

public class TestJenkins {
	@Test(expectedExceptions =
			{NoSuchElementException.class,
			ElementNotVisibleException.class})

	public void cherCherTechThrowException()
	{
		System.setProperty("webdriver.gecko.driver", "D:PATHgeckodriver.exe");
		WebDriver driver = new FirefoxDriver();
		driver.get("https://google.com");
		// name which has no match in google page
		driver.findElement(By.name("who-cares")).click();
	}
}


multiple-expected-exceptions-testng

expectedExceptionsMessageRegExp :

expectedExceptionsMessageRegExp helps user to can pass/fail the test case based on the exception message it throw.

We can use the regular expression to handle the exception message string; As I am not good with a regular expression I will try to use very basic one, do read more on the regular expression on your favorite web sites.

public class TestJenkins {
	@Test(expectedExceptions = NoSuchElementException.class,
		  expectedExceptionsMessageRegExp="karthiq")

	public void cherCherTechThrowException()
	{
		throw new NoSuchElementException("karthiq");
	}
}

Parameters in TestNG

One of the important features of TestNG is parameterization. This feature allows the user to pass parameter values to test methods as arguments. This is supported by using the @Parameters annotation.

If you need to pass simple values such as String types to the test methods at runtime, you can use this approach of sending parameter values through TestNG XML configuration files.

You have to use the Parameters annotation for passing parameter values to the test method.

@Parameters({ "parameter-name" })
The name values used in the testng.xml must match with a parameter used on @Parameters

Lets create a testng.xml which holds the test data and test suite.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite" time-out="3000">
  <test thread-count="5" name="Test">
  <parameter name="searchTerm" value="chercher tech" />
  <parameter name="url" value="https://google.com" />
    <classes>
      <class name="test.TestJenkins"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
public class TestJenkins {

	@Parameters({"searchTerm", "url"})
	@Test
	public void cherCherTech(String search_Term, String url_ofSearch_engine) throws InterruptedException
	{
		System.setProperty("webdriver.gecko.driver", "D:PATHchromedriver.exe");
		WebDriver driver = new FirefoxDriver();
		driver.get("https://google.com");
		driver.findElement(By.name("q")).sendKeys(search_Term);
	}
}

@Optional Parameter in TestNG

By now we know, we can pass parameter values to the test methods during run time from the testng.xml file by specifying @Parameters annotation to test method.

To receive the parameter in the test method, we need to declare parameters tag in the XML file using 'name' and 'value' attribute.

Where the name attribute of the tag defines the name of the parameter, and the value attribute defines the value of the parameter.

If a defined parameter is not found in your testng.xml file, The test method will receive the default value, which is specified inside the @Optional annotation.

<parameter name="param" value="Value of parameter" />
@Parameters("browser")
@Test
public void test(@Optional("Optional Value") String value)
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Sample Test Suite" verbose="1" >
  <parameter name="param1" value="First parameter" />
  <parameter name="param2" value="Second parameter" />
  <test name="Sample Test Cases" >
    <classes>
       <class name="Annotations.OptionalParamExample" />
    </classes>
  </test>
</suite>
public class OptionalParameterExample {
  @Parameters("parameter1")
  @Test
  public void testMethod(String a) {
    System.out.println("Value passed ::" + a);
  }
  @Parameters("parameter2")
  @Test
  public void testMethod2(@Optional("I am Optional value") String b) {
    System.out.println("Value passed ::" + b);
  }
  @Parameters("parameter3")
  @Test
  public void testMethod3(@Optional("I am Optional value") String c) {
    System.out.println("Value passed ::" + c);
  }
}
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions
  • swapnali
    @Parameters({"searchTerm", "url"})
    	@Test
    	public void cherCherTech(String search_Term, String url_ofSearch_engine) throws InterruptedException
    	{
    		System.setProperty("webdriver.gecko.driver", "D:\Eclipse progs\driverserver\chromedriver.exe");
    		WebDriver driver = new FirefoxDriver();
    		driver.get("https://google.com");
    		driver.findElement(By.name("q")).sendKeys(search_Term);
    	}
    }
    
    driver.get("https://google.com");
    should be driver.get(url_ofSearch_engine);
    
    Reply
  • poorna pragna
    Ultimate sir, it would have been still more ultimate if all these were in recorded session.
    However,  this blog is perfect for the new bee to selenium.
    
    Thanks,
    Poorna.
    Reply
  • Ram Bhai
    maintain the sequence of topic
    Reply
    • karthiQ [ admin]
      Hi Ram,
      
      thanks for highlighting the issue,we will correct it.
      Reply