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

时间:2015-04-30 13:49:21

标签: android-testing

我正在使用新的Android测试支持库(com.android.support.test:runner:0.2)来运行Instrumentation Tests (a.k.a设备或仿真器测试)。

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

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

InstrumentationRegistry.getContext()InstrumentationRegistry.getTargetContext()之间的区别是什么?

3 个答案:

答案 0 :(得分:33)

我在这里找到了答案:https://code.google.com/p/android-test-kit/wiki/AndroidJUnitRunnerUserGuide

  

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

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

修改

  

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

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

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

  1. 测试应用程序,用于执行测试逻辑并测试您的“真实”应用程序
  2. “真实”应用(您的用户会看到)
  3. 因此,在编写测试时,如果要加载真实应用的资源 ,请使用getTargetContext()

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

答案 1 :(得分:2)

您可能需要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);

答案 2 :(得分:2)

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

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的权限被拒绝。

事实证明,通过将上下文替换为检测上下文,我获得了一个我的应用无法访问的路径,我得到了FileNotFoundException permission denied而没有GrantTestRule或其他东西会工作

因此在使用这些背景时要小心,这可能会浪费你的时间:/