I'm using selenium 3.8.1 and TestNG 6.9.2 version,while test execution before completing the #Test method another #Test method is starts,because of this i'm getting error in selenium script After completion of Test Cases execution.
One Class
public class LoginPage{
#Test(priority=0)
public void test1(){
System.out.println(first test);
}
#Test(priority=1)
public void test2(){
System.out.println(Second test);
}
}
Second Class
public class HomePage{
#Test(priority=0)
public void test3(){
System.out.println(first test);
}
#Test(priority=1)
public void test4(){
System.out.println(Second test);
}
}
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Test" preserve-order="true">
<classes>
<class name="com.tests.day.modules.LoginPage"/>
<class name="com.tests.day.modules.HomePage"/>
</classes>
</test>
</suite>
After Executing the above using testng.xml file before completing the test2 of login page class,test3 is starting of HomePage,because of this i'm getting exception,Unable to Find the Elements.
The Annotations mentions about the preserve-order attribute of TestNG as follows:
By default, TestNG will run your tests in the order they are found in
the XML file. If you want the classes and methods listed in this file
to be run in an unpredictable order, set the preserve-order attribute
to false
I executed the same test similar to your code block and testng.xml as follows :
LoginPage
package testng_order_of_tests_execution;
import org.testng.annotations.Test;
public class LoginPage
{
#Test(priority=0)
public void test1(){
System.out.println("First Test");
}
#Test(priority=1)
public void test2(){
System.out.println("Second Test");
}
}
HomePage
package testng_order_of_tests_execution;
import org.testng.annotations.Test;
public class HomePage
{
#Test(priority=0)
public void test3(){
System.out.println("first test");
}
#Test(priority=1)
public void test4(){
System.out.println("second test");
}
}
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Test" preserve-order="true">
<classes>
<class name="testng_order_of_tests_execution.LoginPage"/>
<class name="testng_order_of_tests_execution.HomePage"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
What I found as an output on my console was similar to yours as follows :
First Test
first test
Second Test
second test
This Console Output apparently gives us an impression that the sequence of execution was :
test1() -> test3() -> test2() -> test4()
But actually No
Looking at the Result of running suite you will get the actual sequence of execution as per the figure below :
So it's pretty clear that the actual sequence was :
test1() -> test2() -> test3() -> test4()
Trivia
You can be more granular in your observation with the testng-results.xml which is as follows :
<?xml version="1.0" encoding="UTF-8"?>
<testng-results skipped="0" failed="0" ignored="0" total="4" passed="4">
<reporter-output>
</reporter-output>
<suite name="Suite" duration-ms="61" started-at="2017-12-25T12:57:12Z" finished-at="2017-12-25T12:57:12Z">
<groups>
</groups>
<test name="Test" duration-ms="61" started-at="2017-12-25T12:57:12Z" finished-at="2017-12-25T12:57:12Z">
<class name="testng_order_of_tests_execution.HomePage">
<test-method status="PASS" signature="test3()[pri:0, instance:testng_order_of_tests_execution.HomePage#5419f379]" name="test3" duration-ms="4" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test3 -->
<test-method status="PASS" signature="test4()[pri:1, instance:testng_order_of_tests_execution.HomePage#5419f379]" name="test4" duration-ms="1" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test4 -->
</class> <!-- testng_order_of_tests_execution.HomePage -->
<class name="testng_order_of_tests_execution.LoginPage">
<test-method status="PASS" signature="test1()[pri:0, instance:testng_order_of_tests_execution.LoginPage#735b5592]" name="test1" duration-ms="14" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test1 -->
<test-method status="PASS" signature="test2()[pri:1, instance:testng_order_of_tests_execution.LoginPage#735b5592]" name="test2" duration-ms="2" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test2 -->
</class> <!-- testng_order_of_tests_execution.LoginPage -->
</test> <!-- Test -->
</suite> <!-- Suite -->
</testng-results>
In testng-results.xml you will observe that all the tests starts at 2017-12-25T12:57:12Z and ends at 2017-12-25T12:57:12Z. Though the time taken for Test Execution is even less then 1 second still you may observe the difference in the instancename as instance:testng_order_of_tests_execution.HomePage#5419f379 and instance:testng_order_of_tests_execution.LoginPage#735b5592. As our test was a single threaded test, hence we can conclude that the sequence of execution was proper and as per expectation. But the Console Output got mixed up.
Use group-by-instances="true" inside test tag of the testng.xml
Define your xml test tag like below:
<test name="Test" group-by-instances="true">
Or, you can also check below line of code:
<test name="Test" preserve-order="true" group-by-instances="true">
Related
I have several test classes sharing extending the BaseTest.class as following
class BaseTest{
#BeforeAll
static setup(){
// code to setup some configs for tests
}
}
AND
class TestClass1 extends BaseTest{
#Test
void test1(){
// test code
}
}
class TestClass2 extends BaseTest{
#Test
void test2(){
// test code
}
}
My need is to run these two tests in Parallel, but on different parameters passed to setup() method in BaseTest class, I found it easy in TestNg using testng.xml, but i need to use Junit5 to achieve this, Example from testng is
<suite name="Test-class Suite" parallel="classes" thread-count="2">
<test name="Test-class test 1">
<parameter name="paramName" value="paramValue1" />
<classes>
<class name="TestClass1" />
<class name="TestClass2" />
</classes>
</test>
<test name="Test-class test 2">
<parameter name="paramName" value="paramValue2" />
<classes>
<class name="TestClass1" />
<class name="TestClass2" />
</classes>
</test>
</suite>
I want your help to hear some suggestions/ideas how can i achieve this goal using Junit5, I appreciate all you inputs !
Thanks in advance
I am using Extent Report Version 4.0.9 to generate report for two of my tests. I am working on selenium, java, testng, cucumber, maven project. I have two TestRunner files in my cucumberOptions which I run one after the other using POM.xml.
When I run only one TestRunner, the Extent Report gets generated as expected. But when I run both TestRunners one after the other, the Extent Report which is generated by the second test overwrites the one generated by the first one.
How do I append the ExtentReport generated by the second test to that generated by the first test?
Here is my ExtentReporterListener code:
public class ExtentReporterListener {
private static Logger log = LogManager.getLogger(ExceptionHandler.class);
private static final String TEST_OUTPUT = TestConfiguration.USER_DIR + "\\test-output\\Screenshots";
public static ExtentHtmlReporter report = null;
public static ExtentReports extent = null;
public static ExtentTest feature = null;
public static ExtentTest scenario = null;
public static ExtentReports setUp() {
String reportLocation = "./Reports/Extent_Report.html";
report = new ExtentHtmlReporter(reportLocation);
report.config().setDocumentTitle("Word press Automation Test Report");
report.config().setReportName("Word Press Automation Test Report");
report.config().setTheme(Theme.STANDARD);
log.info("Extent Report location initialized...");
report.start();
extent = new ExtentReports();
extent.attachReporter(report);
extent.setSystemInfo("Application", "Word Press");
return extent;
}
}
This is my testng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name = "listener-class" />
</listeners>
<test thread-count="5" name="frontEnd">
<parameter name="URL" value="front-end-url" />
<classes>
<class name="frontendTestRunner"/>
</classes>
</test>
<test thread-count="5" name="Backend">
<parameter name="URL" value="back-end-url" />
<classes>
<class name="backendtestrunner"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
I am using Extent Report version 4. Somehow setAppendExisting(true); method which was in older version doesnot seem to exist in version 4.
After the below line of code please make the append existing as true.
report = new ExtentHtmlReporter(reportLocation);
report.setAppendExisting(true);
This will append the tests after execution.
I could solve the problem of ExtentReport getting overwritting when I changed my testng.xml like the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name = "listener-class" />
</listeners>
<test thread-count="5" name="frontEnd">
<classes>
<class name="frontendTestRunner">
<parameter name="URL" value="front-end-url" />
</class>
<class name="backendtestrunner">
<parameter name="URL" value="back-end-url" />
</class>
</classes>
</test>
</suite> <!-- Suite -->
i am using appium and selenium.
i am trying to rum it parallel (one case after another case)
my first case (forgot password is running properly ) and after that execution is just stop.
can anyone help me with this?
i have attached testng.xml , and testbase file. also login and forgot password scripts.
i guess there is some issues with annotations.
i have tried few but now working.
can anyone help me with this?
Thanks!!!
Here my code looks like:
1.testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test" parallel="classes">
<classes>
<class name="com.live.testcase.TC0001ForgotPassword" />
<class name="com.live.testcase.TC0002Login" />
<class name="com.live.testcase.TC0003Dashboard" />
<class name="com.live.testcase.TC0004Activity" />
<class name="com.live.testcase.TC0005MoveMoney" />
<class name="com.live.testcase.TC0006InternationalTransfer" />
<class name="com.live.testcase.TC0007Integration" />
<class name="com.live.testcase.TC0008Account" />
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
2. testbase.java
public class testBase {
private String reportDirectory = "reports";
private String reportFormat = "xml";
private String testName = "Untitled";
protected IOSDriver<IOSElement> driver = null;
#BeforeSuite
public void setup() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("reportDirectory", reportDirectory);
dc.setCapability("reportFormat", reportFormat);
dc.setCapability("testName", testName);
dc.setCapability(MobileCapabilityType.UDID, "afb65172e9b47b01482d912dede58515819748a3");
dc.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.novo.ios.dev");
driver = new IOSDriver<IOSElement>(new URL("http://localhost:4723/wd/hub"), dc);
driver.setLogLevel(Level.INFO);
}
#AfterSuite
public void teardown() {
}
}
3.Forgot password
public class TC0001ForgotPassword extends testBase {
#Test
public void ForgotPassword() throws InterruptedException {
// Test case for blank email address.
driver.findElement(By.xpath("//*[#text='Forgot Password?']")).click();
driver.findElement(By.xpath("//*[#placeholder='Email']")).sendKeys("Automationtesting#banknovo.com");
driver.findElement(By.xpath("//*[#text='Done']")).click();
Thread.sleep(1000);
driver.findElement(By.xpath("//*[#text='CONFIRM']")).click();
Thread.sleep(5000);
driver.findElement(By.xpath("//*[#text='(MM/DD/YYYY)']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='Done']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='CONFIRM']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='1']")).click();
driver.findElement(By.xpath("//*[#text='2']")).click();
driver.findElement(By.xpath("//*[#text='3']")).click();
driver.findElement(By.xpath("//*[#text='4']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='CONFIRM']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='CONFIRM']")).sendKeys("111111");
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='CONFIRM']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#placeholder='Password']")).sendKeys("Novo#2019");
driver.findElement(By.xpath("//*[#placeholder='Confirm Password']")).sendKeys("Novo#2019");
Thread.sleep(2000);
driver.findElement(
By.xpath("(//*[#class='UIAView' and ./parent::*[#class='UIAScrollView']]/*[#text='icEyeOpen'])[1]"))
.click();
driver.findElement(By.xpath("//*[#text='icEyeOpen']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='RESET PASSWORD']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#text='DONE']")).click();
}
4. Login
package com.live.testcase;
import org.testng.annotations.Test;
import org.openqa.selenium.By;
import com.live.common.testBase;
public class TC0002Login extends testBase {
#Test
public void TC000001_Blank_Email_Password() {
// Test case for blank email address.
driver.findElement(By.xpath("//*[#text='LOG IN']")).click();
driver.findElement(By.xpath("//*[#text='OK']")).click();
}
#Test
public void TC000002_Invailid_Email() throws Exception {
// Test case for invalid email addresses
driver.findElement(By.xpath("//*[#placeholder='Email']")).sendKeys("automationtesting");
driver.findElement(By.xpath("//*[#placeholder='Password']")).sendKeys("Novo");
driver.findElement(By.xpath("//*[#text='LOG IN']")).click();
driver.findElement(By.xpath("//*[#text='OK']")).click();
}
#Test
public void TC000003_Invailid_Password() throws Exception {
// Test case for invalid email addresses
driver.findElement(By.xpath("//*[#placeholder='Email']")).clear();
driver.findElement(By.xpath("//*[#placeholder='Password']")).clear();
driver.findElement(By.xpath("//*[#placeholder='Password']")).sendKeys("Novo#2019");
driver.findElement(By.xpath("//*[#text='LOG IN']")).click();
driver.findElement(By.xpath("//*[#text='OK']")).click();
}
#Test
public void TC000004_Valid_Email_Password() throws Exception {
// Test case for Valid email addresses & password
driver.findElement(By.xpath("//*[#placeholder='Email']")).sendKeys("automationtesting#banknovo.com");
driver.findElement(By.xpath("//*[#placeholder='Password']")).sendKeys("Novo#2019");
driver.findElement(By.xpath("//*[#text='LOG IN']")).click();
}
}
5. pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.novo.app</groupId>
<artifactId>com.novo.app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
</dependency>
</dependencies>
</project>
I assume this could be the issue:
You instruct testng to run parallel at suite tag not at test tag.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" thread-count="5" parallel="classes">
<test name="Test">
<classes>
<class name="com.live.testcase.TC0001ForgotPassword" />
<class name="com.live.testcase.TC0002Login" />
<class name="com.live.testcase.TC0003Dashboard" />
<class name="com.live.testcase.TC0004Activity" />
<class name="com.live.testcase.TC0005MoveMoney" />
<class name="com.live.testcase.TC0006InternationalTransfer" />
<class name="com.live.testcase.TC0007Integration" />
<class name="com.live.testcase.TC0008Account" />
</classes>
</test> <!-- Test -->
As per Parallelism and time-outs chapter:
The parallel attribute on the <suite> tag can take one of following values:
<suite name="My suite" parallel="methods" thread-count="5">
<suite name="My suite" parallel="tests" thread-count="5">
<suite name="My suite" parallel="classes" thread-count="5">
<suite name="My suite" parallel="instances" thread-count="5">
So my expectation is that you need to amend your testng.xml to look like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" configfailurepolicy="continue" verbose="2">
<test name="TC0001ForgotPassword">
<classes>
<class name="com.live.testcase.TC0001ForgotPassword"/>
</classes>
</test>
<test name="TC0002Login">
<classes>
<class name="com.live.testcase.TC0002Login"/>
</classes>
</test>
<test name="TC0003Dashboard">
<classes>
<class name="com.live.testcase.TC0003Dashboard"/>
</classes>
</test>
<test name="TC0004Activity">
<classes>
<class name="com.live.testcase.TC0004Activity"/>
</classes>
</test>
<test name="TC0005MoveMoney">
<classes>
<class name="com.live.testcase.TC0005MoveMoney"/>
</classes>
</test>
<test name="TC0006InternationalTransfer">
<classes>
<class name="com.live.testcase.TC0006InternationalTransfer"/>
</classes>
</test>
<test name="TC0007Integration">
<classes>
<class name="com.live.testcase.TC0007Integration"/>
</classes>
</test>
<test name="TC0008Account">
<classes>
<class name="com.live.testcase.TC0008Account"/>
</classes>
</test>
</suite>
More information including sample project: Parallel Tests Execution
I am not able to invoke the browsers in parallel, which are currently invoking one after another. Need a way to invoke the browsers in parallel tests.
NOTE: In my configuration xml file I have kept the thread count as 2.
Below is my configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "testng.org/testng-1.0.dtd"; >
<suite name="Parallel" parallel="tests" thread-count="4" >
<test verbose="3" name="<name>">
<parameter name="platform" value ="win8"/>
<parameter name="browsername" value ="internet explorer"/>
<classes>
<class name="com.parallel.execution.ParallelExecution">
<methods>
<include name="testmethod1"/>
</methods>
</class>
</classes>
</test>
</suite>
We have to define two attributes 'parallel' and 'thread-count' in simple testng.xml file. See below:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel Execution suite" parallel="methods" thread-count="2">
<test name="Regression 2">
<classes>
<class name="com.parallel.TestParallelExecution"/>
</classes>
</test>
</suite>
In above, as we want the test methods to be executed parallel, we have set the parallel attribute as 'methods' and thread-count attribute will control the max number of threads to be created.
Re-installing TestNG solved the above problem.
You have to explicitly write code to invoke the browser as part of a #Before configuration to invoke the browser every time a #Test is run . I will specify one of the many approaches so that you get an idea.
<suite name="Parallel" parallel="tests" thread-count="4" >
<test verbose="3" name="test1">
<classes>
<class name="com.parallel.execution.ParallelExecution1"/>
</classes>
</test>
<test verbose="3" name="test2">
<classes>
<class name="com.parallel.execution.ParallelExecution2"/>
</classes>
</test>
</suite>
Consider a suite file with 2 tests set to run in parallel. What we expect is #Test methods in ParallelExecution1 runs in first browser and #Test methods in ParallelExecution2 runs in second browser. So you need a mechanism by which you can invoke browser sessions and run your test methods. Enter BaseTest class.
public abstract class BaseTest {
protected WebDriver driver;
#BeforeTest
#Parameters({"browser"})
public void init(String browser) {
// Initialize your browser here. Code below is dummy
driver = new FF();
}
#AfterTest
public void end() {
driver.close();
driver.quit();
}
}
Now inherit this 'BaseTest' in both your test classes.
public class ParallelExecution1 extends BaseTest {
#Test
public void test1() {
}
}
public class ParallelExecution2 extends BaseTest {
#Test
public void test2() {
}
}
Now both the tests have #BeforeTest and #AfterTest methods which will invoke the browsers.
I am having trouble reading parameter values from testng.xml inside a testng testcase in Eclipse IDE. I have browser initiated from BeforeClass and at #TEST method ,parameter values are coming as "NULL"...and it asks me to define my #Test parameters as Optional..
MyJavacode
public class headerValidation extends init {
WebDriver driver;
#BeforeClass
public void beforeClass() {
driver = initBrowser(BrowserType.FIREFOX, "http://www.abc123.com/");
}
#Test
#Parameters(value = { "loginID", "PasswordKey", "testURL" } )
public void testLogin(String loginID, String PasswordKey, String testURL) throws Exception {
try {
driver.get(testURL);
driver.findElement(By.id("login-b")).click();
driver.findElement(By.id("login_e")).sendKeys(loginID);
driver.findElement(By.id("login_p")).sendKeys(PasswordKey);
driver.findElement(By.name("submit")).click();
}//try
catch (Exception e) {
e.printStackTrace();
}//catch
My Testng XML file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="none">
<test name="Test">
<parameter name="loginID" value="emailadd#add2.com"></parameter>
<parameter name="PasswordKey" value="21232131"></parameter>
<parameter name="testURL" value="www.abctest.com"></parameter>
<classes>
<class name="org.pa.qa.headerValidation"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Am i missing something here?
If you right click on the file and run as testng test, the testng xml is not picked up by default, which explains why the parameters are not being picked up.
Two solutions :
Right click on the suite xml and trigger with Run as ->testng suite
OR
Go to Project->Properties->Testng-> Set this xml as your template xml and then you can run as testng test