Android Studio单元测试:读取数据(输入)文件

时间:2023-01-13 10:08:28

In a unit test, how can I read data from a json file on my (desktop) file system, without hardcoding the path?

在单元测试中,如何在不硬编码路径的情况下从(桌面)文件系统上的json文件读取数据?

I would like to read test input (for my parsing methods) from a file instead of creating static Strings.

我希望从文件中读取测试输入(用于解析方法),而不是创建静态字符串。

The file is in the same location as my unit testing code, but I can also place it somewhere else in the project if needed. I am using Android Studio.

这个文件与我的单元测试代码位于同一个位置,但是如果需要,我也可以将它放在项目中的其他地方。我在使用Android Studio。

5 个解决方案

#1


104  

Depending on android-gradle-plugin version:

根据android-gradle-plugin版本:

1. version 1.5 and higher:

1。版本1.5和更高版本:

Just put json file to src/test/resources/test.json and reference it as

只需将json文件放入src/test/resources/test。json并作为引用

classLoader.getResource("test.json"). 

No gradle modification is needed.

不需要修改等级。

2. version below 1.5: (or if for some reason above solution doesn't work)

2。版本1.5以下:(或者由于某种原因,上面的解决方案不起作用)

  1. Ensure you're using at least Android Gradle Plugin version 1.1. Follow the link to set up Android Studio correctly.

    确保你使用的至少是1.1版的Android Gradle插件。按照链接正确设置Android Studio。

  2. Create test directory. Put unit test classes in java directory and put your resources file in res directory. Android Studio should mark them like follow:

    创建测试目录。将单元测试类放在java目录中,并将资源文件放在res目录中。Android Studio应该标记如下:

    Android Studio单元测试:读取数据(输入)文件

  3. Create gradle task to copy resources into classes directory to make them visible for classloader:

    创建渐变任务,将资源复制到类目录中,使类加载器可以看到它们:

    android{
       ...
    }
    
    task copyResDirectoryToClasses(type: Copy){
        from "${projectDir}/src/test/res"
        into "${buildDir}/intermediates/classes/test/debug/res"
    }
    
    assembleDebug.dependsOn(copyResDirectoryToClasses)
    
  4. Now you can use this method to get File reference for the file resource:

    现在您可以使用此方法获取文件资源的文件引用:

    private static File getFileFromPath(Object obj, String fileName) {
        ClassLoader classLoader = obj.getClass().getClassLoader();
        URL resource = classLoader.getResource(fileName);
        return new File(resource.getPath());
    }
    
    @Test
    public void fileObjectShouldNotBeNull() throws Exception {
        File file = getFileFromPath(this, "res/test.json");
        assertThat(file, notNullValue());
    }
    
  5. Run unit test by Ctrl+Shift+F10 on whole class or specyfic test method.
  6. 使用Ctrl+Shift+F10对整个类或特定的测试方法运行单元测试。

#2


51  

For local unit tests (vs. instrumentation tests), you can put files under src/test/resources and read them using classLoader. For example, following code opens myFile.txt file in the resources directory.

对于本地单元测试(与插装测试相比),您可以将文件放在src/test/resources下,并使用classLoader读取它们。例如,下面的代码将打开myFile。资源目录中的txt文件。

InputStream in = this.getClass().getClassLoader().getResourceAsStream("myFile.txt");

It worked with

它曾与

  • Android Studio 1.5.1
  • Android工作室1.5.1
  • gradle plugin 1.3.1
  • gradle插件1.3.1

#3


6  

If you go to Run -> Edit configurations -> JUnit and then select the run configuration for your unit tests, there is a 'Working directory' setting. That should point to wherever your json file is. Keep in mind this might break other tests.

如果您去运行——>编辑配置——> JUnit,然后为您的单元测试选择运行配置,这里有一个“工作目录”设置。这应该指向json文件所在的位置。记住,这可能会破坏其他测试。

#4


6  

I've had plenty of problems with test resources in Android Studio so I set up a few tests for clarity. In my mobile (Android Application) project I added the following files:

我在Android Studio的测试资源上遇到了很多问题,所以我设置了一些测试来提高清晰度。在我的手机(Android应用)项目中,我添加了以下文件:

mobile/src/test/java/test/ResourceTest.java
mobile/src/test/resources/test.txt
mobile/src/test/resources/test/samePackage.txt

The test class (all tests passes):

测试类(所有测试通过):

assertTrue(getClass().getResource("test.txt") == null);
assertTrue(getClass().getResource("/test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getResource("samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getResource("/test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getClassLoader().getResource("test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getClassLoader().getResource("test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));

In the same root project I have a Java (not Android) project called data. If I add the same files to the data project:

在同一个根项目中,我有一个名为data的Java(不是Android)项目。如果我向数据项目添加相同的文件:

data/src/test/java/test/ResourceTest.java
data/src/test/resources/test.txt
data/src/test/resources/test/samePackage.txt

Then all the tests above will fail if I execute them from Android Studio, but they pass on the command line with ./gradlew data:test. To get around it I use this hack (in Groovy)

如果我在Android Studio中执行这些测试,那么上面的所有测试都将失败,但是它们将使用./gradlew数据:test传递命令行。为了解决这个问题,我使用了这个技巧(在Groovy中)

def resource(String path) {
    getClass().getResource(path) ?:
            // Hack to load test resources when executing tests from Android Studio
            new File(getClass().getClassLoader().getResource('.').path
                    .replace('/build/classes/test/', "/build/resources/test$path"))
}

Usage: resource('/test.txt')

用法:资源(/用法)

Android Studio 2.3, Gradle 3.3

Android Studio 2.3,第3.3级

#5


6  

In my case, the solution was to add to the gradle file

在我的例子中,解决方案是添加到gradle文件

sourceSets {
    test.resources.srcDirs += 'src/unitTests/resources'
  } 

After it everything was found by AS 2.3.1

之后所有的东西都被发现了2。3.1

javaClass.classLoader.getResourceAsStream("countries.txt")

#1


104  

Depending on android-gradle-plugin version:

根据android-gradle-plugin版本:

1. version 1.5 and higher:

1。版本1.5和更高版本:

Just put json file to src/test/resources/test.json and reference it as

只需将json文件放入src/test/resources/test。json并作为引用

classLoader.getResource("test.json"). 

No gradle modification is needed.

不需要修改等级。

2. version below 1.5: (or if for some reason above solution doesn't work)

2。版本1.5以下:(或者由于某种原因,上面的解决方案不起作用)

  1. Ensure you're using at least Android Gradle Plugin version 1.1. Follow the link to set up Android Studio correctly.

    确保你使用的至少是1.1版的Android Gradle插件。按照链接正确设置Android Studio。

  2. Create test directory. Put unit test classes in java directory and put your resources file in res directory. Android Studio should mark them like follow:

    创建测试目录。将单元测试类放在java目录中,并将资源文件放在res目录中。Android Studio应该标记如下:

    Android Studio单元测试:读取数据(输入)文件

  3. Create gradle task to copy resources into classes directory to make them visible for classloader:

    创建渐变任务,将资源复制到类目录中,使类加载器可以看到它们:

    android{
       ...
    }
    
    task copyResDirectoryToClasses(type: Copy){
        from "${projectDir}/src/test/res"
        into "${buildDir}/intermediates/classes/test/debug/res"
    }
    
    assembleDebug.dependsOn(copyResDirectoryToClasses)
    
  4. Now you can use this method to get File reference for the file resource:

    现在您可以使用此方法获取文件资源的文件引用:

    private static File getFileFromPath(Object obj, String fileName) {
        ClassLoader classLoader = obj.getClass().getClassLoader();
        URL resource = classLoader.getResource(fileName);
        return new File(resource.getPath());
    }
    
    @Test
    public void fileObjectShouldNotBeNull() throws Exception {
        File file = getFileFromPath(this, "res/test.json");
        assertThat(file, notNullValue());
    }
    
  5. Run unit test by Ctrl+Shift+F10 on whole class or specyfic test method.
  6. 使用Ctrl+Shift+F10对整个类或特定的测试方法运行单元测试。

#2


51  

For local unit tests (vs. instrumentation tests), you can put files under src/test/resources and read them using classLoader. For example, following code opens myFile.txt file in the resources directory.

对于本地单元测试(与插装测试相比),您可以将文件放在src/test/resources下,并使用classLoader读取它们。例如,下面的代码将打开myFile。资源目录中的txt文件。

InputStream in = this.getClass().getClassLoader().getResourceAsStream("myFile.txt");

It worked with

它曾与

  • Android Studio 1.5.1
  • Android工作室1.5.1
  • gradle plugin 1.3.1
  • gradle插件1.3.1

#3


6  

If you go to Run -> Edit configurations -> JUnit and then select the run configuration for your unit tests, there is a 'Working directory' setting. That should point to wherever your json file is. Keep in mind this might break other tests.

如果您去运行——>编辑配置——> JUnit,然后为您的单元测试选择运行配置,这里有一个“工作目录”设置。这应该指向json文件所在的位置。记住,这可能会破坏其他测试。

#4


6  

I've had plenty of problems with test resources in Android Studio so I set up a few tests for clarity. In my mobile (Android Application) project I added the following files:

我在Android Studio的测试资源上遇到了很多问题,所以我设置了一些测试来提高清晰度。在我的手机(Android应用)项目中,我添加了以下文件:

mobile/src/test/java/test/ResourceTest.java
mobile/src/test/resources/test.txt
mobile/src/test/resources/test/samePackage.txt

The test class (all tests passes):

测试类(所有测试通过):

assertTrue(getClass().getResource("test.txt") == null);
assertTrue(getClass().getResource("/test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getResource("samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getResource("/test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getClassLoader().getResource("test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getClassLoader().getResource("test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));

In the same root project I have a Java (not Android) project called data. If I add the same files to the data project:

在同一个根项目中,我有一个名为data的Java(不是Android)项目。如果我向数据项目添加相同的文件:

data/src/test/java/test/ResourceTest.java
data/src/test/resources/test.txt
data/src/test/resources/test/samePackage.txt

Then all the tests above will fail if I execute them from Android Studio, but they pass on the command line with ./gradlew data:test. To get around it I use this hack (in Groovy)

如果我在Android Studio中执行这些测试,那么上面的所有测试都将失败,但是它们将使用./gradlew数据:test传递命令行。为了解决这个问题,我使用了这个技巧(在Groovy中)

def resource(String path) {
    getClass().getResource(path) ?:
            // Hack to load test resources when executing tests from Android Studio
            new File(getClass().getClassLoader().getResource('.').path
                    .replace('/build/classes/test/', "/build/resources/test$path"))
}

Usage: resource('/test.txt')

用法:资源(/用法)

Android Studio 2.3, Gradle 3.3

Android Studio 2.3,第3.3级

#5


6  

In my case, the solution was to add to the gradle file

在我的例子中,解决方案是添加到gradle文件

sourceSets {
    test.resources.srcDirs += 'src/unitTests/resources'
  } 

After it everything was found by AS 2.3.1

之后所有的东西都被发现了2。3.1

javaClass.classLoader.getResourceAsStream("countries.txt")