Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to run Android Espresso unit tests in @BeforeClass annotated methods?

I have an issue using the JUnit4 @BeforeClass annotation in instrumented Android unit test (I'm using the Espresso GUI testing library). As soon as I add a test with the @BeforeClass annotation, Android Studio 1.5.1 does not run any tests at all but instead just prints "Empty test suite". I'm not using a test suite. I searched this site and the web but couldn't find a solution. I thought that it might be a problem that the code, which is called within the @BeforeClass method actually fails (TDD), but this error even occurs when code, which is working in normal test cases, is put in the @BeforeClass annotated method.

Thank you.

UPDATE: After checking the logcat output, as one commenter suggested, it seems that the problem is that the problem is that no activity was started: No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?

How should I do this? I can't use the ActivityTestRule field, as the @BeforeClass annotated method is static.

Maybe I'm just using the @BeforeClass annotation in a wrong way. My impression was that you can use this annotation to execute tests before all the other tests in the test class. I was basically looking for a replacement for the TestNG annotation "dependsOnMethods" here. Maybe I'm better off using the @FixMethodOrder(MethodSorters.NAME_ASCENDING) annotation on the test class and renaming the first test case to aaa_my_testcase.

Could somebody please comment on that? Thanks.

Rephrased the title of the question.

import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.not;


@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    @Rule
    public ActivityTestRule<MainActivity> menuActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    private static void checkSignBrowserIsDisplayed() {
        onView(withText(R.string.sign_browser)).check(matches(isDisplayed()));
    }

    @BeforeClass
    public static void checkSignBrowserIsDisplayedOnAppStartup() {
        checkSignBrowserIsDisplayed();
    }

build.app:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "foo"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            debuggable true
        }
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
}

dependencies {
    testCompile 'org.mockito:mockito-core:1.10.19'
    testCompile 'junit:junit:4.12'
    androidTestCompile 'junit:junit:4.12'
    androidTestCompile 'com.android.support:support-annotations:23.1.1'
    androidTestCompile 'com.android.support.test:runner:0.4.1'
    androidTestCompile 'com.android.support.test:rules:0.4.1'
    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
    // required if you want to use Mockito for Android instrumentation tests - not needed now.
    // androidTestCompile 'org.mockito:mockito-core:1.+'
    // androidTestCompile "com.google.dexmaker:dexmaker:1.2"
    // androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'org.apache.commons:commons-lang3:3.4'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

Test output:

Running tests

Test running startedFinish

Empty test suite.

Logcat output:

01-25 10:22:42.746 22098-22118/foo I/TestRunner: run started: 5 tests
01-25 10:22:42.764 22098-22118/foo D/InputManagerEventInjectionStrategy: Creating injection strategy with input manager.
01-25 10:22:42.890 22098-22118/foo I/TestRunner: failed: foo.MainActivityTest
01-25 10:22:42.890 22098-22118/foo I/TestRunner: ----- begin exception -----
01-25 10:22:42.891 22098-22118/foo I/TestRunner: java.lang.RuntimeException: No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?
                                                                                                   at android.support.test.espresso.base.RootViewPicker.waitForAtLeastOneActivityToBeResumed(RootViewPicker.java:189)
                                                                                                   at android.support.test.espresso.base.RootViewPicker.findRoot(RootViewPicker.java:134)
                                                                                                   at android.support.test.espresso.base.RootViewPicker.get(RootViewPicker.java:80)
                                                                                                   at android.support.test.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:69)
                                                                                                   at android.support.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:23)
                                                                                                   at android.support.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:9)
                                                                                                   at android.support.test.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:68)
                                                                                                   at android.support.test.espresso.ViewInteraction$2.run(ViewInteraction.java:166)
                                                                                                   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
                                                                                                   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                                   at android.os.Handler.handleCallback(Handler.java:739)
                                                                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                                   at android.os.Looper.loop(Looper.java:135)
                                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5312)
                                                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                                                   at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
                                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
01-25 10:22:42.891 22098-22118/foo I/TestRunner: ----- end exception -----
01-25 10:22:42.891 22098-22118/foo I/TestRunner: failed: Test mechanism
01-25 10:22:42.892 22098-22118/foo I/TestRunner: ----- begin exception -----
01-25 10:22:42.892 22098-22118/foo I/TestRunner: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.Bundle.putString(java.lang.String, java.lang.String)' on a null object reference
                                                                                                   at android.support.test.internal.runner.listener.InstrumentationResultPrinter.reportFailure(InstrumentationResultPrinter.java:183)
                                                                                                   at android.support.test.internal.runner.listener.InstrumentationResultPrinter.testFailure(InstrumentationResultPrinter.java:173)
                                                                                                   at org.junit.runner.notification.SynchronizedRunListener.testFailure(SynchronizedRunListener.java:63)
                                                                                                   at org.junit.runner.notification.RunNotifier$4.notifyListener(RunNotifier.java:142)
                                                                                                   at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72)
                                                                                                   at org.junit.runner.notification.RunNotifier.fireTestFailures(RunNotifier.java:138)
                                                                                                   at org.junit.runner.notification.RunNotifier.fireTestFailure(RunNotifier.java:132)
                                                                                                   at org.junit.internal.runners.model.EachTestNotifier.addFailure(EachTestNotifier.java:23)
                                                                                                   at org.junit.runners.ParentRunner.run(ParentRunner.java:369)
                                                                                                   at org.junit.runners.Suite.runChild(Suite.java:128)
                                                                                                   at org.junit.runners.Suite.runChild(Suite.java:27)
                                                                                                   at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
                                                                                                   at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
                                                                                                   at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
                                                                                                   at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
                                                                                                   at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
                                                                                                   at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
                                                                                                   at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
                                                                                                   at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
                                                                                                   at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
                                                                                                   at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:240)
                                                                                                   at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1928)
like image 756
Matthias T Avatar asked Jan 24 '16 21:01

Matthias T


People also ask

What is JUnit in Espresso?

JUnit is the de facto standard for unit testing a Java application. Even though, it is popular for unit testing, it has complete support and provision for instrumentation testing as well. Espresso testing library extends the necessary JUnit classes to support the Android based instrumentation testing.

What is espresso unit testing?

Espresso tests state expectations, interactions, and assertions clearly without the distraction of boilerplate content, custom infrastructure, or messy implementation details getting in the way. Espresso tests run optimally fast!


2 Answers

I had the same issue and it was only because of the Rule, you can set the activity to launch in rule's constructor:

@Rule
public ActivityTestRule<MainActivity> menuActivityTestRule = 
        new ActivityTestRule<>(MainActivity.class, true, true);

last argument is responsible for launching the activity.

like image 175
Kacper Wolkowski Avatar answered Nov 13 '22 07:11

Kacper Wolkowski


Hate to see this question unanswered.

So, for everyone who might be stumbling upon this:

My solution was to use the @FixMethodOrder(MethodSorters.NAME_ASCENDING) annotation on the test class and renaming the first test case to aaa_my_testcase.

See: MethodSorters, FixMethodOrder.

like image 35
Matthias T Avatar answered Nov 13 '22 08:11

Matthias T