3

I am having trouble with starting a new package using TestNg. Note I have simplified the code to try to figure out where I was going wrong. At @Test(priority=3) I am having the issue. It is not allowing me to click on a button.

I have checked the compiler and running 1.8 which is fine.

I checked my previous project which is running just fine but could not see any differences. Also I have my dependencies which are maven, selenium, testng which looks good. I imported the library which is good.

The kicker is that TestNg worked Great in my past Project maybe one month ago on the same computer and everything.

package com.Prod.dtx_project;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;


public class DIF1v2 {

protected WebDriver driver;

@Test(priority=1)
public void initialization()
{
    // To set the path of the Chrome driver.
    System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Eclipes\\ChromeDriver\\chromedriver.exe");
}

@Test(priority=2)
public void OpenBrowserChrome ()
{
    // Create a new instance of the Chrome driver
    WebDriver driver = new ChromeDriver();
    //WebDriver driver = new InternetExplorerDriver();
    driver.get("https://testng.org/doc/index.html");
        // To maximize the browser
    driver.manage().window().maximize();
        // implicit wait
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        // Print a Log In message to the screen
    System.out.println("Successfully opened the website ");

    driver.findElement(By.xpath("//*[@id='topmenu']/table/tbody/tr[2]/td[1]/a")).click();

}

@Test(priority=3)    //IT FAILED HERE WHEN USING A NEW ANNOTATION// 
public void Issue ()
{
driver.findElement(By.xpath("/html/body/a[13]")).click();

}

@Test(priority=4)
public void LandingPage ()
{
    System.out.println("LandingPage-4");

}

@Test(priority=5)
private void publ() 
{
    System.out.println("publ-5");
}



}

Here is my testng.xml:

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

<suite name="Suite">

  <test name="Regression Testing">
    <classes>
      <class name="com.Prod.dtx_project.DIF1v2"/>
    </classes>
  </test>   

</suite> 

Also, here is the error message that I am receiving in the Console -

FAILED: Issue
java.lang.NullPointerException
at com.Prod.dtx_project.DIF1v2.Issue(DIF1v2.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod 
(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods 
(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run     
(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
===============================================
Default test
Tests run: 5, Failures: 1, Skips: 0
===============================================

I expected that it would open to url and click on the eclipse button on this page however it does not.

PLEASE NOTE: When I move the driver.get and driver.findElement inside the @Test(priority=2), Then IT WORKS. Please see below. HOWEVER How can I Run my TestNG with a this layout. Why does this work but when using more then one @Test annotation it Fails.

@Test(priority=2)
 public void OpenBrowserChrome ()
 {
        // Create a new instance of the Chrome driver
    WebDriver driver = new ChromeDriver();
        //WebDriver driver = new InternetExplorerDriver();
    driver.get("https://testng.org/doc/index.html");
        // To maximize the browser
    driver.manage().window().maximize();
        // implicit wait
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        // Print a Log In message to the screen
    System.out.println("Successfully opened the website ");


    driver.get("https://testng.org/doc/index.html");
    driver.findElement(By.xpath("//*[@id='topmenu']/table/tbody/tr[2]/td[1]/a")).click();



}
fari
  • 31
  • 5

3 Answers3

0

Its giving nullpointer at driver.get statement as you have not initialised the driver in priority=3 test.
The scope of every test is different so you need to initialise it in every test you want to use it.

In priority=2, you have initialised it using driver = new ChromeDriver();, so similarly you need to initialise it in the priority=3 test and then you need to execute driver.get(url) and it would work.

Your test 2 and test 3 should be like:

@Test(priority=2)
public void OpenBrowserChrome()
{
    WebDriver driver = new ChromeDriver();
    driver.get("https://testng.org/doc/index.html");
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    System.out.println("Successfully opened the website ");
    driver.findElement(By.xpath("//[@id='topmenu']/table/tbody/tr[2]/td[1]/a")).click();
    driver.quit();

}

@Test(priority=3)
public void Issue() throws InterruptedException
{
    WebDriver driver = new ChromeDriver();
    driver.get("https://testng.org/doc/index.html");
    driver.findElement(By.xpath("//[@id='topmenu']/table/tbody/tr[2]/td[1]/a")).click();
    Thread.sleep(5000);
    driver.findElement(By.xpath("/html/body/a[13]")).click();
    driver.quit();

}

If you want to click on two elements in continuation like in the test3, you need to make a separate instance of the driver other than that of test2 and then again hit the url and then you need to click on the elements. In the above scenario, you can remove the test2 because it is not actually solving any purpose for you currently and you can perform both the operations in the test3.

Sameer Arora
  • 4,439
  • 3
  • 10
  • 20
  • Hello Sameer, I set the following below and it still is Failed at @Test(priory=3) – fari Feb 08 '19 at 12:47
  • @Test(priority=2) public void OpenBrowserChrome (){ WebDriver driver = new ChromeDriver(); driver.get("https://testng.org/doc/index.html"); driver.findElement(By.xpath("//*[@id='topmenu']/table/tbody/tr[2]/td[1]/a")).click(); } @Test(priority=3) public void Issue (){ driver.findElement(By.xpath("/html/body/a[13]")).click(); } – fari Feb 08 '19 at 12:48
  • In the @Test(priority=3), please add a line of code `WebDriver driver = new ChromeDriver();` before `driver.findElement(By.xpath("/html/body/a[13]")).click();` and it would work. – Sameer Arora Feb 08 '19 at 12:50
  • Iv noticed that if all the steps were under 1 @ Test, then it works. But continuing to say @ Test p3, and making it start from an open browser already to find an element will not work. – fari Feb 08 '19 at 12:50
  • I have updated my answer, please check that. And your test2 and 3 are different, their scope are different, so you need to again initialise the driver and then again hit the url and then operate on the element. I have also added `driver.quit();` at the end of the tests so that the previous browser gets closed after its execution. Please check the updated answer and try that. – Sameer Arora Feb 08 '19 at 12:58
  • Have edited my answer, please check now. If you want few things to run in continuation, you need to do those things under one test only as every test need their driver separately. – Sameer Arora Feb 08 '19 at 13:05
  • Hello Sameer, Yes your code works. Thank you very much. But I thought for using TestNG that I could use it for Data Driven testing to recall a method over using a @ Test method from e.g. a login passwords. The way above is showing up down the line to have to many test scripts and steps in each @ Test annotation. – fari Feb 08 '19 at 13:50
  • My goal was to do the following within 1 Class file: @ Test p1 //initiate driver @ Test p2 //enter form values @ Test p3 //login @ Test p4 //complete form as different profile – fari Feb 08 '19 at 13:50
  • I got your point but in test class, one test depicts one flow and the things you are doing comes under one flow so you need to do all those in one test. If you have other flow then you should make other test. And please upvote and accept the answer if its helps :) – Sameer Arora Feb 08 '19 at 13:57
  • And one more suggestion, you can use @BeforeTest and in that you can initialise the webdriver and open the url. Beforetest runs before every test so you dont need to do the initialise the driver everytime under your test. – Sameer Arora Feb 08 '19 at 13:59
  • I first ended up using @Before Suite for System.setProperty and @ BeforeTest to initiate the Browser. Then used @ Test for the test steps and always when using the second @ Test it failed. So I ended up slowly deleting each step one by one to diagnose the problem. I ended up with the above org script and could not figure it out. – fari Feb 08 '19 at 14:07
  • Yes because when you are using beforesuite or beforetest, you initialise the driver there and after that you need to pass that driver to the test class else it would also fail like its failing right now. My suggestion would be that you should start with the basics and do one flow in one test and then you should start using beforesuite or beforetest afterwards when your basics are clear. – Sameer Arora Feb 08 '19 at 14:31
  • And please upvote and accept the answer if it helps you :) – Sameer Arora Feb 08 '19 at 14:52
  • Hello Sameer, so, just to clarify, when running a class file, the acceptable annotation would be to use only 1 time @Test + any before/after ect. to run a test case? and using it more then once will mess up TestNG. thank you for the clarification. – fari Feb 08 '19 at 16:03
  • Also, I did do the upvote and received the following message. :) "Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score. – fari Feb 08 '19 at 16:04
  • There can be n number of tests, you should write test for every flow you want to test but there can be only one beforesuite, one beforetest, one beforemethod and same for aftersuite aftertest and aftermethod. – Sameer Arora Feb 08 '19 at 16:06
  • And if you are using beforetest or suite then you need to pass the driver to the test from the beforetest to use it. And if you are using only tests then you need to initialise driver everytime and you should make one test for one flow and you can make any number of test in your class. – Sameer Arora Feb 08 '19 at 16:09
  • You should refer to this link, its very helpful !! https://www.guru99.com/all-about-testng-and-selenium.html – Sameer Arora Feb 08 '19 at 16:15
  • And you can mark the answer as accepted by clicking on the tick mark, please do if it helped you :) – Sameer Arora Feb 08 '19 at 16:16
0

adding a @BeforeClass for systems.setProperty ended up working.

fari
  • 31
  • 5
0

In @Test(priority=2), remove "WebDriver" then everything will work fine. I tested.

Under "public class DIF1v2", you had "protected WebDriver driver". This means "driver" is an instance variable (variable defined in a class) - variable declared under class, outside of every methods. In this case, "driver" has default value of null.

But in @Test(priority=2), there is "WebDriver driver = new ChromeDriver();". You declare "driver" as "WebDriver". This is another "driver". This "driver" is local variable. This "driver" belongs to only @Test(priority=2). Its value affects only inside @Test(priority=2).

The error "java.lang.NullPointerException" in @Test(priority=3) is caused by driver = null. You are invoking method findElement of null.

For the value remains from method to method, a variable needs to be instance variable. Let's see a test. I added a string variable "test".


import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;


public class DIF1v2 {

protected WebDriver driver;
protected String test = "123"; //// THIS INSTANCE VARIABLE IS FOR TESTING.
@Test(priority=1)
public void initialization()
{
    // To set the path of the Chrome driver.
    System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Eclipes\\ChromeDriver\\chromedriver.exe");
}

@Test(priority=2)
public void OpenBrowserChrome ()
{
    String test = "456";       //// THIS IS ANOTHER "test". JUST THE SAME NAME.
    // Create a new instance of the Chrome driver
    driver = new ChromeDriver();
    //WebDriver driver = new InternetExplorerDriver();
    driver.get("https://testng.org/doc/index.html");
        // To maximize the browser
    driver.manage().window().maximize();
        // implicit wait
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        // Print a Log In message to the screen
    System.out.println("Successfully opened the website ");

    driver.findElement(By.xpath("//*[@id='topmenu']/table/tbody/tr[2]/td[1]/a")).click();

}

@Test(priority=3)    //IT FAILED HERE WHEN USING A NEW ANNOTATION// 
public void Issue ()
{
    System.out.println(test);  //// THIS WILL PRINT "123"
    driver.findElement(By.xpath("/html/body/a[13]")).click();

}

@Test(priority=4)
public void LandingPage ()
{
    System.out.println("LandingPage-4");

}

@Test(priority=5)
private void publ() 
{
    System.out.println("publ-5");
}



}

OUTPUT:

123
LandingPage-4
publ-5
PASSED: initialization
PASSED: OpenBrowserChrome
PASSED: Issue
PASSED: LandingPage
PASSED: publ

I initialized instance variable:

protected String test = "123";

In @Test(priority=2), I initialized another variable with the same name:

String test = "456";

Then, in @Test(priority=3), I have:

System.out.println(test);

The printed result is:

123

hthhth
  • 111
  • 1
  • 5