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

vs91vp4v  于 2023-06-20  发布在  Android
关注(0)|答案(4)|浏览(159)

我正在使用新的Android测试支持库(com.android.support.test:runner:0.2)来运行仪器测试(也称为设备或模拟器测试)。
我用@RunWith(AndroidJUnit4.class)注解我的测试类,并使用Android Studio来运行它们。
对于我的测试用例,我需要一个Context示例。我可以用InstrumentationRegistry得到它,但它有两个上下文相关的方法,不清楚有什么区别。
InstrumentationRegistry.getContext()InstrumentationRegistry.getContext()有什么区别?InstrumentationRegistry.getTargetContext()

h4cxqtbf

h4cxqtbf1#

我花了好几个小时才发现。
InstrumentedTest用例有一个上下文成员,它在设置中被设置为:

context = InstrumentationRegistry.getTargetContext();

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

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

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

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或其他东西可以工作。
所以在使用这些上下文时要小心,它可能会浪费你的时间:/

vybvopom

vybvopom2#

很简单当你进行仪器测试时,会安装两个应用程序。
1.目标应用:您要测试的应用程序[您的应用程序]
1.测试应用程序:具有您的测试逻辑的应用程序。
在Kotlin的世界里
getInstrumentation().context返回测试应用的上下文getInstrumentation().targetContext返回目标应用的上下文。

z18hc3ub

z18hc3ub3#

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

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

那么什么时候使用getContext()和getTargetContext()呢?
文档并没有很好地解释这些差异,所以下面是我的观点:
你知道,当你在Android上进行仪器测试时,你有两个应用程序:
1.测试应用程序,执行您的测试逻辑并测试您的“真实的”应用程序
1.“真实的的”应用程序(您的用户将看到)
因此,当您编写测试并希望加载真实的应用的资源时,请使用getTargetContext()
如果您想使用测试应用 * 的资源(例如一个测试的测试输入),然后调用getContext()

dxxyhpgq

dxxyhpgq4#

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

相关问题