如何为 JUnit 测试设置 JVM 参数?

我有一些 Junit 单元测试,它们需要大量的堆空间来运行——也就是1G。(他们测试 webstart 应用程序的内存密集型功能,该应用程序只能在足够的堆空间下运行,并且将在 Win 764位机器上内部运行——因此重新设计测试不是一个实际的建议。)

我是在 Intellij IDEA 开发的,所以我知道我可以为测试类设置 JVM 参数(例如-Xmx1024M)。然而,这只是为了运行整个测试类——如果我想运行一个单独的测试,我必须为那个测试方法重新创建运行配置。

而且,这些都是 IDE 和特定的框-所以如果我切换框(我在多台机器上开发)或者我的一个同事试图运行测试,这些设置不会被传输。(另外,我的同事也在使用 Eclipse 和 NetBeans 等其他 IDE。)FWIW,我们正在使用 mercurial 进行源代码控制。

对于构建周期,我们使用 Maven,所以我知道如何为其指定 JVM 参数。

- 我正在寻找一种方法来指定将应用于整个测试类和单个测试方法的 JVM 参数; 以及 我希望在任何机器上的 IDE 之间共享这些规范(已经从存储库中获取了代码)。

133411 次浏览

In Maven you can configure the surefire plugin

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>-Xmx256M</argLine>
</configuration>
</plugin>

If you use Maven for builds then this configuration will be carried in the source tree and applied when tests are carried out. See the Maven Surefire Plugin documentation.

In IntelliJ you can specify default settings for each run configuration. In Run/Debug configuration dialog (the one you use to configure heap per test) click on Defaults and JUnit. These settings will be automatically applied to each new JUnit test configuration. I guess similar setting exists for Eclipse.

However there is no simple option to transfer such settings (at least in IntelliJ) across environments. You can commit IntelliJ project files to your repository: it might work, but I do not recommend it.

You know how to set these for maven-surefire-plugin. Good. This is the most portable way (see Ptomli's answer for an example).

For the rest - you must remember that JUnit test cases are just a bunch of Java classes, not a standalone program. It is up to the runner (let it be a standalone JUnit runner, your IDE, maven-surefire-plugin to set those options. That being said there is no "portable" way to set them, so that memory settings are applied irrespective to the runner.

To give you an example: you cannot define Xmx parameter when developing a servlet - it is up to the container to define that. You can't say: "this servlet should always be run with Xmx=1G.

I agree with the others who said that there is no simple way to distribute these settings.

For Eclipse: ask your colleagues to set the following:

  • Windows Preferences / Java / Installed JREs:
  • Select the proper JRE/JDK (or do it for all of them)
  • Edit
  • Default VM arguments: -Xmx1024m
  • Finish, OK.

After that all test will run with -Xmx1024m but unfortunately you have set it in every Eclipse installation. Maybe you could create a custom Eclipse package which contains this setting and give it to you co-workers.

The following working process also could help: If the IDE cannot run a test the developer should check that Maven could run this test or not.

  • If Maven could run it the cause of the failure usually is the settings of the developer's IDE. The developer should check these settings.
  • If Maven also could not run the test the developer knows that the cause of the failure is not the IDE, so he/she could use the IDE to debug the test.

An eclipse specific alternative limited to the java.library.path JVM parameter allows to set it for a specific source folder rather than for the whole jdk as proposed in another response:

  1. select the source folder in which the program to start resides (usually source/test/java)
  2. type alt enter to open Properties page for that folder
  3. select native in the left panel
  4. Edit the native path. The path can be absolute or relative to the workspace, the second being more change resilient.

For those interested on detail on why maven argline tag should be preferred to the systemProperties one, look, for example:

Pick up native JNI files in Maven test (lwjgl)

You can use systemPropertyVariables (java.protocol.handler.pkgs is your JVM argument name):

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<systemPropertyVariables>
<java.protocol.handler.pkgs>com.zunix.base</java.protocol.handler.pkgs>
<log4j.configuration>log4j-core.properties</log4j.configuration>
</systemPropertyVariables>
</configuration>
</plugin>

http://maven.apache.org/surefire/maven-surefire-plugin/examples/system-properties.html

Parameters can be set on the fly also.

mvn test -DargLine="-Dsystem.test.property=test"

See http://www.cowtowncoder.com/blog/archives/2010/04/entry_385.html

According to this support question https://intellij-support.jetbrains.com/hc/en-us/community/posts/206165789-JUnit-default-heap-size-overridden-

the -Xmx argument for an IntelliJ junit test run will come from the maven-surefire-plugin, if it's set.

This pom.xml snippet

        <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>

seems to pass the -Xmx1024 argument to the junit test run, with IntelliJ 2016.2.4.

If you set it in Java code, you can set it like this

      static {
System.getProperties().setProperty("env", "test");
System.getProperties().setProperty("spring.application.name", "spring-example");
}

reference:

https://stackoverflow.com/a/60654275/4712855

https://stackoverflow.com/a/10774432/4712855