TestNG 中多个 类 为 运行 时出现 NullPointerException

NullPointerException when multiple classes are run in TestNG

我一直在尝试在 TestNG.xml 中执行多个 classes 但立即得到 NullPointerException。但是当使用 运行 作为 TestNG 测试单独执行时,相同的测试通过。我添加了各种 classes 和 属性 文件中使用的所有代码。

错误信息:

    org.testng.TestNGException: 
Cannot find class in classpath: com.w2a.testcases.BankManagerLogin
    at org.testng.xml.XmlClass.loadClass(XmlClass.java:77)
    at org.testng.xml.XmlClass.init(XmlClass.java:69)
    at org.testng.xml.XmlClass.<init>(XmlClass.java:55)
    at org.testng.xml.TestNGContentHandler.startElement(TestNGContentHandler.java:575)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
    at org.apache.xerces.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(SAXParser.java:195)
    at org.testng.xml.XMLParser.parse(XMLParser.java:38)
    at org.testng.xml.SuiteXmlParser.parse(SuiteXmlParser.java:16)
    at org.testng.xml.SuiteXmlParser.parse(SuiteXmlParser.java:9)
    at org.testng.xml.Parser.parse(Parser.java:152)
    at org.testng.xml.Parser.parse(Parser.java:233)
    at org.testng.TestNG.parseSuite(TestNG.java:295)
    at org.testng.TestNG.initializeSuitesAndJarFile(TestNG.java:348)
    at org.testng.TestNG.initializeEverything(TestNG.java:995)
    at org.testng.remote.support.RemoteTestNG6_12.initialize(RemoteTestNG6_12.java:22)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:98)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)

下面是 testng.xml 文件的详细信息:

 <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite name="Data Driven">
    <test name="Bank Manager Login Test">
        <classes>
            <class name="com.w2a.testcases.BankManagerLogin"/>
        </classes>
    </test>
    <test name="Adding Customer Test">
        <classes>
            <class name="com.w2a.testcases.AddCustomerTest"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite -->

BankManagerLogin class

    public class BankManagerLogin extends TestBase{

    @Test
    public void loginAsBankManager() throws Exception 
    {
        driver.findElement(By.cssSelector(OR.getProperty("BNKButton"))).click();
        Thread.sleep(4000);

    }

}

AddCustomerTest class

public class AddCustomerTest extends TestBase {

    @Test(dataProvider="getData")
    public void AddCustomer(String firstName, String lastName, String postCode) throws Exception {
        driver.findElement(By.cssSelector(OR.getProperty("addCustButton1"))).click();
        driver.findElement(By.cssSelector(OR.getProperty("firstName"))).sendKeys(firstName);
        driver.findElement(By.cssSelector(OR.getProperty("lastName"))).sendKeys(lastName);
        driver.findElement(By.cssSelector(OR.getProperty("postCode"))).sendKeys(postCode);
        driver.findElement(By.cssSelector(OR.getProperty("addCustButton2"))).click();
    }


    @DataProvider
    public Object[][] getData()
    {
        String sheetName="AddCustomerTest";
        int rows= excel.getRowCount(sheetName);
        int cols= excel.getColumnCount(sheetName);
        Object[][] data = new Object[rows-1][cols];

        for (int rowNum=2; rowNum<=rows; rowNum++)
        {
            for (int col_Num=0; col_Num<cols; col_Num++)
            {
                data[rowNum-2][col_Num]= excel.getCellData(sheetName, col_Num, rowNum);
            }
        }
        return data;


    }

}

有一个基类来定义@BeforeSuite 和@AfterSuite:

public class TestBase {

    public  WebDriver driver;
    public static Properties config = new Properties();
    public static Properties OR = new Properties();
    public static FileInputStream fis;
    public static ExcelReader excel =new ExcelReader(System.getProperty("user.dir")+"\src\test\resources\excel\testdata.xlsx");



    //public static Logger log=Logger.get

    @BeforeSuite
    public void setUp()
    {
        if(driver==null)
        {

            try{
                fis = new FileInputStream(System.getProperty("user.dir")+"\src\test\resources\properties\config.properties");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();}
                try {
                    config.load(fis);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
            try {

                fis= new FileInputStream(System.getProperty("user.dir")+"\src\test\resources\properties\OR.properties");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();}
                try {
                    OR.load(fis);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }



                if(config.getProperty("browser").equals("chrome"))
                {
                    System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\src\test\resources\executables\chromedriver.exe");
                    driver= new ChromeDriver();
                    //log.debug("Chrome launched");
                }
                else if

                (config.getProperty("browser").equals("firefox"))
                {
                    System.setProperty("webdriver.gecko.driver", System.getProperty("user.dir")+"\src\test\resources\executables\geckodriver.exe");
                    driver= new FirefoxDriver();
                    //log.debug("Firefox launched");
                }

                else if

                (config.getProperty("browser").equals("IE"))
                {
                    System.setProperty("webdriver.IE.driver",System.getProperty("user.dir")+"\src\test\resources\executables\IEDriverServer.exe");
                    driver= new InternetExplorerDriver();
                    //log.debug("Internet Explorer launched");
                }

                driver.get(config.getProperty("testSiteurl"));
                //log.debug("Navigated to: "+config.getProperty("testSiteURL"));
                driver.manage().window().maximize();
                driver.manage().timeouts().implicitlyWait(Integer.parseInt(config.getProperty("implicit.wait")), TimeUnit.SECONDS);
            }


    @AfterSuite
    public void tearDown()
    {
        driver.quit();
    }
}

******对象 属性 文件:******

    #Bank Manager Login button
BankManagerLogin=div > div:last-child > .btn.btn-primary.btn-lg

#Add Customer button
addCustomerButton=button[ng-click='addCust()']

#customer details
addCustButton1=button[ng-click='addCust()']
firstName=input[ng-model='fName']
lastName=input[ng-model='lName']
postCode=input[ng-model='postCd']


#click add customer button on form
addCustButton2=button[class='btn btn-default']

******配置 属性 文件:******

browser=chrome
testSiteURL=http://www.way2automation.com/angularjs-protractor/banking/#/login
implicit.wait=10

这个异常的主要原因是packageName.classname in Testng.xml is not equal to actual file location packageName.classname。如果两个地方都一样,那么这个问题的可能性有很多。

  1. 只需执行 Eclipse> Project > Clean 然后再 运行 测试用例。 它应该工作。

What it does in background is, that it will call mvn eclipse:clean in your project directory which will delete your .project and .classpath files and you can also do a mvn eclipse:eclipse - this regenerates your .project and .classpath files. Thus adding the desired class in the classpath.

  1. 有时,我们已经安装了 testng plugin for eclipse 漏洞。解决方案与第一点相同。

Eclipse> Project > Clean

  1. 有时 cleanmavenupdate 项目也有帮助

Clean the project (Right click on pom.xml and clean) And update the maven project (Project > Maven > Update Maven Project)

4.Adding Pom.xml 标签下的 Pom.xml src 和 test 目录也有帮助

<build>
        <sourceDirectory>${basedir}/src</sourceDirectory>
        <testSourceDirectory>${basedir}/test</testSourceDirectory>
         (...)
        <plugins>
            (...)
        </plugins>
    </build>

工作原理

Maven provides TestNG with the directory of where those packages are potentially stored, and then TestNG starts looking recursively. Even just providing ${baseDir} should work. It seems the issue is not providing a directory at all. I am not sure where it looks by default, but providing a valid directory within the project allows TestNG to spider through and find the location of the packages. Maven is then able to build the changes from each package into the target/ folder and run

  1. 运行 在命令提示符下为 testng.xml 文件执行命令, 如果您缺少它们,请检查以下内容

    a) 在命令提示符中,确保导航到放置 testng.xml 文件的文件夹。 b) 导航到该位置后,设置 CLASSPATH 并包括 testng jar 文件位置、selenium-server jar 文件位置(如果您使用的是 selenium webdriver)、bin folder 项目位置其中包含项目的所有 .class 文件。

    c) 例如,设置 CLASSPATH=C:\Selenium\testng-5.8-jdk15.jar;C:\Selenium\selenium-server-standalone-2.31.0.jar;C:\SeleniumTests\YourProject\bin d) 现在 运行 命令 java org.testng.TestNG testng.xml.

  2. 如果你是 运行宁 testng test cases 来自 Eclipse or other IDE 交叉检查你在 Run Configuration 中指向 correct testng.xml (如果我们在工作区中有多个 testng 项目,通常会发生)

  3. 有时卸载重装testng plugin也会解决 问题。