2

I am trying to automate a Login and Logout Scenario in TestNG and passing the browser as parameter from XML on the basis of which chromedriver() instance will be created and the code will run.I have two classes TestRunner and Login where login method gets data (username and password) TestRunner and data is fetched from excel.Exception e is getting null value as I found out while debugging. Any way to fix it?

FAILED: Registration_data("[email protected]", "ashwin123") java.lang.NullPointerException at com.DataDriven.Login.login(Login.java:68) at com.DataDriven.TestRunner.Registration_data(TestRunner.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84) at org.testng.internal.Invoker.invokeMethod(Invoker.java:714) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:12) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) at org.testng.TestRunner.privateRun(TestRunner.java:767) at org.testng.TestRunner.run(TestRunner.java:617) at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at org.testng.SuiteRunner.run(SuiteRunner.java:240) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224) at org.testng.TestNG.runSuitesLocally(TestNG.java:1149) at org.testng.TestNG.run(TestNG.java:1057) at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204) 

 package com.DataDriven; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class TestRunner { @Test(dataProvider = "Authentication") public static void Registration_data(String sUserName, String sPassword) throws Exception { Login lp = new Login(); lp.login(sUserName, sPassword); } @DataProvider public Object[][] Authentication() throws Exception { Object[][] testObjArray = ReadData.getTableArray( "F:\\Automation\\DataDrivenPractice\\DataFiles\\DataFile.xlsx", "Sheet1"); return (testObjArray); } } 

 package com.DataDriven; import java.io.File; import org.apache.commons.io.FileUtils; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class Login { WebDriver driver = null; @Parameters("browser") @BeforeClass // Passing Browser parameter from TestNG xml public void beforeTest(String browser) { // If the browser is Firefox, then do this if (browser.equalsIgnoreCase("firefox")) { driver = new FirefoxDriver(); // If browser is IE, then do this } else if (browser.equalsIgnoreCase("chrome")) { // Here I am setting up the path for my IEDriver driver = new ChromeDriver(); } } public void login(String username, String password) { try { driver.get("https://www.facebook.com/"); driver.findElement(By.id("email")).sendKeys(username); driver.findElement(By.id("pass")).sendKeys(password); driver.findElement(By.id("loginbutton")).click(); driver.findElement(By.linkText("Log Out")).click(); } catch (Exception e) { File srcfile = ((TakesScreenshot) driver) .getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(srcfile, new File( "F:\\Automation\\Screenshots\\Login.jpg")); } catch (Exception e1) { e1.printStackTrace(); } } }} 

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite" parallel="none"> <test name="FirefoxTest"> <parameter name="browser" value="chrome" /> <classes> <class name="com.DataDriven.TestRunner" /> <class name="com.DataDriven.Login" /> </classes> </test> </suite> 
10
  • possible duplicate of What is a Null Pointer Exception, and how do I fix it?
    – Jens
    CommentedMar 15, 2015 at 19:25
  • I would recommend stepping through this with a debugger, to make sure that driver is being set to what you think it's being set to, and to find out exactly which value is unexpectedly null.CommentedMar 15, 2015 at 19:27
  • @DavidWallace Exception e is getting null value. Any idea how to fix it?CommentedMar 15, 2015 at 19:30
  • 1
    I've already told you what I recommend for you to do.CommentedMar 15, 2015 at 19:32
  • @DavidWallace Yes, I did debugging and it says Exception e is getting value as null.CommentedMar 15, 2015 at 19:36

2 Answers 2

1

There are many issues in your scripts

1 - Your classes init separately. The driver from @BeforeClass doesnot inherite into your @Test

2 - When you do

Login lp = new Login(); 

you have

WebDriver driver = null; @BeforeClass is not invoked, no driver init, your driver is still null 

Then

lp.login(sUserName, sPassword); 

NullPointException throws because driver in following line of code is null

driver.get("https://www.facebook.com/"); 

Suggest action

  • You need to get driver goes through all your classes

TestBase.class

Put your @BeforeClass here 

LoginPage.class, be sure you allow to cast driver into it

public LoginPage(WebDriver driver) { // your code here } // Put login(sUserName, sPassword) method here 

TestRunner.class

inherite/extends from TestBase.class LoginPage lp = new LoginPage(driver); lp.login(sUserName, sPassword); 
    0

    Your problem is - your method beforeTest doesn't invoke. Your driver doesn't point to any type of object.

    TestNG search through all your classes only for @Test annotation. How it's supposed to know that @BeforeClass annotation lies in specific class you've created?

    To run @BeforeClass annotation, you either have to set extends for Login class (it won't be effective for multiple scripts) or run beforeTest method manually. Or set it to running class containing @Test annotation.

    Correct me if i'm wrong. Hope it helps!

    EDIT:

    Move your method and WebDriver variable to Test Runner Class

     WebDriver driver = null; @Parameters("browser") @BeforeClass // Passing Browser parameter from TestNG xml public void beforeTest(String browser) { // If the browser is Firefox, then do this if (browser.equalsIgnoreCase("firefox")) { driver = new FirefoxDriver(); // If browser is IE, then do this } else if (browser.equalsIgnoreCase("chrome")) { // Here I am setting up the path for my IEDriver driver = new ChromeDriver(); } } 

    TestRunner class should contain both, @Test and @BeforeClass. As TestNG reads Annotations from classes containing @Test annotation.

    5
    • 1
      You're correct that beforeTest() isn't being called, but your reasoning isn't quite right. TestNG does searches classes for annotations, but only for @Test, all other TestNG annotations are inspected after the classes have been found. Your comment about "setting" extends doesn't make any sense; there's no need to extend anything.
      – dimo414
      CommentedMar 15, 2015 at 20:03
    • I would still work, tho! I used to create "Settings" class as a major settings for all @Tests and every @Test class extended Settings class. With this kind of solution, TestNG invokes @BeforeClass and @Test. It's kind of specific solution. I corrected my answer according to your comment. Thanks!
      – Fenio
      CommentedMar 15, 2015 at 20:09
    • Are you trying to suggest TestRunner extends Login?
      – dimo414
      CommentedMar 15, 2015 at 20:14
    • In this particullary scenario it won't be a good solution, but this is what i meant, answering this question. E.g.: Login extends BasicSettings or TestRunner extends Login
      – Fenio
      CommentedMar 15, 2015 at 20:16
    • I marked my login method as @Test and ran my class now my beforeTest method is getting invoked but now I am getting error as : org.testng.TestNGException: Method login requires 2 parameters but 0 were supplied in the Test annotation. ... Removed 23 stack frames Cant understand why values are not getting supplied, any idea why?CommentedMar 15, 2015 at 20:17

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.