Search code examples
mavennullpointerexceptiontestng

NullPointerException when multiple classes are run in TestNG


I have been trying to execute multiple classes in TestNG.xml but immediately get NullPointerException. But the same test passes when executed individually using Run as TestNG Test. I have added all codes used in various classes and property files.

Error message:

    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)

Below is the testng.xml file details:

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


    }

}

Have a BaseClass to define @BeforeSuite and @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();
    }
}

******Object property file:******

    #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']

******Config property file:******

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

Solution

  • The main reason of this exception is packageName.classname in Testng.xml is not equal to actual file location packageName.classname. If it is same at both place then there is many possibilities for this issue.

    1. Just do Eclipse> Project > Clean and then run the test cases again. It should work.

    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. Sometime, we have got Installed testng plugin for eclipse which has bug. Solution is same mention in first point.

    Eclipse> Project > Clean

    1. Sometime clean project with maven and update it also help

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

    4.Adding src and test directory in Pom.xml under build tag also help

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

    How it works

    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. running the command for testng.xml file from command prompt, please check the following if you are missing them

      a) In the command prompt, make sure you are navigating to the folder where you have placed the testng.xml file. b) after navigating to that, set CLASSPATH and include the testng jar file location, selenium-server jar file location(if you are working with selenium webdriver), bin folder location of your project which contains all the .class files of your project.

      c) e.g., set CLASSPATH=C:\Selenium\testng-5.8-jdk15.jar;C:\Selenium\selenium-server-standalone-2.31.0.jar;C:\SeleniumTests\YourProject\bin d) Now run the command java org.testng.TestNG testng.xml.

    2. If you are running testng test cases from Eclipse or other IDE just cross check you have pointing correct testng.xml in Run Configuration (mostly happen if we have multiple testng project in workspace)

    3. Sometime uninstall and reinstall testng plugin will also solve issue.