当前位置: 首页 > 知识库问答 >
问题:

使用TestNg和Maven的Selenium WebDriver中的NullPointerException

景俊良
2023-03-14

我目前正在构建一个Maven项目,其中也包括Eclipse中的TestNg库。我使用最新的Selenium版本3.8.1运行在Java 8上(从Java 9切换过来,因为我听说这会导致其他版本的问题)。我的项目运行顺利,没有任何问题,测试运行良好,然后它开始抛出< code > NullPointerException s。我尝试再次构建项目,但没有成功。

这是我的设置:

下面是TestBase类,其中我使用了< code>@BeforeSuite和< code>@AfterSuite来实例化WebDriver。这将顺利启动。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;

public class TestBaseMaven {

    public WebDriver driver;
    public static FileInputStream fis;
    public static FileInputStream fis1;
    public static Properties config = new Properties();
    public static Properties OR = new Properties();
    public static Logger log;

    @BeforeSuite
    public void setUp() throws IOException, InterruptedException {
        fis = new FileInputStream("C:\\Users\\Kohout\\eclipse-workspace\\MavenProjects\\MavenProject2\\src\\test\\resources\\properties\\Config.properties");
        config.load(fis);
        fis1 = new FileInputStream("C:\\Users\\Kohout\\eclipse-workspace\\MavenProjects\\MavenProject2\\src\\test\\resources\\properties\\OR.properties");
        OR.load(fis1);

        if(driver==null) {
            if(config.getProperty("browser").equals("chrome")) {
                System.setProperty("webdriver.chrome.driver", "C:\\Users\\Kohout\\eclipse-workspace\\MavenProjects\\MavenProject2\\src\\test\\resources\\executables\\chromedriver.exe");
                driver = new ChromeDriver();
            } else if(config.getProperty("browser").equals("firefox")) {
                System.setProperty("webdriver.gecko.driver", "C:\\Users\\Kohout\\eclipse-workspace\\MavenProjects\\MavenProject2\\src\\test\\resources\\executables\\geckodriver.exe");
                DesiredCapabilities dc = DesiredCapabilities.firefox();
                dc.setCapability("marionette", true);
                driver=new FirefoxDriver();
            } else if(config.getProperty("browser").equals("ie")) {
                System.setProperty("webdriver.ie.driver", "C:\\Users\\Kohout\\eclipse-workspace\\MavenProjects\\MavenProject2\\src\\test\\resources\\executables\\IEDriverServer.exe");
                driver = new InternetExplorerDriver();
            }
        }

        driver.get(config.getProperty("testUrl"));
        driver.manage().window().maximize();
        Thread.sleep(2000);
    }

    public boolean isElementPresent(By by) {
        try {
            driver.findElement(by);
            return true;
        } catch(Throwable t) {
            return false;
        }
    }

    @AfterSuite
    public void tearDown() {
        if(driver!=null) {
            driver.quit();
        }
    }
}

这是我的第一个测试,也运行良好,正在通过。虽然有时这也会在我使用< code>Webdriver时抛出< code > NullPointerException ,例如在< code>driver.findElement中...

import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.Test;

import com.kohout.base.TestBaseMaven;

public class ManagerLoginTest extends TestBaseMaven {

    @Test
    public void managerLoginTest() throws InterruptedException {
        driver.findElement(By.cssSelector(config.getProperty("managerLogin"))).click();
        Thread.sleep(2000);
        Assert.assertTrue(isElementPresent(By.cssSelector(OR.getProperty("addCust"))));
    }

}

这是我的第二个测试。现在无论出于什么原因,每当我使用实例化的驱动程序变量(实例化在@BeforeSuite中)时,这个总是会抛出NullPointerException

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;

import com.kohout.base.TestBaseMaven;

public class AddCustomerTest extends TestBaseMaven {

    @Test
    public void addCustomerTest() {
         driver.findElement(By.xpath("/html/body/div[3]/div/div[2]/div/div[1]/button[1]"));
    }

}

以下是我的堆栈跟踪:

java.lang.NullPointerException
at com.kohout.testcases.AddCustomerTest.addCustomerTest(AddCustomerTest.java:14)
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:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:571)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:707)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:979)
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:1187)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
at org.testng.TestNG.runSuites(TestNG.java:1028)
at org.testng.TestNG.run(TestNG.java:996)
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)

我还想包括我的testng.xml,我也在pom.xml中称之为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Bank Suite">     
  <test name="Login Test">
    <classes>
      <class name="com.kohout.testcases.ManagerLoginTest"/>
      <class name="com.kohout.testcases.AddCustomerTest"/>
    </classes>     
  </test> <!-- Test -->    
</suite> <!-- Suite -->

这也是我的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.kohout</groupId>
    <artifactId>MavenProject2</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <dependencies>        
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.8.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.testng/testng -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.13.1</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans -->
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>2.6.0</version>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.20.1</version>
                    <configuration>
                        <suiteXmlFiles>
                            <suitXmlFile>C:\Users\Kohout\eclipse-workspace\MavenProjects\MavenProject2\testng.xml</suitXmlFile>
                        </suiteXmlFiles>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

谢谢你的时间和帮助。

共有1个答案

许高峻
2023-03-14

问题出在您的测试代码中。您正在使用基类中的@BeforeSuite注释来初始化WebDriver实例。

TestNG 仅执行一次@BeforeSuite带注释的方法

如果测试类只有一个@test方法,请将其更改为开始使用@BeforeClass。

如果您的测试类有多个< code>@Test方法,那么您应该基本上利用一个< code>ThreadLocal变量(或者)您应该利用一个TestNG侦听器来初始化webdriver,然后查询webdriver实例。

您可以参考我在这里的博客文章,了解如何使用TestNG侦听器来促进并行执行。

这是一个示例,它显示了线程局部变体的样子

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger;

public class TestBaseMavenRefactored {

    private static final String PREFIX = "C:\\Users\\Kohout\\eclipse-workspace\\MavenProjects\\MavenProject2";

    private static final ThreadLocal<WebDriver> driver = new ThreadLocal<>();
    private Properties config = new Properties();
    private Properties OR = new Properties();
    public static Logger log;

    protected WebDriver getDriver() {
        return driver.get();
    }

    protected Properties getConfig() {
        return config;
    }

    public Properties getOR() {
        return OR;
    }

    private void cleanupDriver() {
        driver.get().quit();
        driver.remove();
    }

    @BeforeMethod
    public void setUp() throws IOException, InterruptedException {
        FileInputStream fis = new FileInputStream(PREFIX + "\\src\\test\\resources\\properties\\Config.properties");
        config.load(fis);

        FileInputStream fis1 = new FileInputStream(PREFIX + "\\src\\test\\resources\\properties\\OR.properties");
        OR.load(fis1);

        switch (config.getProperty("browser")) {
            case "chrome":
                System.setProperty("webdriver.chrome.driver", PREFIX + "\\src\\test\\resources\\executables\\chromedriver.exe");
                driver.set(new ChromeDriver());
                break;

            case "firefox":
                System.setProperty("webdriver.gecko.driver", PREFIX + "\\src\\test\\resources\\executables\\geckodriver.exe");
                DesiredCapabilities dc = DesiredCapabilities.firefox();
                dc.setCapability("marionette", true);
                driver.set(new FirefoxDriver());
                break;

            case "ie":
                System.setProperty("webdriver.ie.driver", PREFIX + "\\src\\test\\resources\\executables\\IEDriverServer.exe");
                driver.set(new InternetExplorerDriver());
                break;
        }
        getDriver().get(config.getProperty("testUrl"));
        getDriver().manage().window().maximize();
        Thread.sleep(2000);
    }

    public boolean isElementPresent(By by) {
        try {
            getDriver().findElement(by);
            return true;
        } catch (Throwable t) {
            return false;
        }
    }

    @AfterMethod
    public void tearDown() {
        cleanupDriver();
    }
}

下面是重构后的测试类的样子:

import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.Test;

public class ManagerLoginTest extends TestBaseMavenRefactored {
    @Test
    public void managerLoginTest() throws InterruptedException {
        getDriver().findElement(By.cssSelector(getConfig().getProperty("managerLogin"))).click();
        Thread.sleep(2000);
        Assert.assertTrue(isElementPresent(By.cssSelector(getOR().getProperty("addCust"))));
    }
}
 类似资料:
  • 有没有任何一个测试REST API的使用硒网络驱动程序Maven TestNG。请分享信息或样本项目

  • 当我使用maven运行我的testng套件xml时,在suite标记中没有parallel=“tests”时,我会出现异常。 当我用parallel=“tests”运行它时,它工作得很好。此外,如果我在没有parallel=“tests”的情况下从eclipse“Run as testng Test”运行我的testng套件xml,它工作得很好。请帮忙。

  • 请查看testng.xml并建议 我想运行2个类(下面提到),但面临一些挑战,因为它在下面提到的2个场景下显示了一些不稳定的行为。 这些测试类下的方法具有组和优先级 **目标是使用组运行这些测试 Scenario1:当我使用Threadcount=1时; [test name=“autopracticee”parallel=“classes”thread-count=“1”] 以下是行为: 1.1

  • TestNG属性“DelegateCommandSystemProperties”不能与maven surefire插件一起使用。 我试图在testng.xml中运行一个测试,它使用名为“count”的参数。 我在其中配置属性的pom.xml代码段 简而言之,我需要帮助从maven surefire命令将参数传递给testng test!

  • 我正在尝试播放以下网站的视频(使用JUnit)-Day01。http://www.itelearn.com/live-training/security-testing-live-training我试图实现的是,在播放视频后,我将拍摄一张屏幕截图,以证明视频播放正确。点击Day01视频后,它会在一个新窗口中打开——当我查看代码时,我意识到他们使用了iFrame。我可以关闭此视频窗口,但无法播放/暂

  • 我正在尝试使用2个xml文件与Maven并行运行我的测试,但似乎不起作用。我已经尝试了Maven留档中的步骤/参数:http://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html 以下是我的pom.xml文件: 这是功能1.xml文件: 我应该做哪些参数/更改才能使其生效? 谢谢你