如何在 Android Studio 中创建测试?

Posted

技术标签:

【中文标题】如何在 Android Studio 中创建测试?【英文标题】:How can I create tests in Android Studio? 【发布时间】:2013-05-11 06:51:34 【问题描述】:

刚刚下载了基于 Intellij Idea 的 android Studio。

如何创建测试?

我注意到有一个创建测试模块的选项,但这似乎没有任何作用,只能使用 src 创建一个新项目

我还尝试按下热键 CTRL+AlT+T,它允许在现有类上创建单元测试,但它似乎想将它放在当前项目中。当然这对 TDD 没有帮助

有人在这里有经验吗?

【问题讨论】:

我也尝试过创建一个测试项目。如果您像使用 Eclipse 项目一样使用 Android 命令行工具执行此操作,则会出现错误,因为它找不到 AndroidManifest.xml 文件。谷歌似乎需要更新他们的 Android 工具来处理 Grundle 项目。但是,我是在 Android 中进行测试的新手,所以我无法帮助您 =( 【参考方案1】:

其中一个重大变化似乎是使用 Android Studio 将测试应用程序集成到应用程序项目中。

我不确定这是否有助于解决您的具体问题,但我找到了使用 Gradle 项目进行测试的指南。 Android Gradle user Guide

【讨论】:

【参考方案2】:

编辑:截至0.1.8 this is now supported in the IDE。请按照其中的说明进行操作,而不是使用下面的说明。

按照Android Gradle Plugin User Guide,我能够通过对新创建的项目执行以下步骤(我使用默认的“com.example.myapplication”包)在命令行上进行测试:

    为测试添加一个 src/instrumentTest/java 目录 在包com.example.myapplication.test中添加一个测试类(扩展ActivityTestCase) 启动虚拟设备 在命令行(在 MyApplicationProject/MyApplication 目录中)使用命令“../gradlew connectedInstrumentTest”

这会运行我的测试并将测试结果放在 MyApplicationProject/MyApplication/build/reports/instrumentTests/connected 中。我是测试 Android 应用程序的新手,但它似乎运行良好。

在 IDE 中,可以尝试运行相同的测试类。你需要

    更新 build.gradle 以将 Maven Central 列为存储库 更新 build.gradle 添加 JUnit 3.8 作为 instrumentTestCompile 依赖项,例如instrumentTestCompile 'junit:junit:3.8' 在“项目结构”中手动将 JUnit 移动到依赖顺序的首位

但是这会失败(运行测试时使用的类路径缺少测试输出目录)。但是,我不确定这是否可行,因为我的理解是需要 Android 特定的测试运行器。

【讨论】:

【参考方案3】:

我建议使用 gradle.build 文件。

    为测试添加一个src/androidTest/java目录(就像Chris开始解释)

    打开 gradle.build 文件并在其中指定:

    android 
    
        compileSdkVersion rootProject.compileSdkVersion
        buildToolsVersion rootProject.buildToolsVersion
    
        sourceSets 
    
            androidTest 
                java.srcDirs = ['androidTest/java']
            
        
    
    

    按“将项目与 Gradle 文件同步”(在顶部面板中)。您现在应该看到文件夹“java”(在“androidTest”内)是绿色的。

    现在您可以在那里创建任何测试文件并执行它们。

【讨论】:

别忘了 androidTest.setRoot('instrumentTest') 在当前的 Android Studio 版本中,没有必要,更重要的是 - 将所有名称为 instrumentTest 的内容替换为 androidTest 名称“instrumentTest”和“androidTest”完全是任意的。它们只是您的测试项目的目录名称。您也可以创建一个“测试”目录。另外,SDK在测试框架中的包名是android.test.InstrumentationTestCase。因此,我认为“仪器”或“仪器”对于命名一个测试仍然有意义。请参阅以下源代码:grepcode.com/file/repository.grepcode.com/java/ext/… 请阅读此处的文档:tools.android.com/tech-docs/new-build-system。自 0.9.0 版起,instrumentTest 更名为 androidTest @IgorGanapolsky 将文件夹命名为 androidTest 不是任意的。必须这样做才能使文件夹变为绿色。【参考方案4】:

我认为 Rex St John 的 this post 对于使用 android studio 进行单元测试非常有用。

(来源:rexstjohn.com)

【讨论】:

【参考方案5】:

到目前为止(工作室 0.61)保持适当的项目结构就足够了。 无需像在 eclipse 中那样创建单独的测试项目(见下文)。

【讨论】:

【参考方案6】:

Android Studio 一直是一个不断变化的目标,最初是开发者预览版,现在处于测试阶段。 项目中测试类的路径随着时间的推移发生了变化,但无论您使用什么版本的 AS,该路径都在您的 .iml 文件中声明。目前,在 0.8.3 版本中,您会在内部 iml 文件中找到以下内容:

      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/groovy" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />

.iml 文件告诉您将测试类放在哪里。

【讨论】:

【参考方案7】:

从 Android Studio 1.1 开始,我们为编写单元测试提供了官方(实验性)支持(Roboelectric 也可以)。

来源:https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support

【讨论】:

对编写Android测试的支持,刚刚得到增强,新的支持测试库。你可以在这里看到一个很好的演示:docs.google.com/presentation/d/…【参考方案8】:

Android Studio 不断发展,因此上述响应最终将不再适用。对于当前版本的 Android Studio 1.2.1.1,有一个很好的测试教程:

http://evgenii.com/blog/testing-activity-in-android-studio-tutorial-part-1/

【讨论】:

是的,AS 一直在发展,所以有人写一篇关于尖端技术的文章,却从不提及它适用的版本号是相当愚蠢的。唯一的线索是最底部的日期。【参考方案9】:

我找到的最简单的方法是my following blog post中的精简:

    创建一个文件夹,您将在其中编写所有单元测试(最好是 com.example.app.tests) 创建一个新的测试类(最好是 NameOfClassTestedTests,即 BankAccountLoginActivityTests) 扩展 InstrumentationTestCase 编写失败的单元测试以确保我们成功配置单元测试 请注意,单元测试方法名称必须以单词“test”开头(最好是 testTestedMethodNameExpectedResult(),即 testBankAccountValidationFailedShouldLogout()) 为单元测试配置您的项目: 打开“运行...”菜单并单击“编辑配置” 点击 + 按钮 选择 Android 测试模板 输入运行配置的名称(最好是“AppName Tests”) 在模块组合框中选择您的应用 选择“All In Package”单选按钮(通常您会希望选择此选项,因为它会在您的所有测试类中运行所有单元测试) 填写步骤 1 中的测试包名称(即 com.example.app.tests) 选择您希望在其上运行测试的设备 应用并保存配置 运行单元测试(预计会失败): 从“运行”菜单中选择新创建的测试配置 单击运行并在输出控制台中读取结果

祝您的代码更具可读性、可维护性和经过良好测试!

【讨论】:

问题是关于仪器测试的!我也很难编写一些仪器测试。在***.com/questions/35426990/… 看到我的问题【参考方案10】:

在 gradle 文件中的 lib 下面添加

 androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', 
        exclude group: 'com.android.support', module: 'support-annotations'
    )

在 androidTest 目录中创建类 HomeActivityTest 并在运行测试之前在字符串资源文件中添加 flurry_api_key 和 sender_id 字符串并更改失败和成功案例的值。

@RunWith(AndroidJUnit4.class)
public class HomeActivityTest

    private static final String SENDER_ID = "abc";
    private static final String RELEASE_FLURRY_API_KEY = "xyz";

    @Test
    public void gcmRegistrationId_isCorrect() throws Exception
    
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        Assert.assertEquals(SENDER_ID, appContext.getString(R.string.sender_id));
    

    @Test
    public void flurryApiKey_isCorrect() throws Exception
    
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        Assert.assertEquals(RELEASE_FLURRY_API_KEY, appContext.getString(R.string.flurry_api_key));
    

【讨论】:

【参考方案11】:

此答案适用于刚开始进行 Android 测试的人。我将提供两个简单的示例来帮助您了解测试的工作原理。如果您在接下来的 10 分钟内继续进行,您将准备好开始将测试添加到您自己的应用程序中。我想你会惊讶于它是多么容易。我当然是。

Android 测试简介

您将进行两种不同类型的测试。

本地单元测试。 这些测试在 JVM(Java 虚拟机)上本地运行。由于它们是本地的,因此速度很快。您可以使用它们来测试只需要 Java 而不需要 Android API 的代码部分。 (有时您可以制作一个虚假的 API 对象来在本地测试更多内容。这称为 mocking。模拟 Context 就是一个示例。) 仪器测试。这些测试在真实设备或模拟器中运行。这使得它们比本地测试慢。但是,它们更灵活,因为您可以使用完整的 Android API。

创建一个新项目,您将看到以下默认文件夹。

一切都已经存在,等待您创建测试。都已经设置好了!

如何创建本地单元测试

打开上图中显示的ExampleUnitTest 文件。它应该看起来像这样:

public class ExampleUnitTest 
    @Test
    public void addition_isCorrect() throws Exception 
        assertEquals(4, 2 + 2);
    

按绿色双箭头运行所有测试,或按绿色单箭头仅运行一个。 (在这种情况下,只有一个测试,所以它们都做同样的事情。)

它应该通过(当您阅读此答案时,只要2 + 2 仍然是4)。恭喜,您刚刚进行了第一次测试!

进行自己的测试

让我们编写自己的测试。首先将此类添加到您的主应用程序项目中,以便我们进行一些测试:

public class MyClass 
    public int add(int a, int b) 
        return a + b;
    

现在将测试类中的addition_isCorrect() 方法更改为如下代码(或者只是添加另一个名称不同的方法):

public class ExampleUnitTest 
    @Test
    public void addition_isCorrect() throws Exception 
        MyClass myClass = new MyClass();
        int result = myClass.add(2, 2);
        int expected = 4;
        assertEquals(expected, result);
    

再次运行它,您应该会看到它通过了。恭喜,您刚刚创建了自己的第一个测试! (好吧,从技术上讲,我猜它是我的,但是,嘿,足够接近了。我的就是你的。)

如何创建插桩测试

打开ExampleInstrumentedTest 文件。它应该看起来像这样:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest 
    @Test
    public void useAppContext() throws Exception 
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.example.myapp", appContext.getPackageName());
    

再次按下其中一个绿色按钮。

只要您连接了真实设备或设置了模拟器,它就应该已启动并运行您的应用程序。恭喜,您刚刚运行了您的第一个仪器测试!

进行自己的测试

插桩测试使用Espresso 运行测试。它有点像你自己的小机器人用户,你可以测试你的应用程序。你可以告诉它做一些事情,比如按下按钮或读取 TextView 的属性。

您可以编写有关如何手动进行测试的说明,但由于我们才刚刚开始,让我们使用auto-record function。超级简单。

首先在您的 UI 中添加一个按钮,以便我们可以使用。我这样做了:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context="com.example.myapp.MainActivity">

    <Button
        android:id="@+id/myButton"
        android:text="Click me"
        android:layout_
        android:layout_/>

</android.support.constraint.ConstraintLayout> 

然后按菜单中的运行 > 录制 Espresso 测试

启动后,单击模拟器中的按钮,然后在“录制”对话框中选择“确定”完成。它应该会自动生成以下测试代码。

@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest 

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

    @Test
    public void mainActivityTest() 
        ViewInteraction appCompatButton = onView(
                allOf(withId(R.id.myButton), withText("Click me"), isDisplayed()));
        appCompatButton.perform(click());
    

太棒了!您刚刚创建了您的第一个仪器测试!那非常容易。您可能应该添加一个断言以使其成为真正的测试,但这也很容易使用记录器来完成。观看this video 以更深入地了解。

进一步研究

我会先观看视频,然后通读文档。这一切都非常有帮助。最后一个链接是一系列文章,其中涵盖了在选择测试内容时要考虑的一些重要事项。

Android Testing Patterns(来自 Android 开发者的短视频系列) Getting Started with Testing(Android 文档) Three Steps to Code Quality via TDD

【讨论】:

很好的答案@Suragch。快速提问:我会将本地单元测试用例的支持文件放在哪里?这很 hacky,但我很乐意将完整路径放在测试的基础上,但如果我在 Android Studio 中运行,测试将从 root_/app 运行,但是如果我从 Gradle 命令行运行 (或 CI) 那么它就是 _root。 (理想情况下,无论以哪种方式运行,我都想访问特定的 assets 文件夹)。 @mm2001,我写这个答案是为了学习如何进行自己的测试,所以我什至还没有达到你的水平。如果你在我做之前弄清楚了,你能发表评论吗? 我发现这很有用:***.com/a/42751502/19506 - 它说创建一个文件夹 test/resources 并将文件放在那里,例如test.txt 并使用 getClass().getClassLoader().getResource("test.txt") 访问它们。我已经决定直接访问 APK 资产可能是个坏主意,因此我将通过复制文件以在构建步骤或外部更新过程中进行测试来解决这个问题。关于 Gradle 的不同版本还有一些问题,但我还没有遇到过。【参考方案12】:

Android Studio v.2.3.3

突出显示您要测试的代码上下文,并使用热键:CTRL+SHIFT+T

使用对话框界面完成设置。

测试框架应该反映您的项目包布局以获得最佳结果,但您可以手动创建自定义测试,前提是您具有正确的目录和构建设置。

【讨论】:

以上是关于如何在 Android Studio 中创建测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android Studio 1.4 中创建横向布局

如何在 Android Studio 中创建自定义图像按钮?

如何在 Android Studio 中创建动态 ListView

如何在 android studio 中创建没有主要活动的应用程序?

如何在 Kotlin 中创建一个打开新活动(Android Studio)的按钮?

如何在Android Studio中创建入门芯片填充?