简体   繁体   English

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

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

I'm using the new Android Testing Support Library ( com.android.support.test:runner:0.2 ) to run Instrumentation Tests (aka Device or Emulator Tests). 我正在使用新的Android测试支持库( com.android.support.test:runner:0.2 )来运行Instrumentation Tests(aka Device或Emulator Tests)。

I annotate my test class with @RunWith(AndroidJUnit4.class) and use Android Studio to run them. 我使用@RunWith(AndroidJUnit4.class)注释我的测试类,并使用Android Studio来运行它们。

For my test cases I need a Context instance. 对于我的测试用例,我需要一个Context实例。 I can get it with InstrumentationRegistry but it has two context related methods and it's not clear what the difference is. 我可以通过InstrumentationRegistry获得它,但它有两个与上下文相关的方法,并不清楚它们之间的区别。

What is the difference between InstrumentationRegistry.getContext() vs. InstrumentationRegistry.getTargetContext() ? InstrumentationRegistry.getContext()InstrumentationRegistry.getTargetContext()什么区别?

InstrumentationRegistry is an exposed registry instance that holds a reference to the instrumentation running in the process and it's arguments and allows injection of the following instances: InstrumentationRegistry是一个公开的注册表实例,它包含对进程中运行的检测的引用及其参数,并允许注入以下实例:

  • InstrumentationRegistry.getInstrumentation() , returns the Instrumentation currently running. InstrumentationRegistry.getInstrumentation()返回当前正在运行的Instrumentation。
  • InstrumentationRegistry.getContext() , returns the Context of this Instrumentation's package. InstrumentationRegistry.getContext()返回此Instrumentation包的Context。
  • InstrumentationRegistry.getTargetContext() , returns the application Context of the target application. InstrumentationRegistry.getTargetContext() ,返回目标应用程序的应用程序上下文。
  • InstrumentationRegistry.getArguments() , returns a copy of arguments Bundle that was passed to this Instrumentation. InstrumentationRegistry.getArguments()返回传递给此Instrumentation的参数Bundle的副本。 This is useful when you want to access the command line arguments passed to Instrumentation for your test. 当您想要访问为测试传递给Instrumentation的命令行参数时,这非常有用。

EDIT: 编辑:

So when to use getContext() vs getTargetContext()? 那么何时使用getContext()vs getTargetContext()?

The documentation doesn't do a great job of explaining the differences so here it is from my POV: 文档在解释差异方面做得不是很好,所以这里来自我的POV:

You know that when you do instrumentation tests on Android then you have two apps: 您知道,当您在Android上进行仪器测试时,您有两个应用程序:

  1. The test app, that executes your test logic and tests your "real" app 测试应用程序,执行您的测试逻辑并测试您的“真实”应用程序
  2. The "real" app (that your users will see) “真实”应用(您的用户会看到)

So when you are writing your tests and you want to load a resource of your real app , use getTargetContext() . 因此,当您编写测试并希望加载真实应用程序的资源时,请使用getTargetContext()

If you want to use a resource of your test app (eg a test input for one of your tests) then call getContext() . 如果您想使用测试应用程序的资源(例如,您的某个测试的测试输入),请调用getContext()

You may need InstrumentationRegistry.getContext() for access to raw resources of a test case. 您可能需要InstrumentationRegistry.getContext()来访问测试用例的原始资源。

Eg, to access app/src/androidTest/res/raw/resource_name.json in a TestCase: 例如,要在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);

Took me hours to find that out. 花了我几个小时才找到它。

A InstrumentedTest case had a context member which was set up in the setup like this: InstrumentedTest案例有一个上下文成员,它在设置中设置如下:

context = InstrumentationRegistry.getTargetContext();

this was used to open files, especially things like that: 这用于打开文件,尤其是这样的东西:

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

Now I decided that I need to use some resource which is only available in the instrumented test, I did not want to distribute this resource with the release version. 现在我决定我需要使用一些在检测测试中可用的资源,我不想在发布版本中分发此资源。 Therefore I recreated the resource directories under test: 因此,我重新创建了测试中的资源目录:

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

But to be able to use this in code I had to call something like this: 但是为了能够在代码中使用它,我不得不调用这样的东西:

    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)

Which would always fail because R.raw.v1 coincidently corresponded to something that was actually in my R resource file from the main application. 总是会失败,因为R.raw.v1恰好与主应用程序中我的R资源文件中的内容相对应。 By using resources in the instrumented tests, there were two R files generated. 通过使用检测测试中的资源,生成了两个R文件。 To fix that I had to include the test R file: 要解决这个问题,我必须包含测试R文件:

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

the resourceToUri call would then however sill fail. 然后, resourceToUri调用将失败。

The issue was, that I must not have used InstrumentationRegistry.getTargetContext() but rather InstrumentationRegistry.getInstrumentation().getContext() to get the resource of R.raw.v1 so I blindly replace the setup of the context for the whole test class to 问题是,我不能使用InstrumentationRegistry.getTargetContext()而是使用InstrumentationRegistry.getInstrumentation().getContext()来获取R.raw.v1的资源,所以我盲目地替换整个测试类的上下文设置至

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

It worked well for the specific test but other tests in the test case started to fail with permission denied for the filenameOriginal I was using above. 它适用于特定测试,但测试用例中的其他测试开始失败,并且我在上面使用的filenameOriginal被拒绝了。

Turned out that by replacing the context to the instrumentation context I obtained a path to which my app had no access and I got FileNotFoundException with permission denied and no GrantTestRule or other things would work. 事实证明,通过将上下文替换为检测上下文,我获得了一个我的应用程序无法访问的路径,并且我获得了FileNotFoundExceptionpermission denied并且没有GrantTestRule或其他东西可以工作。

So be careful when using those contexts, it might screw your time :/ 所以在使用这些上下文时要小心,这可能会让你的时间变得紧张:/

暂无
暂无

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

相关问题 这有什么区别,getContext() 和 getActivity()? - What is the difference between this, getContext() and getActivity()? InstrumentationRegistry.getContext() 替换示例 - Example for replacement for InstrumentationRegistry.getContext() AndroidX 迁移 AndroidTestCase 后,AndroidJUnit4 和 InstrumentationRegistry.getTargetContext 被弃用 - After AndroidX migration AndroidTestCase, AndroidJUnit4 & InstrumentationRegistry.getTargetContext are depricated getContext()、getApplicationContext()、getBaseContext() 和“this”之间的区别 - Difference between getContext() , getApplicationContext() , getBaseContext() and "this" Fragment的getContext与传递给Fragment的onCreateView的容器的getContext有区别吗? - Is there a difference between getContext of Fragment and getContext of container passed to onCreateView of Fragment? 从 Android 测试中获取资源:InstrumentationRegistry.getInstrumentation().getTargetContext() VS myActivityTestRule.getActivity() - Get resource from Android test: InstrumentationRegistry.getInstrumentation().getTargetContext() VS myActivityTestRule.getActivity() 使用片段时 getContext() 和 requireContext() 的区别 - Difference between getContext() and requireContext() when using fragments ProgressDialog的getContext不是我传递的 - What ProgressDialog's getContext is not what I pass into 文档与 android 中的实际 class 'InstrumentationRegistry' 之间的不相关性 - Uncorrelation between the documentation and the actuall class 'InstrumentationRegistry' in android Android - View.getResources()和View.getContext()之间的区别.getResources() - Android - Difference between View.getResources() and View.getContext().getResources()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM