繁体   English   中英

getTargetContext()和getContext(在InstrumentationRegistry上)之间有什么区别?

[英]What's the difference between getTargetContext() and getContext (on InstrumentationRegistry)?

我正在使用新的Android测试支持库( com.android.support.test:runner:0.2 )来运行Instrumentation Tests(aka Device或Emulator Tests)。

我使用@RunWith(AndroidJUnit4.class)注释我的测试类,并使用Android Studio来运行它们。

对于我的测试用例,我需要一个Context实例。 我可以通过InstrumentationRegistry获得它,但它有两个与上下文相关的方法,并不清楚它们之间的区别。

InstrumentationRegistry.getContext()InstrumentationRegistry.getTargetContext()什么区别?

InstrumentationRegistry是一个公开的注册表实例,它包含对进程中运行的检测的引用及其参数,并允许注入以下实例:

  • InstrumentationRegistry.getInstrumentation()返回当前正在运行的Instrumentation。
  • InstrumentationRegistry.getContext()返回此Instrumentation包的Context。
  • InstrumentationRegistry.getTargetContext() ,返回目标应用程序的应用程序上下文。
  • InstrumentationRegistry.getArguments()返回传递给此Instrumentation的参数Bundle的副本。 当您想要访问为测试传递给Instrumentation的命令行参数时,这非常有用。

编辑:

那么何时使用getContext()vs getTargetContext()?

文档在解释差异方面做得不是很好,所以这里来自我的POV:

您知道,当您在Android上进行仪器测试时,您有两个应用程序:

  1. 测试应用程序,执行您的测试逻辑并测试您的“真实”应用程序
  2. “真实”应用(您的用户会看到)

因此,当您编写测试并希望加载真实应用程序的资源时,请使用getTargetContext()

如果您想使用测试应用程序的资源(例如,您的某个测试的测试输入),请调用getContext()

您可能需要InstrumentationRegistry.getContext()来访问测试用例的原始资源。

例如,要在TestCase中访问app/src/androidTest/res/raw/resource_name.json

final Context context = InstrumentationRegistry.getContext(); InputStream is = context.getResources().openRawResource(com.example.package.test.R.raw.resource_name);

花了我几个小时才找到它。

InstrumentedTest案例有一个上下文成员,它在设置中设置如下:

context = InstrumentationRegistry.getTargetContext();

这用于打开文件,尤其是这样的东西:

String filenameOriginal = context.getCacheDir() + "/initial.csv";

现在我决定我需要使用一些在检测测试中可用的资源,我不想在发布版本中分发此资源。 因此,我重新创建了测试中的资源目录:

app\src\androidTest
└───res
    └───raw
            v1.csv

但是为了能够在代码中使用它,我不得不调用这样的东西:

    public static Uri resourceToUri(Context context, int resID)
    {
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                context.getResources().getResourcePackageName(resID) + '/' +
                context.getResources().getResourceTypeName(resID) + '/' +
                context.getResources().getResourceEntryName(resID));
    }

    resourceToUri(context, R.raw.v1)

总是会失败,因为R.raw.v1恰好与主应用程序中我的R资源文件中的内容相对应。 通过使用检测测试中的资源,生成了两个R文件。 要解决这个问题,我必须包含测试R文件:

import com.my_thing.app.my_app.test.R;

然后, resourceToUri调用将失败。

问题是,我不能使用InstrumentationRegistry.getTargetContext()而是使用InstrumentationRegistry.getInstrumentation().getContext()来获取R.raw.v1的资源,所以我盲目地替换整个测试类的上下文设置至

context = InstrumentationRegistry.getInstrumentation().getContext();

它适用于特定测试,但测试用例中的其他测试开始失败,并且我在上面使用的filenameOriginal被拒绝了。

事实证明,通过将上下文替换为检测上下文,我获得了一个我的应用程序无法访问的路径,并且我获得了FileNotFoundExceptionpermission denied并且没有GrantTestRule或其他东西可以工作。

所以在使用这些上下文时要小心,这可能会让你的时间变得紧张:/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM