简体   繁体   English

是否可以在 @BeforeClass 注释方法中运行 Android Espresso 单元测试?

[英]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).我在仪表化 Android 单元测试中使用JUnit4 @BeforeClass注释时遇到问题(我正在使用Espresso GUI 测试库)。 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".只要我添加带有@BeforeClass注释的测试, Android Studio 1.5.1就根本不会运行任何测试,而只会打印“空测试套件”。 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.我认为在@BeforeClass方法中调用的代码实际失败(TDD)可能是一个问题,但是当将在正常测试用例中工作的代码放入@BeforeClass注释方法中时,甚至会发生此错误.

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.更新:检查 logcat 输出后,正如一位评论者所建议的那样,问题似乎是没有启动任何活动:找不到活动。 Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?您是否忘记通过调用getActivity()startActivitySync或类似方法来启动活动?

How should I do this?我应该怎么做? I can't use the ActivityTestRule field, as the @BeforeClass annotated method is static.我不能使用ActivityTestRule字段,因为@BeforeClass注释方法是静态的。

Maybe I'm just using the @BeforeClass annotation in a wrong way.也许我只是以错误的方式使用了@BeforeClass注释。 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.我基本上是在这里寻找 TestNG 注释"dependsOnMethods"的替代品。 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 .也许我最好在测试类上使用@FixMethodOrder(MethodSorters.NAME_ASCENDING)注释并将第一个测试用例重命名为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:构建.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)

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.最后一个参数负责启动活动。

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 .我的解决方案是在测试类上使用@FixMethodOrder(MethodSorters.NAME_ASCENDING)注释并将第一个测试用例重命名为aaa_my_testcase

See: MethodSorters , FixMethodOrder .请参阅: MethodSortersFixMethodOrder

I was having the same issue because i was testing standalone fragments not an activity, I have created FragmentTestRule extending ActivityTestRule .我遇到了同样的问题,因为我测试的是独立片段而不是活动,我创建了扩展ActivityTestRuleFragmentTestRule And i have to call launchActivity() method in every test.而且我必须在每次测试中调用launchActivity()方法。

@Test
 public void recyclerViewItemClickTest() {

        mFragmentTestRule.launchActivity(null);
}

The @Rule causes the activity to start before each separate @Test. @Rule 使活动在每个单独的@Test 之前启动。 To use Espresso in a static @BeforeClass initialization method, first start the activity explicitly using ActivityScenario.要在静态 @BeforeClass 初始化方法中使用 Espresso,首先使用 ActivityScenario 显式启动活动。

@BeforeClass
public static void createTestData() {
    ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);
    onView(withId(R.id.calibrationsButton)).perform(click());
    sharedCalibrationName = Utils.addTestCalibration(PREFIX, "200");
    scenario.close();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为用@Circuitbreaker 注释的方法创建单元测试 - How to create unit tests for methods annotated with @Circuitbreaker 仅在以调试模式启动单元测试时才运行特定的@BeforeClass吗? - Run specific @BeforeClass only when starting unit tests in debug mode? 无法为Android运行espresso测试 - Unable to run espresso tests for android 在使用Android Studio保存时运行单元测试 - Run unit tests on Save with Android Studio 如何为Android运行单元测试不在设备或模拟器上? - How to run unit tests for Android is not on the device or emulator? 带有片段的Android Espresso功能测试 - Android Espresso functional tests with fragments TestNG 重试类不运行 @BeforeClass 也不 @AfterClass 方法 - TestNG retry class doesn't run @BeforeClass nor @AfterClass methods TestNG失败时重新运行测试,而不运行BeforeClass AfterClass方法 - TestNG Re run test on failure, not running BeforeClass AfterClass methods 是否可以使用 Mockito 运行 Espresso 测试(不带匕首)? - Is running Espresso tests with Mockito possible (without dagger)? 在单个事务中运行spring @Transactional注释方法 - Run spring @Transactional annotated methods in a single transaction
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM