Search code examples
androidandroid-testingcucumber-jvm

Android Unit Testing: Cucumber-jvm + Android Instrumentation


Using: Cucumber-JVM with Android Instrumentation + Espresso).

Reference Github link: https://github.com/mfellner/cucumber-android for this. The simple sample works fine.

Problem with cucumber-jvm + android instrumentation: But in the sample in link, it uses ActivityInstrumentationTestCase2 which is deprecated. I would like to use @Rule - ActivityTestRule class as said by Google.

Here my question is: For using cucumber-jvm, I am using the CucumberInstrumentationCore instead of testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner".

So Android junit annotations like @Rule for ActivityTestRule is not parsed by CucumberInstrumentation. So Is it possible to overcome this problem?

Then is my decision to use cucumber-jvm + android instrumentation has to be reverted back. My question is not only for the deprecated class but globally is it good idea to go for cucumber-jvm + android instrumentation, as it can't use instrumentation features because of annotation parsing.


Solution

  • Your runner should inherit from Android JUnitRunner:

    public class Instrumentation extends AndroidJUnitRunner {
    
    private final CucumberInstrumentationCore instrumentationCore = new CucumberInstrumentationCore(this);
    
    @Override
    public void onCreate(final Bundle bundle) {
        instrumentationCore.create(bundle);
        super.onCreate(bundle);
    }
    
    @Override
    public void onStart() {
        waitForIdleSync();
        instrumentationCore.start();
    }
    

    Pay attention to the super class been initialized at the end of onCreate.

    Then, edit your defaultConfig in your build.grade file:

    defaultConfig {
        applicationId "your.package.name"
    
        testApplicationId "your.steps.package"
        testInstrumentationRunner "your.package.Instrumentation"     
    }
    

    And finally, the steps definition class, which inherited from ActivityInstrumentationTestCase2 should look like:

    public class BaseStepDefinitions {
    public static final String TAG = BaseStepDefinitions.class.getSimpleName();
    
    @Rule
    public ActivityTestRule<StartupActivity> mActivityRule = new ActivityTestRule<>(StartupActivity.class);
    
    
    @Before
    public void setUp() throws Exception {
        mActivityRule.launchActivity(null);
        mActivityRule.getActivity();
    }
    
    /**
     * All the clean up of application's data and state after each scenario must happen here
     */
    @After
    public void tearDown() throws Exception {
    
    }
    
    @When("^I login with \"([^\"]*)\" and \"([^\"]*)\"$")
    public void i_login_with_and(String user, String password) throws Throwable {
       // Login...
    }
    

    The setUp function runs before each scenario, and launching the activity.

    Globally, if it serves your needs I don't see any problem using it like so, both Cucumber annotations and the JUnit annotations can be parsed in this way.

    I've created a sample project: github.com/Clutcha/EspressoCucumber