创建模拟Activity以进行测试的最快方法

Mis*_*ith 10 android unit-testing mocking android-activity

我目前正在对图书馆进行单元测试.在某些类中,我需要在一些静态方法中将活动作为参数传递.图书馆本身不包含任何活动.我需要以某种方式获取模拟活动的实例,以便在每个单独的方法测试中使用.

我已经阅读了Activity Testing TutorialTesting Fundamentals部分.如果你要测试已经存在于待测试项目中的活动,那么它的大部分内容才有意义.但我只需要一个模拟的东西,比如在Ui线程中显示对话框和运行短任务.

实现这一目标的最快,最简单的方法是什么?我应该在我的测试项目中创建模拟活动,还为虚拟UI提供xml布局资源?


更新
由于我没有找到任何自动创建模拟活动的方法,我决定自己提供.我在测试项目中创建了一个虚拟活动,什么都不做,并通过xml提供了一个虚拟布局.然后我编写了我的测试扩展ActivityInstrumentationTestCase2:

    public class LibraryTest extends ActivityInstrumentationTestCase2<MockActivity> {

        public LibraryTest(String name) {
            super(MockActivity.class);
        }

        protected void setUp() throws Exception {
            super.setUp();
        }

        public void testAMethodFromLibrary() {
            fail("Not yet implemented");
        }
    }
Run Code Online (Sandbox Code Playgroud)

MockActivity我在此测试项目中创建的上述模拟活动在哪里.但是,似乎Android测试框架在启动活动时遇到问题,并且它出现了这个异常:

        java.lang.RuntimeException: Exception during suite construction
        at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:239)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
        at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
        at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:520)
        at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
        Caused by: java.lang.NullPointerException: Method name must not be null.
        at java.lang.ClassCache.findMethodByName(ClassCache.java:297)
        at java.lang.Class.getMethod(Class.java:985)
        at android.test.suitebuilder.TestMethod.getAnnotation(TestMethod.java:60)
        at android.test.suitebuilder.annotation.HasMethodAnnotation.apply(HasMethodAnnotation.java:39)
        at android.test.suitebuilder.annotation.HasMethodAnnotation.apply(HasMethodAnnotation.java:30)
        at com.android.internal.util.Predicates$OrPredicate.apply(Predicates.java:106)
        at android.test.suitebuilder.annotation.HasAnnotation.apply(HasAnnotation.java:42)
        at android.test.suitebuilder.annotation.HasAnnotation.apply(HasAnnotation.java:31)
        at com.android.internal.util.Predicates$NotPredicate.apply(Predicates.java:122)
        at android.test.suitebuilder.TestSuiteBuilder.satisfiesAllPredicates(TestSuiteBuilder.java:254)
        at android.test.suitebuilder.TestSuiteBuilder.build(TestSuiteBuilder.java:190)
        at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:373)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4218)
        at android.app.ActivityThread.access$3000(ActivityThread.java:125)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:4627)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
        at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

现在我完全迷失在这里.怎么会这么复杂?我选择了正确的方法吗?我只想在测试方法中启动一个对话框.也许框架搞乱了,因为要测试的活动不在目标项目中?

这里的任何帮助将不胜感激.我已经没时间了,如果找不到合适的方法,我必须使用我的库创建第二个项目,在那里移动模拟活动并从测试项目进行测试.这是很多代码,因为我必须在(现在不是通用的)模拟活动中包含一个方法来调用我想要测试的每个库方法.

Nic*_*zzi 7

使用 androidX 库,您可以使用ActivityScenario. 只需androidTestImplementation("androidx.test:core:1.2.0")在您的 app.gradle 文件中导入

然后,在您的仪器测试中,使用以下命令导入ActivityScenario并启动活动:

import androidx.test.core.app.ActivityScenario

@Test
fun testActivity() {
    ActivityScenario.launch(MainActivity::class.java).onActivity { activity ->
        // do something with your activity instance
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是如何创建 Activity 的模拟的? (2认同)

Mis*_*ith 6

解决了!这是我所做的:

  • 在测试项目中,我删除了检测选项卡中的目标包,并再次添加它,指向测试项目基础包,即模拟活动所在的位置。
  • 在我的测试项目中添加了目标库作为 Android 库。(右键单击测试项目 -> 属性 -> Android -> 库 -> 添加目标库)。
  • 在测试项目清单中添加了模拟活动。
  • 为了解决我上面发布的异常,只需用这个替换测试用例构造函数:

        public LibraryTest() {
            super(MockActivity.class);
        }
    
    Run Code Online (Sandbox Code Playgroud)

现在可以了,我可以成功启动对话框。但在我的简短研究中,我偶然发现了Robotium。这个图书馆真是太棒了。我最初尝试做的事情不需要它,但我发现以自动化方式测试 GUI 非常有用。现在我在每次setUp通话中都重新创建了一个全新的活动。