简体   繁体   English

来自命令行的 NullPointerException,不在 IntelliJ 调试器中

[英]NullPointerException from command line, not in IntelliJ debugger

When running JUnit tests from the command line, I get a NullPointerException, but when run through IntelliJ's debugger, no exception is thrown.从命令行运行 JUnit 测试时,我得到一个 NullPointerException,但是当通过 IntelliJ 的调试器运行时,没有抛出异常。

Here is the relevant exception info:以下是相关的异常信息:

java.lang.NullPointerException
    at org.ecx.test.models.AbstractPage.open(AbstractPage.java:98)
    at org.ecx.test.UserContext.login(UserContext.java:64)
    at org.ecx.test.TabMemory.TabMemoryTest(TabMemory.java:21)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runners.Suite.runChild(Suite.java:127)
    at org.junit.runners.Suite.runChild(Suite.java:26)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
    at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96)
    at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47)
    at org.junit.runner.JUnitCore.main(JUnitCore.java:40)

I'm not sure what could be causing the problem, as the line in question is: driver.navigate().to(url);我不确定是什么导致了问题,因为有问题的行是: driver.navigate().to(url);

And url is a string that's hardcoded to an overridden getPageUrl() method.并且url是一个字符串,它被硬编码为覆盖的getPageUrl()方法。 The WebDriver inits fine, as the specified browser opens, and is functional in other scripts (the utils, test data housekeeping, etc), which is interesting as the same code is used to manage driver/selenium instances.当指定的浏览器打开时,WebDriver 初始化良好,并且在其他脚本(实用程序、测试数据管理等)中正常运行,这很有趣,因为相同的代码用于管理驱动程序/selenium 实例。

No other arguments are being specified by IntelliJ's debug configurations, except passing -ea to the Java VM, which is default. IntelliJ 的调试配置没有指定其他参数,除了将-ea传递给 Java VM,这是默认设置。

AbstractTest.open: AbstractTest.open:

public void open() {
    if (!isInitialized) {
        throw new IllegalStateException("Page not initialized.");
    }
    String url = Environment.getBaseUrl() + getPageUrl();
    Log.debug("Opening url: %s", url);
    WebDriver.Navigation navigation = driver.navigate(); //Error is thrown here.
    navigation.to(url);
    //driver.navigate().to(url);
    PageFactory.initElements(driver, this);
    isLoaded = true;
}

AbstractTest(constructor): AbstractTest(构造函数):

public AbstractPage(Selenium selenium) {
    this.selenium = selenium;
    if (WebDriverBackedSelenium.class.isInstance(selenium)) {
        this.driver = ((WebDriverBackedSelenium) selenium).getWrappedDriver();
    }
    PageFactory.initElements(driver, this);
    uiMap = new Properties();
    initialize();
}

Environment.openSelenium: Environment.openSelenium:

public static void openSelenium() {
    if (!isSelenium) {
        Log.info("Opening Selenium...");
        driver = WebDriverFactory.getWebDriver();
        selenium = new WebDriverBackedSelenium(driver, Environment.getBaseUrl());
        Environment.setIsSelenium(true);
        seleniumExtension = SeleniumExtension.getInstance();
    }
}

@Jerry101 suggestion is a good one. @Jerry101 的建议很好。 However, if you want a way to do this without changing the source code (or in case you can't change the code), you could also create a remote debug configuration in IDEA.但是,如果您想在不更改源代码的情况下执行此操作(或者在无法更改代码的情况下),您还可以在 IDEA 中创建远程调试配置。 This would allow you to run it in the environment when the null occurs, but use the IDEA debugger to see what the issue is.这将允许您在发生 null 时在环境中运行它,但使用 IDEA 调试器来查看问题所在。

In the Run/Debug Configurations dialog, click the add button在“ Run/Debug Configurations对话框中,单击添加按钮添加按钮and select并选择远程调试图标Remote . Remote You may want to use the Listen debugger mode so you can start the debugger first.您可能想要使用Listen调试器模式,以便您可以先启动调试器。 You can use the Attach mode, but would need to make sure you can start the IDEA debug configuration quickly after starting the test from the command line before it got to the code in question.您可以使用Attach模式,但需要确保您可以在从命令行启动测试后快速启动 IDEA 调试配置,然后再进入相关代码。 For a non-production system, Listen is fine.对于非生产系统, Listen很好。

When you go to run your test via the command line, add the necessary configuration options -- as shown in the IDEA remote debug configuration dialog -- to your command line.当您通过命令行运行测试时,将必要的配置选项(如 IDEA 远程调试配置对话框中所示)添加到您的命令行。 When the breakpoint is hit, you can see what is null .当断点被命中时,你可以看到什么是null

I was struggled for the same problem.我为同样的问题而苦苦挣扎。 I enabled the detailed stacktrace in the maven-surefire-plugin by using configuration <trimStackTrace>false</trimStackTrace> .我使用配置<trimStackTrace>false</trimStackTrace>maven-surefire-plugin中启用了详细的堆栈跟踪。 The stack trace was looking like its an internal problem not from my code.堆栈跟踪看起来像是一个内部问题,而不是我的代码。

Then I used the configuration of surefire-plugin as follows and it worked.然后我使用了surefire-plugin的配置,如下所示,它起作用了。

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <forkCount>3</forkCount>
            <reuseForks>true</reuseForks>
        </configuration>
    </plugin>

Not sure if it was due to the parallel execution of tests or not but the configuration worked for me.不确定这是否是由于测试的并行执行,但配置对我有用。

I was using 2.22.2 version of surefire-plugin .我使用的是2.22.2版本的surefire-plugin

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM