0

I'm stuck with null pointer exception while taking screenshot for failed steps in my test suite. I did google looking for solution to this but nothing has worked for me yet. Appreciate if anyone can please advise.

I have 2 android test classes and 2 iOS test classes. Both android and iOS have their own base program to initialize the android/iOS driver (declared as non static). The test classes are invoking the base program to initialize the driver (as this.driver = .initiaze()) to run all 4 tests classes in parallel.

I have 2 separate listeners (to take screenshot on failure) one for android and one for iOS. When any test fails, the listener program calls (android listener calls android base and ios calls ios base program) the base programs getscreenshot method which then fails with NPE error.

Below are the some code sample for ref.

(Note - if I define the driver as public static in base program, then NPE error goes away but parallel run fails with random error as driver of one class gets used by other class)

Android base: (similar code for iOS Base with return type as IOSDriver)

g_MobileBase.java:

public class g_MobileBase {

    @SuppressWarnings("rawtypes")

    public  AndroidDriver driver=null;

    public DesiredCapabilities cap;

    @SuppressWarnings("rawtypes")
    public AndroidDriver InitializeDriver() throws IOException
    {//initialization code; return driver;
        }
        public void getScreenshot(String classname, String testname) throws IOException
    {
        File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(src,new File(System.getProperty("user.dir")+"\\ErrorSnapshots\\"+classname+"_"+testname+"_"+new SimpleDateFormat("yyyy-MM-dd hh-mm-ss").format(new Date())+".png"));
    }
}

Android test class#1:

public class G_SearchStore_LocOff extends g_MobileBase{


    @BeforeTest (description="Initialize driver and install application")

    public void Initialize() throws IOException
    {

        this.driver = InitializeDriver();
//remaining code

}

@AfterTest (description="Close application and Quit driver")
    public void finish()
    {

        driver.closeApp();

        driver.quit();
}

@Test
.................some methods
.................some methods

}

Android Listener: (similar for iOS listener only create ios base program's object)

public class g_testListener implements ITestListener{

g_MobileBase b = new g_MobileBase();

@Override
    public void onTestFailure(ITestResult result) {
        // TODO Auto-generated method stub

        String[] temp = result.getInstanceName().toString().split("\\.");
        String classname = temp[1];

        try {

            b.getScreenshot(classname,result.getName());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

}
J Jena
  • 51
  • 3

1 Answers1

0

The problem lies in your test code.

TestNG by functionality invokes a @BeforeTest only once per <test> tag. So if in your <test> tag there are more than one test classes which are trying to use a webdriver instance and if that webdriver instance is getting initialized via a @BeforeTest method, then for the second instance the webdriver instance will be null.

To get past this issue, please replace the @BeforeTest annotation with @BeforeClass annotation.

Krishnan Mahadevan
  • 14,121
  • 6
  • 34
  • 66
  • I changed but still getting NPE in the getScreenshot method. I think the problem is: In BeforeClass, I am initializing a local driver by using "this.driver=InitializeDriver();". My getScreenshot method which is in base class doesn't know the value of this driver and hence NPE? May be I should pass this local driver from the listener to the screenshot method but I don't know how I can access this local driver. – J Jena Apr 17 '19 at 17:28