代码之家  ›  专栏  ›  技术社区  ›  tir38

只有在应用程序100%完成检测后,才能正确清理/拆卸

  •  3
  • tir38  · 技术社区  · 7 年前

    我有一堆端到端的仪器测试(依赖于浓缩咖啡),开始我们的启动活动,然后在我们的应用程序中导航(最终创建几个活动)。结束时 每个 测试我们的 @After

    我们遇到的问题是,在测试完成(成功或失败的断言)之后,应用程序仍在“运行”,因此一些清理实际上导致了应用程序崩溃。如果断言成功,这将导致误报,或者隐藏测试失败(我们只看到崩溃而不是失败的断言)。

    下面是一个例子:

    import android.app.Instrumentation;
    import android.content.Intent;
    import android.preference.PreferenceManager;
    import android.support.test.InstrumentationRegistry;
    import android.support.test.rule.ActivityTestRule;
    
    import com.example.SplashActivity;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Rule;
    import org.junit.Test;
    
    import static android.support.test.InstrumentationRegistry.getInstrumentation;
    
    public class ExampleTest {
    
        @Rule
        public ActivityTestRule<SplashActivity> splashActivityTestRule
                = new ActivityTestRule<>(SplashActivity.class, true, false);
    
        Instrumentation.ActivityMonitor splashActivityMonitor;
    
        @Before
        public void setUp() {
            splashActivityMonitor = new Instrumentation.ActivityMonitor(SplashActivity.class.getName(), null, false);
            getInstrumentation().addMonitor(splashActivityMonitor);
        }
    
        @Test
        public void someTest() throws Exception {
            // ... other test-specific setup before starting splash activity
    
            // start first activity
            splashActivityTestRule.launchActivity(new Intent());
    
            // a bunch of espresso steps that result in several other activities
            // ... creating and adding Instrumentation.ActivityMonitor for each one
    
            // assert something
        }
    
        @After
        public void tearDown() {
            // clear shared prefs to prepare for next test
            PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext())
                    .edit()
                    .clear()
                    .apply();
    
            // At this point the app is still running. Maybe a UI is still loading that was not relevant to the test, 
            // or some mock web request is in flight. But at some point after the final assert in our test, the app needs
            // to get something from shared prefs, which we just cleared, so the app crashes.
        }
    }
    

    所以我怎么能断言这个应用已经死了 打扫卫生?

    每一个 测试。另外,如果断言失败,我也不确定这是否有效。

    或者在拆卸中执行某种应用程序终止:

    public void tearDown() {
        // finish all tasks before cleaning up
        ActivityManager activityManager =
                (ActivityManager) InstrumentationRegistry.getTargetContext().getSystemService(Context.ACTIVITY_SERVICE);
    
        List<ActivityManager.AppTask> appTasks = activityManager.getAppTasks();
        for (ActivityManager.AppTask appTask : appTasks) {
            appTask.finishAndRemoveTask();
        }
    
        // clear shared prefs to prepare for next test
        PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext())
                .edit()
                .clear()
                .apply();
    }
    

    我知道我可以用 ActivityTestRule.afterActivityFinished() docs 倍数

    2 回复  |  直到 6 年前
        1
  •  1
  •   denys    7 年前

    您描述的问题可以通过使用 AndroidTestOrchestrator . 从Android官方文档:

    使用时 AndroidJUnitRunner 1.0或更高版本,您可以访问 一个名为Android Test Orchestrator的工具,它允许您运行

    每次测试运行后,将自动清理正在测试的应用程序。

    build.gradle AndroidTestOrchestrator

    1. 使用 AndroidTestOrchestrator github link
    2. 使用 AndroidTestOrchestrator 使用AndroidX测试库- github link

    link .

        2
  •  0
  •   Martin Zeitler    7 年前

    b) 或者使用共享资源本身来防止竞争条件:

    public static final String PREFERENCE_KEY_TEST_COUNT = "testCount";
    public static final int MAX_TEST_COUNT = 6;
    
    @After
    public void tearDown() {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext()):
        if(prefs.getPreference(PREFERENCE_KEY_TEST_COUNT, 0) >= MAX_TEST_COUNT) {
            prefs.edit().clear().apply();
        } else {
            int testCount = prefs.getPreference(PREFERENCE_KEY_TEST_COUNT, 0) + 1;
            prefs.edit().putInt(PREFERENCE_KEY_TEST_COUNT, testCount).apply();
        }
    }
    

    Test Suite 还有习俗 Runner 可以用来控制测试;这个 example