2

從命令行運行JUnit測試時,我得到一個NullPointerException,但是當通過IntelliJ的調試器運行時,不會引發異常。來自命令行的NullPointerException,而不是IntelliJ調試器

下面是相關的異常信息:

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) 

我不知道什麼可能會造成問題,因爲這行是:driver.navigate().to(url);

而且url是多數民衆贊成硬編碼字符串一個覆蓋的getPageUrl()方法。當指定的瀏覽器打開時,WebDriver處於正常運行狀態,並且在其他腳本(utils,測試數據管家等)中起作用,這很有趣,因爲相同的代碼用於管理驅動程序/硒實例。

除了將-ea傳遞給默認的Java VM,IntelliJ的調試配置沒有指定其他參數。

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(構造函數):

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:

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(); 
    } 
} 
+3

如果將'driver.navigate()。(url);'拆分爲兩個語句,則異常行號將區分'driver' == null與'driver.navigate()== null。 – Jerry101 2014-09-30 21:03:25

+0

爲了幫助別人,儘管爲了我自己的尷尬,結果問題是我的classapath被設置爲舊的「out/production」目錄,而不是「target /」目錄。 – 2014-10-08 23:48:02

回答

1

@ Jerry101的建議是一個很好的一個。但是,如果您想在不更改源代碼的情況下執行此操作(或者無法更改代碼),則還可以在IDEA中創建遠程調試配置。這將允許您在發生null時在環境中運行它,但使用IDEA調試器來查看問題是什麼。

Run/Debug Configurations對話框中,單擊添加按鈕Add Button並選擇Remote Debug IconRemote。您可能需要使用Listen調試器模式,以便您可以先啓動調試器。您可以使用Attach模式,但需要確保在從命令行開始測試之後,可以快速啓動IDEA調試配置,然後再轉到有問題的代碼。對於非生產系統,Listen沒問題。

當您通過命令行運行測試時,將必要的配置選項(如IDEA遠程調試配置對話框中所示)添加到命令行。當斷點被擊中時,你可以看到什麼是null