Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Support Testing with JUnit4 Style Rules #894

Closed
mikeholler opened this issue Aug 4, 2015 · 5 comments
Closed

[Android] Support Testing with JUnit4 Style Rules #894

mikeholler opened this issue Aug 4, 2015 · 5 comments

Comments

@mikeholler
Copy link

I converted the Android example CalculatorActivitySteps from this:

public class CalculatorActivitySteps extends ActivityInstrumentationTestCase2<CalculatorActivity> {

    public CalculatorActivitySteps(SomeDependency dependency) {
        super(CalculatorActivity.class);
        assertNotNull(dependency);
    }

    @Given("^I have a CalculatorActivity$")
    public void I_have_a_CalculatorActivity() {
        assertNotNull(getActivity());
    }

    @When("^I press (\\d)$")
    public void I_press_d(final int d) {
        switch (d) {
            case 0:
                onView(withId(R.id.btn_d_0)).perform(click());
                break;
            case 1:
                onView(withId(R.id.btn_d_1)).perform(click());
                break;
            case 2:
                onView(withId(R.id.btn_d_2)).perform(click());
                break;
            case 3:
                onView(withId(R.id.btn_d_3)).perform(click());
                break;
            case 4:
                onView(withId(R.id.btn_d_4)).perform(click());
                break;
            case 5:
                onView(withId(R.id.btn_d_5)).perform(click());
                break;
            case 6:
                onView(withId(R.id.btn_d_6)).perform(click());
                break;
            case 7:
                onView(withId(R.id.btn_d_7)).perform(click());
                break;
            case 8:
                onView(withId(R.id.btn_d_8)).perform(click());
                break;
            case 9:
                onView(withId(R.id.btn_d_9)).perform(click());
                break;
        }
    }

    @When("^I press ([+–x\\/=])$")
    public void I_press_op(final char op) {
        switch (op) {
            case '+':
                onView(withId(R.id.btn_op_add)).perform(click());
                break;
            case '–':
                onView(withId(R.id.btn_op_subtract)).perform(click());
                break;
            case 'x':
                onView(withId(R.id.btn_op_multiply)).perform(click());
                break;
            case '/':
                onView(withId(R.id.btn_op_divide)).perform(click());
                break;
            case '=':
                onView(withId(R.id.btn_op_equals)).perform(click());
                break;
        }
    }

    @Then("^I should see (\\S+) on the display$")
    public void I_should_see_s_on_the_display(final String s) {
        onView(withId(R.id.txt_calc_display)).check(matches(withText(s)));
    }
}

To this:

public class CalculatorActivitySteps {

    @Rule
    private ActivityTestRule<CalculatorActivity> mActivityRule =
            new ActivityTestRule<>(CalculatorActivity.class);

    @Given("^I have a CalculatorActivity$")
    public void I_have_a_CalculatorActivity() {
        mActivityRule.launchActivity(new Intent());
    }

    @When("^I press (\\d)$")
    public void I_press_d(final int d) {
        switch (d) {
            case 0:
                onView(withId(R.id.btn_d_0)).perform(click());
                break;
            case 1:
                onView(withId(R.id.btn_d_1)).perform(click());
                break;
            case 2:
                onView(withId(R.id.btn_d_2)).perform(click());
                break;
            case 3:
                onView(withId(R.id.btn_d_3)).perform(click());
                break;
            case 4:
                onView(withId(R.id.btn_d_4)).perform(click());
                break;
            case 5:
                onView(withId(R.id.btn_d_5)).perform(click());
                break;
            case 6:
                onView(withId(R.id.btn_d_6)).perform(click());
                break;
            case 7:
                onView(withId(R.id.btn_d_7)).perform(click());
                break;
            case 8:
                onView(withId(R.id.btn_d_8)).perform(click());
                break;
            case 9:
                onView(withId(R.id.btn_d_9)).perform(click());
                break;
        }
    }

    @When("^I press ([+–x\\/=])$")
    public void I_press_op(final char op) {
        switch (op) {
            case '+':
                onView(withId(R.id.btn_op_add)).perform(click());
                break;
            case '–':
                onView(withId(R.id.btn_op_subtract)).perform(click());
                break;
            case 'x':
                onView(withId(R.id.btn_op_multiply)).perform(click());
                break;
            case '/':
                onView(withId(R.id.btn_op_divide)).perform(click());
                break;
            case '=':
                onView(withId(R.id.btn_op_equals)).perform(click());
                break;
        }
    }

    @Then("^I should see (\\S+) on the display$")
    public void I_should_see_s_on_the_display(final String s) {
        onView(withId(R.id.txt_calc_display)).check(matches(withText(s)));
    }
}

When using the @Rule, the activity would not shutdown after the first test.

@SierraGolf
Copy link
Contributor

I think junit rules don't really fit into the cucumber [android] world. Cucumber has their own @Before and @After annotations for that. Junit rules are specific to a group of tests (class holding @Test annotated methods). They will be executed for each test method in such a group.

In cucumber you would probably annotate a scenario with a tag and create a step class with @Before and @After annotated methods alongside the actual logic steps.

maybe it makes sense to create a utility project which ports the UiThreadTestRule and its descendants to abstract step classes which provide the same setup, tear down and step logic.

@johndeverall
Copy link

JUnit Rules would be very helpful for tasks such as Spring Integration. For example @SpringMethodRule doesn't work with Cucumber, because of philosophy??? It seems there is a lot of functionality going into JUnit TestRules and you guys are (strangely) choosing to miss out on it?

This also links to serenity-bdd/serenity-core#221

I notice Cucumber does have its own spring integration. It seems to fail when Guice is on the classpath though, is that right? Guice seems a critical dependency on serenity-core so that rules out using Cucumber with Serenity and Spring?

@SierraGolf
Copy link
Contributor

@johndeverall what would you annotate with such an annotation and when should code bound to it be executed?

about the guice/spring classpath problem, please create a separate issue. possibly with a link to a repository where the issue can be reproduced.

@sebrose
Copy link
Member

sebrose commented Sep 1, 2016

One way of running Cucumber is by using JUnit, but there are others, so we would not want to couple Cucumber & JUnit by sharing a JUnit annotation.

@sebrose sebrose closed this as completed Sep 1, 2016
@lock
Copy link

lock bot commented Oct 25, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Oct 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants