在下面的gradle脚本中,maxParallelForks
和forkEvery
将使用每个Junit测试类的新JVM启动一个新进程。 有没有办法让每个测试进程/ JVM / Junit类都有自己独特的系统属性?
我尝试了一个实验,我在beforeSuite
方法中将UUID值作为系统属性传递。
apply plugin:'java'
test {
ignoreFailures = true
maxParallelForks = 8
forkEvery = 1
systemProperty 'some.prop', 'value'
beforeSuite { descriptor ->
logger.lifecycle("Before suite: " + descriptor)
def theuuid = UUID.randomUUID().toString()
println "beforeSuite uuid =" + theuuid
systemProperty 'some.uuid', theuuid
}
beforeTest { descriptor ->
logger.lifecycle("Running test: " + descriptor)
}
}
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
}
JUnit测试类LoginTest1
和LoginTest2
在测试方法中打印出系统属性。
public class LoginTest1 {
private String userName="Gradle";
@Test
public void testUserName() throws Exception {
System.out.println("LoginTest1: Testing Login ");
System.out.println("LoginTest1: Testing Login some.prop -> "
+ System.getProperty("some.prop"));
System.out.println("LoginTest1: Testing Login some.uuid -> "
+ System.getProperty("some.uuid"));
assertTrue(userName.equals("Gradle"));
}
}
public class LoginTest2 {
private String userName="Gradle";
@Test
public void testUserName() throws Exception {
System.out.println("LoginTest2: Testing Login ");
System.out.println("LoginTest2: Testing Login some.prop -> "
+ System.getProperty("some.prop"));
System.out.println("LoginTest2: Testing Login some.uuid -> "
+ System.getProperty("some.uuid"));
assertTrue(userName.equals("Gradle"));
}
}
从下面的gradle输出中可以看出,在运行单个JUnit测试方法之前调用了beforeSuite
方法。两个测试类都获得6a006689-474f-47d5-9649-a88c92b45095
$ gradle clean test
> Task :test
Before suite: Gradle Test Run :test
beforeSuite uuid =6a006689-474f-47d5-9649-a88c92b45095
Before suite: Gradle Test Executor 1
beforeSuite uuid =39edb608-3027-4ad8-bd15-f52f50175582
Before suite: Test class ch6.login.LoginTest1
beforeSuite uuid =c0ce55e0-924c-4319-becb-bc27229c9cf3
Before suite: Gradle Test Executor 2
beforeSuite uuid =c15eaac0-7ea7-46d2-8235-8dc49b3f7a39
Running test: Test testUserNameNotNull(ch6.login.LoginTest1)
Before suite: Test class ch6.login.LoginTest2
beforeSuite uuid =73abbe24-5b78-4935-867a-445ac4ac20ef
Running test: Test testUserName(ch6.login.LoginTest1)
Running test: Test testUserName(ch6.login.LoginTest2)
JUnit测试类输出:
LoginTest1: Testing Login
LoginTest1: Testing Login some.prop -> value
LoginTest1: Testing Login some.uuid -> 6a006689-474f-47d5-9649-a88c92b45095
LoginTest2: Testing Login
LoginTest2: Testing Login some.prop -> value
LoginTest2: Testing Login some.uuid -> 6a006689-474f-47d5-9649-a88c92b45095
看起来有一个对beforeSuite的初始调用(看作":test"),然后每个Test Executor调用一次。所有JVM都设置了第一个uuid值(" 6a006689")。 我可以使用简单的beforeClass方法吗?
在下面的调试日志中,看起来测试执行器被赋予jvm参数-Dsome.uuid=6a006689-474f-47d5-9649-a88c92b45095
,并且使用soley来创建新的JVM(根据forkEvery
配置)。这让我觉得在Gradle中我不想做的事情。
20:23:42.466 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'Gradle Test Executor 1'. Working directory: /a/b/ Command: /usr/lib/jvm/java-8-openjdk-amd64/bin/java -Djava.security.manager=worker.org.gradle.process.internal.worker.child.BootstrapSecurityManager -Dorg.g
radle.native=false -Dsome.prop=value -Dsome.uuid=6a006689-474f-47d5-9649-a88c92b45095 -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -ea -cp /data/.gradle/caches/4.3.1/workerMain/gradle-worker.jar worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 1'
20:23:42.466 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'Gradle Test Executor 2'. Working directory: /a/b/ Command: /usr/lib/jvm/java-8-openjdk-amd64/bin/java -Djava.security.manager=worker.org.gradle.process.internal.worker.child.BootstrapSecurityManager -Dorg.g
radle.native=false -Dsome.prop=value -Dsome.uuid=6a006689-474f-47d5-9649-a88c92b45095 -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -ea -cp /data/.gradle/caches/4.3.1/workerMain/gradle-worker.jar worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 2'
相反,有一个org.gradle.test.worker系统属性,您可以使用它来区分worker,计算显示名称,临时目录等。这个test.worker只是一个增加的long值。 Gradle团队没有计划让测试工作者可配置。很遗憾因为我必须在我的测试代码中进行一些重大的重构才能升级Gradle。 " @ BeforeAllCallback"在JUnit 5中可能对你有用。
此代码演示了lance-java的建议,并成功回答了我的问题。 我有以下build.gradle脚本,它使用MyTestTask来扩展Test并添加一个名为my_uuid
的唯一值。请注意,构建脚本必须具有forkEvery = 1,以确保每个JUnit测试调用copyTo
一次:
class MyTestTask extends Test {
public Test copyTo(JavaForkOptions target) {
super.copyTo(target);
String uuid = UUID.randomUUID().toString();
System.out.println("MyTestTask copyTo:\n my_uuid=" + uuid);
System.out.println("\t before getJvmArgs:" + target.getJvmArgs());
System.out.println("\t before getSystemProperties:" + target.getSystemProperties());
target.systemProperty("my_uuid", uuid);
System.out.println("\t after getJvmArgs:" + target.getJvmArgs());
System.out.println("\t after getSystemProperties:" + target.getSystemProperties());
return this;
}
}
///
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
}
test {
enabled false // This doesn't seem to matter.
}
task my_test(type: MyTestTask) {
forkEvery 1 // need this so copyTo called each JUnit test
testLogging.showStandardStreams = true
doFirst {
def uuid = UUID.randomUUID().toString()
println "TEST:Task name is $name. In doFirst. uuid is " + uuid
jvmArgs '-Dcommon_uuid='+ uuid
}
}
}
执行的Junit测试非常简单,只需打印出System.getProperty(" my_uuid")和System.getProperty(" common_uuid")。
> Task :CustomCopyToSubProject:my_test
TEST:Task name is my_test. In doFirst. uuid is eed1ee92-7805-4b8e-a74c-96218d1be6e1
MyTestTask copyTo:
MyTestTask copyTo:
my_uuid=a7996c20-1085-4397-9e32-fd84467dcb45
my_uuid=69f6f347-71d0-4e5d-9fad-66bf4468fab3
before getJvmArgs:[]
before getJvmArgs:[]
before getSystemProperties:[common_uuid:eed1ee92-7805-4b8e-a74c-96218d1be6e1]
before getSystemProperties:[common_uuid:eed1ee92-7805-4b8e-a74c-96218d1be6e1]
after getJvmArgs:[]
after getJvmArgs:[]
after getSystemProperties:[common_uuid:eed1ee92-7805-4b8e-a74c-96218d1be6e1, my_uuid:69f6f347-71d0-4e5d-9fad-66bf4468fab3]
after getSystemProperties:[common_uuid:eed1ee92-7805-4b8e-a74c-96218d1be6e1, my_uuid:a7996c20-1085-4397-9e32-fd84467dcb45]
ch3.LoginTest2 > testUserName2 STANDARD_OUT
LoginTest2.java: Testing Login ! >>---> my_uuid=a7996c20-1085-4397-9e32-fd84467dcb45 common_uuid=eed1ee92-7805-4b8e-a74c-96218d1be6e1
ch3.LoginTest1 > testUserName1 STANDARD_OUT
LoginTest1.java: Testing Login ! >>---> my_uuid=69f6f347-71d0-4e5d-9fad-66bf4468fab3 common_uuid=eed1ee92-7805-4b8e-a74c-96218d1be6e1
task my_test
中的common_uuid
集doFirst
。 MyTestTask.copyTo
方法设置了自己的my_uuid
。
您可以从输出中看到MyTestTask被调用两次,每个JUnit测试任务一次(LoginTest1和LoginTest2)。两个JUnit测试在my_uuid
中获得了自己独特的系统属性。
答案 0 :(得分:0)
由于为每个测试分叉了一个新的JVM,你可以使用一个用UUID初始化的静态字段。
public class Helper {
public static final String uuid = UUID.randomUUID().toString();
}
public class LoginTest2 {
private String userName="Gradle";
@Test
public void testUserName() throws Exception {
System.out.println("LoginTest2: Testing Login ");
System.out.println("LoginTest2: Testing Login some.uuid -> "
+ Helper.uuid;
assertTrue(userName.equals("Gradle"));
}
}
答案 1 :(得分:0)
我认为您想要拦截Test.copyTo(JavaForkOptions target)
,遗憾的是我能看到这样做的唯一方法是延长Test
例如
public class Test2 extends org.gradle.api.tasks.testing.Test {
public Test copyTo(JavaForkOptions target) {
super.copyTo(target);
target.systemProperty("uuid", UUID.randomUUID().toString());
return this;
}
}
的build.gradle
apply plugin: 'java'
test {
enabled = false
}
task test2(type: Test2) {
// guessing you'll need to configure a bit of stuff here
}
check.dependsOn test2