标签: android-testing

Espresso如何测试活动是否完成?

我想声明我正在测试的我的Acitivty在执行某些操作时已完成.不幸的是到目前为止,我只是通过在测试结束时添加一些睡眠来断言它.有没有更好的办法 ?

import android.content.Context;
import android.os.Build;
import android.support.test.rule.ActivityTestRule;
import android.test.suitebuilder.annotation.LargeTest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import static org.junit.Assert.assertTrue;

@SuppressWarnings("unchecked")
@RunWith(JUnit4.class)
@LargeTest
public class MyActivityTest {

    Context context;

    @Rule
    public ActivityTestRule<MyActivity> activityRule
            = new ActivityTestRule(MyActivity.class, true, false);

    @Before
    public void setup() {
        super.setup();
        // ...
    }

    @Test
    public void finishAfterSomethingIsPerformed() throws Exception {

        activityRule.launchActivity(MyActivity.createIntent(context));

        doSomeTesting();

        activityRule.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                fireEventThatResultsInTheActivityToFinishItself();
            }
        });

        Thread.sleep(2000); // this is needed :(

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) …
Run Code Online (Sandbox Code Playgroud)

testing android android-activity android-testing android-espresso

23
推荐指数
4
解决办法
1万
查看次数

Android单元测试:如何清除SharedPreferences

我试图清除我测试期间添加的所有SharedPreferences.我已经阅读了一些帖子和官方文档(SharedPreferences.Editor.clear()).但是当我运行单元测试后启动应用程序时,我仍然找到了测试值.

所以,在AndroidTestCase.tearDown()中,我这样做:

public class PrivateStorageUtilsTest extends AndroidTestCase {

private static final String KEY_SP_PACKAGE = "PrivateStorageUtilsTest";

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

        // Clear everything in the SharedPreferences
        SharedPreferences sharedPreferences = getContext()
            .getSharedPreferences(KEY_SP_PACKAGE, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.commit();
    }

    protected void tearDown() throws Exception {
        // Clear everything in the SharedPreferences
        SharedPreferences sharedPreferences = getContext().
            getSharedPreferences(KEY_SP_PACKAGE, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.commit();
    }

}
Run Code Online (Sandbox Code Playgroud)

我在SO上发现的所有其他问题都是关于commit()clear()我已经完成的之后添加的问题.

编辑1添加setUp()方法 …

android unit-testing sharedpreferences android-testing

22
推荐指数
2
解决办法
1万
查看次数

如何使用gradle动态切换/更改testInstrumentationRunner

我的项目有两组不同的测试.一个组仅使用默认运行,另一个组AndroidJUnitRunner必须使用自定义实现运行TestRunner extends MonitoringInstrumentation.

目前我每次需要运行另一组测试时都会testInstrumentationRunner通过编辑来切换build.gradle:

android{
      defaultConfig {
          //testInstrumentationRunner "my.custom.TestRunner"
           testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
      }
}
Run Code Online (Sandbox Code Playgroud)

我知道口味可以有自己的味道,testInstrumentationRunner但我目前的应用程序已经有2个flavourDimensions.使用flavor实际上是为了拥有不同版本的app.我需要2个版本的测试应用程序,都使用不同的testInstrumentationRunners 测试相同的应用程序.

我尝试testInstrumentationRunner通过迭代所有测试变体来改变.实际上有多个testInstrumentationRunner属性:

android.testVariants.all { TestVariant variant ->
    //readonly
    variant.variantData.variantConfiguration.instrumentationRunner

    variant.variantData.variantConfiguration.defaultConfig.testInstrumentationRunner

}
Run Code Online (Sandbox Code Playgroud)

但是一旦android.testVariants调用,构建就会被配置,并且所有更改都不会反映在构建中.

如何动态更改testInstrumentationRunner(从gradle插件)?

我更喜欢有2个不同的gradle任务,每个任务使用不同的testInstrumentationRunner但是测试相同的变体.因为我打算创建一个gradle插件,所以解决方案也应该像插件一样工作.

android gradle android-testing android-gradle-plugin

22
推荐指数
3
解决办法
9365
查看次数

Android Studio Instrumentation测试构建变体

所以我试图使用自定义构建变体mock来编写测试测试.在这个构建变体中,我模拟了我的类和服务器.当我尝试使用模拟构建时,它工作正常,但我似乎无法使用我的模拟构建进行测试.这是我在Android Studio中的配置.

构建变体

我有一些问题让我的测试运行所以我试图卸载我的应用程序的所有版本,除了我的模拟版本,我不断收到此错误:

测试运行startedTest运行失败:无法找到检测目标包:com.teamtreehouse.review.debug

但是,当我尝试针对调试版本变体运行我的测试时,它工作正常.它安装我的调试版本然后继续运行测试.

android-testing android-studio android-espresso android-instrumentation

22
推荐指数
3
解决办法
7168
查看次数

什么是触摸模式?为什么它对*ActivityTestRule*类很重要?

android.support.test.rule.ActivityTestRule类(见这里)发生在一个initialTouchMode在其构造函数的参数.除了以下内容之外,在类引用(或任何在线)中没有解释这一点:

initialTouchMode - 如果在启动时应将Activity置于"触摸模式",则为true

"触摸模式"究竟是什么意思?什么是设置的影响initialTouchModeActivityTestRuletruefalse?(我看到这个参数的默认值是false).

android android-testing android-espresso android-instrumentation android-junit

22
推荐指数
1
解决办法
3673
查看次数

使用ant与库项目的Android单元测试

似乎最新的Android SDK工具仍然不能正确支持包含链接库项目的应用程序的测试.

我有一个项目,具有以下设置:

TestLib(android库项目)< - TestMain(android项目)< - TestMainTest(android单元测试项目)

我在eclipse中创建了所有这些项目,然后用于android update (test-/lib-)project ...生成build.xmlet.人.

一旦你在TestMain(InheritAddition.java在我的例子中)中有一个继承自TestLib(Addition.java)中的类并且你想在单元test(InheritAdditionTest.java)中引用这个类的类,问题就会开始.

TESTLIB

public class Addition {
    public int add2(int o1, int o2) {
      return o1 + o2;
    }
}
Run Code Online (Sandbox Code Playgroud)

TestMain

public class InheritAddition extends Addition {
    public int sub(int p1, int p2) {
        return p1 - p2;
    }
}
Run Code Online (Sandbox Code Playgroud)

TestMainTest

public class InheritAdditionTest extends AndroidTestCase {
    public void testSub() {
        Assert.assertEquals(2, new InheritAddition().sub(3, 1));
    }
}
Run Code Online (Sandbox Code Playgroud)

在命令行上构建时,结果如下:

W/ClassPathPackageInfoSource(14871): …

android unit-testing android-testing

21
推荐指数
2
解决办法
6688
查看次数

Android Espresso,测试前唤醒设备.如何使用自定义清单进行测试?

我一直在用androids新的espresso框架编写测试,并发现它运行良好.一个烦人的事情(特别是浓缩咖啡)是我必须确保我的屏幕醒来并解锁以便运行测试.我找到了一种解决方法(通过各种来源),但我不确定整合它的最佳方法.

所以这就是我所做的,在我的"Home"活动中,我有以下代码:

Home.class:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /************ Put this in a conditional for a test version ***********/
    KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG");
    keyguardLock.disableKeyguard();
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Run Code Online (Sandbox Code Playgroud)

您还需要添加以下权限:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Run Code Online (Sandbox Code Playgroud)

所以在这样做之后,我的测试现在唤醒我的手机运行所以我没有必须站岗并确保屏幕在测试开始之前没有关闭.

我宁愿不在我的应用程序中包含这些权限.我知道使用gradle可以制作具有自己的android清单的不同"风味",它将合并到主清单中.我正在考虑使用它,但我不想仅仅因为这个已经使用测试构建类型来运行而添加了一种风味.从android gradle文档看起来,您无法为instrumentTest目录创建AndroidManifest,因为它将自动生成.

但是,我想知道是否有另一种方法可以在不创建变量的情况下执行此操作,然后指定测试应该运行该变体.此外,我不确定所有这些的确切语法,并认为只是为了其他人在网站上有这些信息会很好,因为它似乎分散了.

最后,如果有人知道更好的方法来解决唤醒手机测试的问题,我很乐意听到它,因为我不是这种方式的忠实粉丝,我正在尝试.

android android-wake-lock android-testing android-espresso

21
推荐指数
5
解决办法
7962
查看次数

一种在多个android测试模块之间共享代码的方法

我希望实现这样的目标:

[ComponentTestsModule] com.android.test
[FunctionalTestsModule] com.android.test
both depends on
 -> [TestLibraryModule] ?
which depends on
   -> [AppModule] com.android.application
Run Code Online (Sandbox Code Playgroud)

用android gradle插件3.0+有没有办法做到这一点?

为什么我需要多个测试模块?

我想要不同类型的测试的不同测试运行器,也针对不同的变体.它现在正在使用单个代码库androidTest,但在自定义测试运行器中有丑陋的开关.

为什么我需要一个测试库模块?

我想在不同类型的测试之间共享相同的页面对象,也许是一些实用程序代码.问题是:页面对象必须能够访问R类的app(定位器:R.id.*)

我所知道的模块类型都不能依赖于APK生成模块,期望com.android.test,但我不能依赖于com.android.test另一个com.android.test.

android android-testing android-gradle-plugin android-instrumentation

21
推荐指数
2
解决办法
612
查看次数

MockK - 左侧匹配器的匹配模拟签名失败:[any(), any()]

我想实现一些 UI 测试,以确保今天实现的代码明天也能正常工作,但是当尝试查看过去实现的 UI 测试是否有效时,它会抛出此错误:

Caused by: io.mockk.MockKException: Failed matching mocking signature for left matchers: [any(), any()]

这种情况发生在every {} return Unit有一个名为 WakeUpTimeManager 的对象文件的行上,该文件调用 .set(param1, param2)函数,并且在该函数内部有一些内联函数,我认为这可能会导致问题,但我不知道。我尝试在互联网上搜索但找不到解决方案。

这是引发错误的测试:

  @Before
  fun setup() {
    mockkObject(WakeUpTimerManager)
    every { WakeUpTimerManager.set(any(), any()) } returns Unit
  }
Run Code Online (Sandbox Code Playgroud)

every这是在线调用的函数

  fun set(context: Context, timer: Timer) {
    if (timer.atMillis < System.currentTimeMillis()) {
      return
    }

    if (Preset.findByID(context, timer.presetID) == null) {
      return
    }

    //This is an inline function
    withGson {
      PreferenceManager.getDefaultSharedPreferences(context).edit {
        putString(PREF_WAKE_UP_TIMER, …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-testing mockk

21
推荐指数
2
解决办法
3万
查看次数

不推荐使用espresso contrib的openDrawer

com.android.support.test.espresso:espresso-contrib:2.2.1不推荐使用Espresso contrib()openDrawer方法

那怎么我打开一个抽屉?

android automated-tests open-source android-testing android-espresso

20
推荐指数
1
解决办法
4304
查看次数