Getting NullPointerException if I run tests through testng.xml but it works fine one at a time

Prologue: I'm new to automation testing

I have a problem with two tests that I am trying to run through testng.xml as a suite. But if I run them separately , they work fine. Here is my code: BasePage.java

public class BasePage {
    protected WebDriver driver;
    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

      

BaseTest.java

public class BaseTest {
    private WebDriver driver;
    private final String chromeDriverPath = "src//main//resources//chromedriver.exe";
    private final String firefoxDriverPath = "src//main//resources//geckodriver.exe";

    public WebDriver getDriver() {
        return driver;
    }

    @BeforeTest
    @Parameters({"browser", "baseURL"})
    public void setUp(@Optional String browser, @Optional String baseURL) {
        driver = getBrowserType(browser);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        driver.manage().window().maximize();
        driver.navigate().to(baseURL);
    }

    private WebDriver getBrowserType(String browserType) {
        if (driver == null ) {
            if (browserType.equalsIgnoreCase("firefox")) {
                 System.setProperty("webdriver.gecko.driver", firefoxDriverPath);
                 return  new FirefoxDriver();
            }
            else if (browserType.equalsIgnoreCase("chrome")) {
                System.setProperty("webdriver.chrome.driver", chromeDriverPath);
                return new ChromeDriver();
            }
        }
        return driver;
    }

    @AfterTest
    public void tearDown() {
        if (driver != null)
            driver.quit();
    }
}

      

HomePage.java

public class HomePage extends BasePage {

    public HomePage(WebDriver driver) {
        super(driver);
    }

    public boolean verifyHomePage() {
        return driver.getCurrentUrl().contains("url");
    }
}

      

NavigationMenuComponent.java

public class NavigationMenuComponent extends BasePage{

    public NavigationMenuComponent(WebDriver driver) {
        super(driver);
    }

    @FindBy(xpath = "//ul[@class='right']//a[contains(@href, '/about')]")
    private WebElement aboutLink;

    public void test() {
         aboutLink.click();
    }
}

      

HomePageTest.java

public class HomePageTest extends BaseTest {

    private HomePage homePage;

    @BeforeClass(alwaysRun = true)
    public void init() {
        homePage = PageFactory.initElements(getDriver(), HomePage.class);
    }

    @Test(groups = "home-page")
    public void verifyFirstPage() {
        Assert.assertTrue(homePage.verifyHomePage());
    }
    }

      

NavigationMenuTest.java

public class NavigationMenuTest extends BaseTest{

    private NavigationMenuComponent navigationMenuComponent;

    @BeforeClass
    public void init() {
        navigationMenuComponent = PageFactory.initElements(getDriver(), NavigationMenuComponent.class);
    }

    @Test(groups = "about-page")
    public void verifyAboutLink() {
       navigationMenuComponent.test();
    }
}

      

And my testng.xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="suite" parallel="tests" thread-count="2">
    <parameter name="baseURL" value="https://www.foodpanda.com/"></parameter>
    <test name="chromeTest" >
        <parameter name="browser" value="chrome"></parameter>
        <classes>
            <class name="tests.HomePageTest"></class>
            <class name="tests.NavigationMenuTest"></class>
        </classes>
    </test>
    <test name="firefoxTest">
        <parameter name="browser" value="firefox"></parameter>
        <classes>
            <class name="tests.HomePageTest"></class>
            <class name="tests.NavigationMenuTest"></class>
        </classes>
    </test>
</suite>

      

Here is the stacktrace

java.lang.NullPointerException
    at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
    at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
    at com.sun.proxy.$Proxy9.click(Unknown Source)
    at utils.NavigationMenuComponent.test(NavigationMenuComponent.java:36)
    at tests.NavigationMenuTest.verifyAboutLink(NavigationMenuTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

      

I am stuck on this. Should I run them separately or am I doing smh wrong?

+3


source to share


1 answer


The problem is how you initialize the webdriver instance. Below is a code snippet

@BeforeTest
@Parameters({"browser", "baseURL"})
public void setUp(@Optional String browser, @Optional String baseURL) {
    driver = getBrowserType(browser);
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    driver.manage().window().maximize();
    driver.navigate().to(baseURL);
}

      

calls a method setUp

that is called only once per tag <test>

, because part of the common base class belongs to your test classes.

So if you <test>

have two test classes in your tag like



<test name="chromeTest" >
    <parameter name="browser" value="chrome"></parameter>
    <classes>
        <class name="tests.HomePageTest"></class>
        <class name="tests.NavigationMenuTest"></class>
    </classes>
</test>

      

then the method setUp

will only be called for HomePageTest

and will be skipped on executionNavigationMenuTest

This explains why you are seeing NullPointerException

for your second test class in the tag <test>

. You will need to change this, perhaps annotating the method setUp

with @BeforeClass

instead of@BeforeTest

+4


source







All Articles