【问题标题】:Null Pointer Exception while running code using TestNG使用 TestNG 运行代码时出现空指针异常
【发布时间】:2015-03-15 19:20:56
【问题描述】:

我正在尝试在 TestNG 中自动化登录和注销场景,并根据将创建 chromedriver() 实例和运行代码的基础从 XML 传递浏览器作为参数。我有两个类 TestRunner 和 Login,其中登录方法获取数据(用户名和密码)TestRunner 并从 excel 中获取数据。我在调试时发现异常 e 正在获取空值。有什么办法解决吗?

FAILED: Registration_data("ashwin@gmail.com", "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>

【问题讨论】:

  • 我建议使用调试器逐步执行此操作,以确保将 driver 设置为您认为的设置,并准确找出哪个值意外为空。跨度>
  • @DavidWallace 异常 e 正在获取空值。知道如何解决吗?
  • 我已经告诉过你我建议你做什么。
  • @DavidWallace 是的,我进行了调试,它说异常 e 的值为 null。

标签: java selenium selenium-webdriver nullpointerexception testng


【解决方案1】:

你的脚本有很多问题

1 - 你的类单独初始化。 @BeforeClass 的驱动程序不会继承到您的 @Test

2 - 当你这样做时

Login lp = new Login();

你有

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

然后

lp.login(sUserName, sPassword);

NullPointException 抛出,因为以下代码行中的驱动程序为空

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

建议行动

  • 您需要让驱动程序完成所有课程

TestBase.class

Put your @BeforeClass here

LoginPage.class,请确保您允许将驱动程序投射到其中

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);

【讨论】:

    【解决方案2】:

    您的问题是 - 您的方法 beforeTest 没有调用。您的 driver 不指向任何类型的对象。

    TestNG 仅在您的所有类中搜索 @Test 注释。它应该如何知道 @BeforeClass 注释位于您创建的特定类中?

    要运行@BeforeClass注解,你要么必须为Login类设置extends(对多个脚本无效),要么手动运行beforeTest方法。或者将其设置为包含@Test注解的运行类。

    如果我错了,请纠正我。 希望对您有所帮助!

    编辑:

    将您的方法和 WebDriver 变量移动到 Test Runner

     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 类应该同时包含@Test@BeforeClass。当 TestNG 从包含 @Test 注释的类中读取注释时。

    【讨论】:

    • 您是正确的,beforeTest() 没有被调用,但您的推理并不完全正确。 TestNG 确实 在类中搜索注释,但仅针对@Test,在找到类后检查所有其他TestNG 注释。您对“设置”extends 的评论没有任何意义;没有必要扩展任何东西。
    • 我还是会工作,尽管如此!我曾经创建“设置”类作为所有@Tests 和每个@Test 类扩展Settings 类的主要设置。通过这种解决方案,TestNG 调用@BeforeClass@Test。这是一种特定的解决方案。我根据您的评论更正了我的答案。谢谢!
    • 你是在推荐TestRunner extends Login吗?
    • 在这种特殊情况下,这不是一个好的解决方案,但这就是我的意思,回答这个问题。例如:Login extends BasicSettingsTestRunner extends Login
    • 我将我的登录方法标记为@Test 并运行我的类现在我的 beforeTest 方法被调用但现在我收到错误:org.testng.TestNGException:方法登录需要 2 个参数,但提供了 0在测试注释中。 ...删除了 23 个堆栈帧无法理解为什么没有提供值,知道为什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2014-06-10
    • 1970-01-01
    • 2020-03-21
    • 2014-09-26
    • 1970-01-01
    相关资源
    最近更新 更多