Search code examples
javamavencucumbercucumber-jvm

Cucumber: Class not found com.example.runner.RunnerTest


I have a maven project to run cucumber and selenium. The *.feature files are defined in the src/features, and the steps are defined in the src/test/java/com/example/steps.

enter image description here

I have also defined a test runner class as below:

package com.example.runner;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(
             features={"src/features"},
             glue="com/example/steps")
public class RunnerTest {

}

The problem is: When i run the class it complains with:

Class not found com.example.runner.RunnerTest
java.lang.ClassNotFoundException: com.example.runner.RunnerTest
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:688)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:421)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

The question is, why it does not recognized the runner calss?


Update:

when i run the feature file by

open feature file -> right click -> Run as -> 1 cucumber feature

It works well

I changed the glue="com/example/steps" to glue="com.example.steps" and it complains with :

java.lang.NullPointerException
    at com.example.steps.Click_Steps.i_am_in(Click_Steps.java:23)
    at ✽.Given I am in "http://suvian.in/selenium/1.6checkbox.html"(CheckBox.feature:14)

and when i refer to the file:

base.getDriver().navigate().to(uri);

But as i said, this line work pretty well when i run the feature file using Run as -> Cucumber


Solution

  • I would consider re-organizing your structure in the following way:

    src/
    ├── main/
    │   └── java/
    |        └── ...
    │   
    └── test/
        ├── java/
        |    └── com.example/
        |         ├── checkbox/
        |         |    ├── CheckboxSteps/
        |         |    └── CheckboxTest/
        |         ├── click_button/
        |         |    ├── ClickButtonSteps/
        |         |    └── ClickButtonTest/
        |         └── ...
        |
        └── resources/
             └── features/
                  ├── checkbox/
                  |    └── checkbox.feature/
                  ├── click_button/
                  |    └── ClickButton.feature/
                  └── ...
    

    This will improve both your code organization and traceability in case of failing tests.

    CheckboxTest should then look like this:

    package com.example.checkbox;
    
       import cucumber.api.CucumberOptions;
       import cucumber.api.SnippetType;
       import cucumber.api.junit.Cucumber;
       import org.junit.runner.RunWith;
    
       @RunWith(Cucumber.class)
       @CucumberOptions(
                    snippets = SnippetType.CAMELCASE,
                    glue = {"com.example.checkbox"},
                    features = "classpath:features/checkbox")
       public class CheckboxTest {
    
        /*
        * This class should be empty, step definitions should be in separate classes.
        */
    
       }
    

    Then put your step definitions in CheckboxSteps.

    You should be able to run CheckboxTest now.