I set up a project using Intellij on Linux using Selenium and Testng using the factory method with dataProviders. On Linux the process runs as the following:
**Data 1:**
initialize
second
AfterTest
**Data 2**
initialize
second
AfterTest
But when I transferred the project onto a Windows machine, installed all of the libraries (still using intellij) I get the following output:
Initialize
Initialize(1)
second
second (1)
AfterTest
I'm not too sure why I'm getting differences since it's the same code. Please see the code below:
#DataProvider(name = "data")
public static Object[][] data() {
// This is where I get the data from
}
#Factory(dataProvider = "data")
public TestSuite1(Data data)
{
super();
this.data = data;
}
#Test(priority = 1, description = "First test")
public void initialize()
{
System.out.println("DO THIS FIRST");
}
#Test(priority = 2, description = "Do this after")
public void second()
{
System.out.println("DO THIS AFTER");
}
#AfterClass
public void AfterTest() throws InterruptedException
{
System.out.println("I HAVE FINISHED THE TEST");
}
I see here :https://howtodoinjava.com/testng/testng-factory-annotation-tutorial/ That "#Factory" must be used with "#DataProvider" to test ...
I didn't see "#DataProvider" in your code ... and it seem to not use a correct form of code for TestNG...
That could be why there is a difference ...
You have to check your testNg xml file as well. since I cannot see your any test steps use data from data provider. Your second script is similar to parallel test execution. please make sure your suite details like below.
<suite name="Suite" parallel="false" thread-count="0" verbose="2">
<test name="TestName"> <!--Do not add any other unless its necessary-->
<classes>
<class name="className"/>
</classes>
</test>
Related
I am trying to run a dataprovider based test using ANT. My main class points to testNG file
XmlSuite suite=new XmlSuite();
suite.setName("Test Results");
suite.setPreserveOrder(true);
List<XmlSuite> suits=new ArrayList<XmlSuite>();
suits.add(suite);
List<XmlPackage> xpackage=new ArrayList<XmlPackage>();
xpackage.add(new XmlPackage(TestProperties.TESTNG_PACKAGE.toString()));
XmlTest test=new XmlTest(suite);
test.setPackages(xpackage);
String groups=TestProperties.TESTNG_GROUP.toString();
System.out.println("groups are:"+groups);
String groupArray[]=groups.split(",");
List<String> includedGroups=new ArrayList<String>();
includedGroups.addAll(Arrays.asList(groupArray));
test.setIncludedGroups(includedGroups);
TestNG tng=new TestNG();
tng.setOutputDirectory("test-output");
tng.setXmlSuites(suits);
tng.run();
System.exit(0);
Now, in my Testcase file, I have
#BeforeClass(alwaysRun = true)
public void pretest() throws IOException, GeneralSecurityException {
Pretest
}
#Test(groups= {"indicatorGroup","",""},description = "Validate indicator uploaded", dataProvider = "getIndicatorData")
public void indicatorUpload(String txt){
test
}
#DataProvider
public Object[] getIndicatorData() throws IOException, GeneralSecurityException
{
bla bla
for(int i=0; i<contents.length; i++) {
System.out.println(contents[i]);
if(!contents[i].contains("README")) {
blah blah
System.out.println(path);
names.add(path);
}
}
String[] myArray = new String[names.size()];
names.toArray(myArray);
return myArray;
}
#AfterClass(alwaysRun = true)
public void afterMethod() throws IOException {
System.out.println("Deleting all files after operation.....");
}
The problem is, they run without any issues, if i run from Testng. ie if i right click on the file, click on run, click on Run as Testng Test.
But if I run from my build file, after the first iteration, the driver I bring up in before class, closes and the rest of the tests fail. This causes my tests to fail in jenkins.
Can someone please help me out?
After many trials, I found out that the testng xml created By my trigger file had
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="IndicatorSuite" data-provider-thread-count="1">
<test name="Test Basics 1">
<groups>
<run>
<include name="indicatorUpload" />
</run>
</groups>
<classes>
<class name="Uploads.IndicatorFileUpload">
<class name="Uploads.IndicatorFileUpload1">
<class name="Uploads.IndicatorFileUpload2">
</methods>
</class>
</classes>
</test>
</suite>
Even though my test group was correct, I had given test package, because of which all my testcase files had been added as classes. All of these had a listener which would close the driver after testrun. I dont know much about testng, but I think it mixed up the listeners. In my Trigger file, when I added just
TestNG tng=new TestNG();
tng.setOutputDirectory("test-output");
//tng.setXmlSuites(suits);
tng.setTestClasses(new Class[] { IndicatorFileUpload.class });
tng.run();
it worked!
I have a java class that opens up two Chrome browsers, searches for "test 1" and "test 2", respectively. However, once both browsers open, only one browser with the google page will search for "test 1 test 2".
I believe this issue may be because I am calling the driver = new WebDriver from a parent class. However, I am not sure how to resolve the issue.
Here are my two methods that I am trying to run in parallel.
package webDrivertests;
public class googleTestClass extends Methods{
#Test
public void test1() throws InterruptedException {
googleTestClass object1;
object1 = new googleTestClass();
object1.launchBrowser();
object1.goToURL("https://www.google.com");
object1.enterValue("name","q","google test 1");
driver.quit();
}
#Test
public void test2() throws InterruptedException {
googleTestClass object2;
object2 = new googleTestClass();
object2.launchBrowser();
object2.goToURL("https://www.google.com");
object2.enterValue("name","q","google test 2");
driver.quit();
}
}
This is my xml file I use to call them.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="methods">
<test thread-count="2" name="Test" parallel="methods">
<classes>
<class name="webDrivertests.googleTestClass"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
The parent method that includes the driver
package webDrivertests;
// import statements
public class Methods {
public static WebDriver driver;
public void launchBrowser() {
System.setProperty("webdriver.chrome.driver","C:\\chromedriver_win32\\chromedriver.exe");
System.setProperty("webdriver.chrome.args", "--disable-logging");
System.setProperty("webdriver.chrome.silentOutput", "true");
driver = new ChromeDriver();
}
public void goToURL(String url) {
driver.get(url);
}
public void enterValue(String htmltype, String identifier, String value) throws InterruptedException {
if (htmltype == "id") {
WebElement element = driver.findElement(By.id(identifier));
element.clear();
element.sendKeys(value);
element.submit();
}
if (htmltype =="name") {
WebElement element = driver.findElement(By.name(identifier));
element.clear();
element.sendKeys(value);
element.submit();
}
Thread.sleep(3000);
}
}
Current Result: Two browsers are opened and each go to google.com. However only one browser will search for "test 1 test 2". Any help is appreciated! If possible, I would still like to use my parent class "Methods" as it contains a lot of methods I am using for my other real test cases.
Thanks in advance.
The problem lies in your test code. WebDriver object is being declared as a static object.
So this causes every test method to share the same instance.
To fix the problem remove the static keyword from the WebDriver declaration in your Methods class and try again.
Because of static declaration of the driver object in the class, it get's overridden parallel execution when second test called launchBrowser().
Obviously removing static will fix this issue but still you will fall in different issues of managing driver while your test bed and methods increase.
I would recommend to use any of TestNG extension that takes care of such requirement. We are using QAF which is built upon TestNG and provides driver management, resource management and many more features which are crucial for web/mobile/webservices testing.
I'm trying to automate a website testing using testNG.
Let assume I have created 3 test cases one for each webpage(although there are more than 50 test cases in my case but just for simplifying the issue I have considered 3 only).
Now, my starting 2 test cases are passing but my 3rd test case is getting failed. I am making the code change to that 3rd page and I want just to run that 3rd test case but when I am running my code, everytime new IE driver instance is getting created and testing starts from beginning.
How to use existing driver instance and test the 3rd webpage only. I tried googling this out but couldn't find anything useful.
Any help would be appreciated.
If you want to ignore particular test, you can use this snippet:
import org.testng.Assert;
import org.testng.annotations.Test;
public class IgnoreTest {
#Test(enabled = false) // this test will be ignored
public void testPrintMessage() {
System.out.println("This test is ignored");
}
#Test
public void testSalutationMessage() { // this will be executed
System.out.println("Test works");
}
}
When you execute this class, it will be only second test executed. I don't know if you have stored all 50 tests in one class(hopefully not), but if yes, there is a possibility to group your tests. To be able to do this you can use this sample:
import org.testng.Assert;
import org.testng.annotations.Test;
public class GroupTestExample {
#Test(groups = { "functest", "checkintest" })
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
}
#Test(groups = { "checkintest" })
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
}
#Test(groups = { "functest" })
public void testingExitMessage() {
System.out.println("Inside testExitMessage()");
}
}
then xml file would be like this:
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name = "Suite1">
<test name = "test1">
<groups>
<run>
<include name = "functest" />
</run>
</groups>
<classes>
<class name = "GroupTestExample" />
</classes>
</test>
</suite>
then after compiling your test classes, use this command:
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
More explained information you will get in this tutorials:
ignore tests
group tests
I have test automation framework with a page object model.
All my test are located in separate classes in same package.
In testng.xml i have
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Smoke Test">
<test name="SmokeTest">
<classes>
<class name="name.test1"/>
<class name="name.test2"/>
<class name="name.test3"/>
</classes>
</test>
</suite>
Problem is that after running TestNG.xml if the 1st test will fail, it will stop test execution. But i want to continue executing of all test cases.
I use Jenkins on my project and if one of the tests are failed it stops execution immediately.
Example of test
public class LoginTestTest {
public AndroidDriver<AndroidElement> driver;
public AOWebClient aoWebClient;
AOWebClient aoWeb;
public LoginTestTest(AndroidDriver<AndroidElement> driver, AOWebClient aoWeb){
this.driver = driver;
this.aoWeb = aoWeb;
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}
public LoginTestTest() {
}
SoftAssert softAssert = new SoftAssert();
#BeforeClass
public void setUp() throws Exception {
driver = DesiredCapabilitiesSetup.startAppiumServer();
aoWebClient = DesiredCapabilitiesSetup.getAOWeb();
LogIn logIn = new LogIn(driver,aoWebClient);
logIn.logIn();
}
#org.testng.annotations.Test
public void goToSettings() throws InterruptedException {
HeaderMenu header = new HeaderMenu(driver,aoWeb);
HamburgerMenuList ham = new HamburgerMenuList(driver);
header.clickHamburgerButton();
header.clickHamburgerButton();
header.editButtonClick();
softAssert.assertAll();
}
#AfterClass
public void tearDown(ITestResult result) throws Exception {
if (result.getStatus() == ITestResult.FAILURE) {
TakeScreenshot screenshot = new TakeScreenshot();
screenshot.TakeScreenshot("screenshots/");
}
LogOut logOut = new LogOut(driver,aoWeb);
logOut.logOut();
}
}
If my test will fail in #Test it will never continue to #AfterClass method.
And I want that if #Test fail it will continue to #AfterClass method and After This Class continue executes test from other classes from testng.xml.
Your suite tag in your xml should include configfailurepolicy="continue". This tells testng that even though a config failed in one class, you still want to run other classes in that suite. See "configfailurepolicy" in the documentation.
So your xml would become:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Smoke Test" configfailurepolicy="continue">
<test name="SmokeTest">
<classes>
<class name="name.test1"/>
<class name="name.test2"/>
<class name="name.test3"/>
</classes>
</test>
</suite>
From the documentation:
alwaysRun: For after methods (afterSuite, afterClass, ...): If set to
true, this configuration method will be run even if one or more
methods invoked previously failed or was skipped.
Then, just replace your #AfterClass by #AfterClass(alwaysRun = true).
Add below attribute in testng.xml file under Suite syntax
<suite thread-count="25" name="Smoke" parallel="classes" skipfailedinvocationcounts="true">
Work for me, hope it will work for you as well :)
Given the following codes:
public class NewTest {
private Object _foreground = null;
#BeforeGroups("regression")
public void setUp() {
System.out.println("executed? setUp");
_foreground = new MyObject();
}
#Test(groups="regression")
public void testMyObjectToString() throws Exception {
System.out.println("??? ");
System.out.println(_foreground == null);
String value = _foreground.toString();
Assert.assertTrue(value != null);
}
}
And the testNG.xml:
<groups>
<run>
<include name="regression" />
</run>
</groups>
<classes>
<class name="com.automation.test.NewTest"/>
</classes>
When I tried to run this, the print statements say:
???
true
So that means _foreground is null, meaning the setUp method is not executed.
TestNG also shows java.lang.NullPointerException on the line:
String value = _foreground.toString();
However I have no idea what I missed. Looks to me the "regression" group will be run and the setUp method with #beforeGroup will be run before testMyObjectToString with #Test. Apparently this is not what is happening..
It is a very stupid mistake that maybe someone new to testNG may make...
#BeforeGroups("regression")
This is a wrong usage.. The correct usage should be:
#BeforeGroups(groups = "regression")
Took me two days!!