I am getting a NullPointerException
before Appium and the emulator launch. So trying to debug by having sysout
lines in the code is not helping at all.
If anyone has some advice please send through as I am going crazy!
My dependencies:
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0-beta3</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-core</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
My Hooks class:
package MA.test;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import java.net.MalformedURLException;
import java.net.URL;
public class Hooks {
public AppiumDriver driver;
public AppiumDriverLocalService service;
@Parameters({"platformVersion", "emulatorNumber", "deviceName", "port"})
@BeforeTest(alwaysRun = true)
public void startAppiumServer(String platformVersion, String emulatorNumber, String deviceName, String port) throws InterruptedException, MalformedURLException {
System.out.println("\n ABC");
service = new AppiumServiceBuilder()
.usingPort(Integer.valueOf(port))
.build();
service.start();
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, platformVersion);
caps.setCapability(MobileCapabilityType.DEVICE_NAME, emulatorNumber);
caps.setCapability(AndroidMobileCapabilityType.AVD, deviceName);
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.APPLICATION_NAME, "Name");
caps.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.14.0");
caps.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "activity");
caps.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "package");
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
driver = new AndroidDriver<MobileElement>(new URL("http://0.0.0.0:" + port + "/wd/hub"), caps);
System.out.println("\n Appium server: " + service.getUrl());
Thread.sleep(2000);
}
@AfterTest
public void teardown() {
service.stop();
driver.quit();
driver.closeApp();
System.out.println("\n Test quit");
}
}
My TestRunner class:
package MA.steps;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
@CucumberOptions(
plugin = {"pretty", "html:target/cucumber-reports"}
, monochrome = true
, features = "src/test/java/feature"
, tags = "@Login"
)
public class TestRunner extends AbstractTestNGCucumberTests {
}
My testng.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Android Parallel Execution" parallel="tests" thread-count="2" verbose="7">
<test name="Device1">
<parameter name="platformVersion" value="9.0"/>
<parameter name="emulatorNumber" value="emulator-5554"/>
<parameter name="deviceName" value="Android9_Nexus"/>
<parameter name="port" value="4723"/>
<classes>
<class name="MA.steps.TestRunner"/>
</classes>
</test>
</suite>
And I am receiving the following error:
java.lang.NullPointerException at screens.myAccountOverviewScreen.logoutAccount(myAccountOverviewScreen.java:104)
Which points to the following line of code:
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
This ^ is the first time driver
is called in my tests, but what baffles me is that it is throwing a nullpointerexception
without even launching appium, or starting the emulator.
The problem lies in your test code.
You created a suite xml file to include only your TestRunner
class. But the entire of the appium instantiation logic is stuck in the Hooks
class which does it via the TestNG configuration annotation @BeforeTest
and @AfterTest
. But this class is neither included in your suite, nor your test class (TestRunner
) extends it. So your configurations aren't getting invoked leading to a null value for your AppiumDriver
object.
To fix the problem, you can do one of the following:
Hooks
class also in it. (or)IInvokedMethodListener
and move your driver instantiation into its beforeInvocation