Search code examples
spring-bootselenium-webdrivercucumbercucumber-javacucumber-junit

Getting NullPointerException while running a Cucumber test with Spring Boot, Selenium and JUnit


I have a simple Selenium-Cucumber based test that is throwing NullPointerException when I am executing it.

I have already initialized the WebDriver (chrome) but for some reason the test is not able to pick that.

Not sure why driver is not getting initialized even after doing a new on ChromeDriver

Error

com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.example.TestRunner
driver: null

java.lang.NullPointerException
    at com.example.GoogleCalcStepDefinition.I_open_google(GoogleCalcStepDefinition.java:38)
    at ✽.I open Google(file:src/test/resources/features/calc.feature:7)

Feature: Check addition in Google calculatorcontent
  In order to verify that Google calculator work correctly
  As a user of Google
  I should be able to get correct addition result

  Scenario: Addition                     # src/test/resources/features/calc.feature:6
    Given I open Google                  # GoogleCalcStepDefinition.I_open_google()
      java.lang.NullPointerException
    at com.example.GoogleCalcStepDefinition.I_open_google(GoogleCalcStepDefinition.java:38)
    at ✽.I open Google(file:src/test/resources/features/calc.feature:7)

    When I enter "2+2" in search textbox # GoogleCalcStepDefinition.I_enter_in_search_textbox(String)
    Then I should get result as "4"      # GoogleCalcStepDefinition.I_should_get_correct_result(String)

Failed scenarios:
src/test/resources/features/calc.feature:6 # Addition

1 Scenarios (1 failed)
3 Steps (1 failed, 2 skipped)
0m1.364s

java.lang.NullPointerException
    at com.example.GoogleCalcStepDefinition.I_open_google(GoogleCalcStepDefinition.java:38)
    at ✽.I open Google(file:src/test/resources/features/calc.feature:7)

GoogleCalcStepDefinition.java

public class GoogleCalcStepDefinition extends CucumberStepDefinitions {

    private static final String CHROME_DRIVER_EXE = "drivers/chromedriver.exe";
    private static final String WEBDRIVER_CHROME_DRIVER = "webdriver.chrome.driver";
    private static WebDriver driver;

    @BeforeClass
    public static void setUp() {
        System.out.println("Into the setUp() method...");
        String filePath = ClassLoader.getSystemClassLoader().getResource(CHROME_DRIVER_EXE).getFile();
        System.setProperty(WEBDRIVER_CHROME_DRIVER, filePath);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("useAutomationExtension", false);
        driver = new ChromeDriver(options);
    }

    @Given("^I open Google$")
    public void I_open_google() {
        System.out.println("driver: " + driver);
        //Set implicit wait of 10 seconds and launch google
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        driver.get("https://www.google.co.in");
    }

    @When("^I enter \"([^\"]*)\" in search textbox$")
    public void I_enter_in_search_textbox(String additionTerms) {
        //Write term in google textbox
        WebElement googleTextBox = driver.findElement(By.id("gbqfq"));
        googleTextBox.sendKeys(additionTerms);

        //Click on searchButton
        WebElement searchButton = driver.findElement(By.id("gbqfb"));
        searchButton.click();
    }

    @Then("^I should get result as \"([^\"]*)\"$")
    public void I_should_get_correct_result(String expectedResult) {
        //Get result from calculator
        WebElement calculatorTextBox = driver.findElement(By.id("cwos"));
        String result = calculatorTextBox.getText();
        //Verify that result of 2+2 is 4
        assertEquals(result, expectedResult);
    }

    @AfterClass
    public static void closeBrowser() {
        if (null != driver) {
            driver.close();
            driver.quit();
        }
    }

}   

CucumberStepDefinitions.java

@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class CucumberStepDefinitions {

}

TestRunner.java

@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"pretty"}, features = {"src/test/resources/features"})
public class TestRunner {

}

src/test/resources/features/calc.feature

Feature: Check addition in Google calculatorcontent
  In order to verify that Google calculator work correctly
  As a user of Google
  I should be able to get correct addition result

  Scenario: Addition
    Given I open Google
    When I enter "2+2" in search textbox
    Then I should get result as "4"

src/test/resources/drivers/chromedriver.exe

pom.xml

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>4.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>4.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-spring</artifactId>
        <version>4.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-chrome-driver</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-chrome-driver</artifactId>
        <version>2.45.0</version>
        <scope>test</scope>
    </dependency>

Solution

  • The problem is that you used JUnit's @BeforeClass annotation which is not respected by Cucumber runner.

    Instead, you can use cucumber.api.Before -> @Before or @After annotations.

    If you annotate method hook with one of these annotations you can use Scenario interface to get, for example, tags of the running scenario.

    You can also have multiple @Before and @After methods and you can provide order of them like this:

    @Before(order = 1)
    public void init(Scenario scenario) { }