如何在Android Studio中创建测试?


109

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

一个人将如何创建测试?

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

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

有人在这里有经验吗?


2
我也曾尝试创建一个测试项目。如果像使用Eclipse项目一样使用Android命令行工具进行操作,则会收到错误消息,因为它找不到AndroidManifest.xml文件。看来Google需要更新其Android工具来处理Grundle项目。但是,我是Android设备测试的新手,所以我不能帮您=(
Kage

Answers:


56

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

Android测试简介

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

  • 本地单元测试。它们在JVM(Java虚拟机)上本地运行。由于它们是本地的,因此速度很快。您可以使用它们来测试只需要Java而不需要Android API的代码部分。(有时你可以做一个假API对象在本地测试更多的事情。这就是所谓的嘲讽。有模拟的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的属性。

您可以编写有关如何手动进行测试的说明,但是由于我们刚开始,因此请使用自动记录功能。非常简单。

首先,在您的用户界面中添加一个按钮,以便我们进行一些操作。我这样做:

<?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_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.myapp.MainActivity">

    <Button
        android:id="@+id/myButton"
        android:text="Click me"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</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());
    }
}

大!您刚刚创建了第一个测试仪器!那太容易了。您可能应该添加一个断言以使其成为真正的测试,但是使用记录器也很容易做到。观看这部影片,进一步了解。

进一步研究

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


1
好答案@Suragch。快速提问:我将把本地单元测试用例的支持文件放在哪里?它很hacky,但是我很乐意从测试的基础开始完整的路径,但是如果我在Android Studio中运行,则测试将从root_/app运行,但是如果我从Gradle命令行(或CI)运行,那么它是_root。(理想情况下,assets无论哪种运行方式,我都想访问特定的文件夹)。
mm2001

@ mm2001,我写这个答案是一种学习如何自我测试的方法,所以我什至还没有达到你的水平。如果您先找出答案,可以发表评论吗?
苏拉奇

我发现这很有用:stackoverflow.com/a/42751502/19506-它说创建一个文件夹test/resources并将文件放在这里,例如,test.txt并使用进行访问getClass().getClassLoader().getResource("test.txt")。我认为直接访问APK资产可能不是一个好主意,因此我将通过复制文件以在构建步骤中进行测试或在外部更新过程中进行处理。关于Gradle的不同版本,仍然存在一些问题,但是我还没有遇到过。
mm2001

36

编辑:从0.1.8开始,IDE现在支持此功能。请按照此处的说明进行操作,而不要使用以下说明。

遵循《Android Gradle插件用户指南》,通过对新创建的项目执行以下步骤,我能够在命令行上进行测试(我使用了默认的'com.example.myapplication'包):

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

这运行了我的测试,并将测试结果放置在MyApplicationProject / MyApplication / build / reports / instrumentTests / connected中。我是测试Android应用程序的新手,但似乎工作正常。

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

  1. 更新build.gradle以将Maven Central列为仓库
  2. 更新build.gradle,将JUnit 3.8添加为instrumentTestCompile依赖项,例如instrumentTestCompile'junit:junit:3.8'
  3. 在“项目结构”中,手动将JUnit移至依赖关系顺序的第一位

但是,这将失败(运行测试时使用的类路径缺少测试输出目录)。但是,我不确定这是否行得通,因为据我了解,需要特定于Android的测试运行程序。


20

我建议使用gradle.build文件。

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

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

    android {
    
        compileSdkVersion rootProject.compileSdkVersion
        buildToolsVersion rootProject.buildToolsVersion
    
        sourceSets {
    
            androidTest {
                java.srcDirs = ['androidTest/java']
            }
        }
    }
  3. 按下“使用Gradle文件同步项目”(位于顶部面板)。您现在应该看到文件夹“ java”(在“ androidTest”内部)为绿色。

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


别忘了androidTest.setRoot('instrumentTest')
IgorGanapolsky

3
在当前的Android Studio版本中,没有必要做更多的工作- 用androidTest替换所有名称为instrumentTest东西
Yuriy Chernyshov

名称“ instrumentTest”和“ androidTest”完全是任意的。它们只是您的测试项目的目录名称。您也可以创建一个“ tests”目录。此外,测试框架中SDK的软件包名称为android.test.InstrumentationTestCase。因此,规范地说,我相信“仪器”或“仪器”对于命名测试仍然有意义。请参阅下面的源代码:grepcode.com/file/repository.grepcode.com/java/ext/...
IgorGanapolsky

7
请在此处阅读文档:tools.android.com/tech-docs/new-build-system。从0.9.0版开始,instrumentTest被重命名为androidTest
Yuriy Chernyshov

1
@IgorGanapolsky命名为androidTest的文件夹不是任意的。为了使文件夹变为绿色,必须完成此操作。
Clocksmith


10

Android Studio v.2.3.3

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

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

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


7

截至目前(工作室0.61),保持适当的项目结构就足够了。无需像Eclipse中一样创建单独的测试项目(请参见下文)。

测试结构



3

似乎发生的主要变化之一是,使用Android Studio将测试应用程序集成到了应用程序项目中。

我不确定这是否对您的特定问题有所帮助,但是我找到了有关使用Gradle项目进行测试的指南。 Android Gradle用户指南


3

我发现的最简单的方法是简化我的以下博客文章

  1. 创建一个文件夹,您将在其中编写所有单元测试(最好是com.example.app.tests)
  2. 创建一个新的测试类(最好是NameOfClassTestedTests,即BankAccountLoginActivityTests)
  3. 扩展InstrumentationTestCase
  4. 编写失败的单元测试,以确保我们成功配置了单元测试
  5. 请注意,单元测试方法的名称必须以单词“ test”开头(最好是testTestedMethodNameExpectedResult(),即testBankAccountValidationFailedShouldLogout())。
  6. 配置项目以进行单元测试:
  7. 打开“运行...”菜单,然后单击“编辑配置”
  8. 点击+按钮
  9. 选择Android测试模板
  10. 输入您的运行配置的名称(最好是“ AppName测试”)
  11. 在模块组合框中选择您的应用
  12. 选择“全部打包”单选按钮(通常要选择此选项,因为它会运行所有测试类别中的所有单元测试)
  13. 填写步骤1中的测试包名称(即com.example.app.tests)
  14. 选择您要在其上运行测试的设备
  15. 应用并保存配置
  16. 运行单元测试(并期望失败):
  17. 从“运行”菜单中选择新创建的“测试”配置
  18. 单击运行,然后在输出控制台中读取结果

祝您好运,使您的代码更具可读性,可维护性和测试性!


问题是关于仪器测试!我也很难编写一些仪器测试。请参阅我的问题在stackoverflow.com/questions/35426990/…–
Monica

2

Android Studio一直是一个移动的目标,首先是开发人员预览,现在是beta。项目中Test类的路径在一段时间内已更改,但是无论您使用的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文件告诉您放置测试类的位置。



0

在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));
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.