【问题标题】:Is there a way to write a unit test for a target API有没有办法为目标 API 编写单元测试
【发布时间】:2015-12-30 15:35:20
【问题描述】:

我正在编写 Android 仪器测试,但 Robolectric 自定义阴影不足。

理想情况下,我们希望编写跨所有版本的 Android SDK 灵活的代码,但是我处于边缘情况,我需要为仅适用于 Marshmallow 的方法编写单独的单元测试。

由于操作系统依赖的差异(即 java.lang.NoClassDefFoundError's),我还需要编写一个仅适用于 Lollipop 及以下的单元测试

我是否可以通过类似 Junit4 的注释或类似于 Robolectric 所做的事情来做到这一点,如果 SDK 不合适,它可以忽略运行测试?

我不想写这样的代码:

// MarshmallowWidgetTest.java
@Test
public void testPrintName()
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    {
        // ...asserts...
    }
}

// LollipopWidgetTest.java
@Test
public void testPrintName()
{
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
    {
        // ...asserts...
    }
}

【问题讨论】:

    标签: android unit-testing robolectric android-instrumentation


    【解决方案1】:

    我对单元测试或 Robolectric 不是很熟悉,但因为在我编写单元测试时不支持 API 23,所以我使用了该配置:

    @RunWith(RobolectricGradleTestRunner.class)
    @Config(constants = BuildConfig.class, sdk = 21) //this guy
    public class MainActivityTest {
    
        MainActivity_ activity = Robolectric.setupActivity(MainActivity_.class);
    
    }
    

    就像您看到的那样,您可以将注释用于您的测试类。


    编辑:

    抱歉,我只关注Robolectric 测试框架,而不是主要问题。

    对于我将使用的特定 API 的仪器测试注释:

    1.带有@Before 注释的类

    创建一个带有@Before 注解的类,用于检查被测设备的API。如果错误,此方法中的测试将失败。使用fail();方法。

    2。使用@SdkSuppress注解

    表示特定测试或类需要最低 API 级别才能执行。

    在低于指定级别的 Android 平台上执行时将跳过测试。

    发件人:http://developer.android.com/reference/android/support/test/filters/SdkSuppress.html

    因此,如果您设置@SdkSuppress(minSdkVersion=23),它将仅在Android Marshmallow 设备上运行,而如果@@SdkSuppress(minSdkVersion=20),它将仅在更高版本的5.0 API 设备上运行。

    另请阅读:http://www.vogella.com/tutorials/AndroidTesting/article.html

    3.创建您自己的注释,例如 @SdkOnly

    也许这篇文章会有用:http://help.testdroid.com/customer/portal/articles/1256803-using-annotations-in-android-instrumentation-tests

    4.为您的特定仪器测试创建套件

    为此,您将使用@RunWith()Suites.SuiteClasses() 注释。

    要组织您的插桩单元测试的执行,您可以 在测试套件类中对一组测试类进行分组并运行这些 一起测试。测试套件可以嵌套;您的测试套件可以分组 其他测试套件并一起运行它们的所有组件测试类。

    测试套件包含在测试包中,类似于主包 应用程序包。按照约定,测试套件包名 通常以 .suite 后缀结尾(例如, com.example.android.testing.mysample.suite)。

    要为您的单元测试创​​建测试套件,请导入 JUnit RunWithSuite 类。在您的测试套件中,添加@RunWith(Suite.class)@Suite.SuitClasses() 注释。在@Suite.SuiteClasses() 注释,将各个测试类或测试套件列为 论据。

    以下示例展示了如何实现测试套件 名为 UnitTestSuite 的分组并运行 CalculatorInstrumentationTestCalculatorAddParameterizedTest 测试 一起上课。

    import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
    import com.example.android.testing.mysample.CalculatorInstrumentationTest;
    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;
    
    // Runs all unit tests.
    @RunWith(Suite.class)
    @Suite.SuiteClasses({CalculatorInstrumentationTest.class,
            CalculatorAddParameterizedTest.class})
    public class UnitTestSuite {}
    

    发件人:http://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html

    5.有用的资源

    希望对你有帮助

    【讨论】:

    • Config 也适用于方法
    • 是的,这不是正确的答案,因为我问的是 Android 仪器测试而不是 Roblectric JVM 单元测试。当我说“类似于 Robolectric 所做的事情,如果 SDK 不合适,它可以忽略运行测试”时,您的回答指的是我已经意识到的事情。理想的解决方案是使用 @RunWith(AndroidJUnit4. class) 测试运行器,而不是 @RunWith(RobolectricGradleTestRunner.class)
    • 我已经编辑了我的答案。我认为@SdkSupress 注释可能会帮助您解决问题;-)
    • 这绝对是我所需要的! SdkSuppress 没有出现在 Stackoverflow 的任何地方,所以这是新知识。感谢您的帮助!
    • 就像对尝试使用@SdkSupress 的任何其他人的附加说明一样,该注释仅适用于Android 仪器测试,即在/androidTest 下。它不会出现在 JVM Robolectric 测试中,即 /test
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多