2012-09-03 51 views
1

我有2个使用JUnit实现的集成测试。两个测试的执行到远程服务器和所述服务器的目标的呼叫是由环境变量中配置:如何在单独的进程中运行JUnit测试?

System.setProperty("property", "value1"); 

棘手的是,这些性能必须是2次测试的不同。如果我为每个单元测试设置环境变量,它不起作用,因为我们使用的中间件在第一次调用时缓存了属性值,并且不再对其进行评估(对于第二次测试)。

相信该解决方案可运行在单独的进程的单元测试。我看到类似的讨论here,但是用JUnit4做这件事可能更优雅吗?这个问题看起来很常见。 或者也许有另一种方式来运行不同配置的单元测试?

先感谢您的任何建议。

+0

是否为每个进程实例化了中间件?如果不是,那么即使是一个新的进程也不会覆盖缓存......也许,在中间件文档中的某个地方会有一种方法来清除缓存......我的回答建议了一种方法来为每个测试启动一个新进程不同的环境变量... – rrufai

回答

2

它被认为是不好的做法有其无法测试之间复位状态。虽然不容易测试的代码很常见,但解决方案并不简单。

我会考虑重新即使你使用反射做缓存值。具体需要重置的内容取决于库的内部表示。

2

这取决于你如何运行JUnit。

如果您希望能够从IDE或构建中运行它,请执行您的定制Runner并使用标注RunWith(MyRunner.class)标记测试用例。

如果您使用的是maven,并且足以让您能够从那里运行测试,请使用<forkMode>always</forkMode>转换为maven-surefire-plugin定义。

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-surefire-plugin</artifactId> 
      <version>2.11</version> 
      <configuration> 
       <systemProperties> 
        <systemProperty> 
         <name>panpwr.conf.dir</name> 
         <value>${basedir}/conf-test</value> 
        </systemProperty> 
       </systemProperties> 
       <forkMode>always</forkMode> 

-1

单元测试一般不应依赖于外部资源,如远程服务器。否则,您不是在测试设备,而是依赖它的资源的可用性和正确性。

那么如何测试这些单元呢?

你通常会做此与模仿对象。将对外部资源的调用封装在一个对象中,并将此对象传递给要测试的单元(称为dependency injection)。在你的单元测试中,你不会传递一个真正的服务器抽象对象。而是传递一个实现相同接口或扩展服务器抽象类的模拟对象。模拟对象并不真正查询服务器。而是立即返回服务器应返回的值。

这可能需要你的代码的一些重构。但它可以让你的单元测试工作,而不依赖于外部资源。它也使测试更加快速,从而缩短了测试套装的整体执行时间。这使您可以更频繁地执行单元测试

+1

我完全同意你的看法。我知道什么是依赖注入,我确实使用它。这两个是综合测试,这是在问题的第一句中说明的。我只是使用JUnit来创建在远程服务器上运行的集成测试,以进行集成测试。我们还有所有系统组件的测试配置 – nogard

0

使用ProcessBuilder API,您可以在启动每个进程之前更改环境变量。这里有一个代码片段,你可能会这样做。

@Test 
void testVariant1(){ 
     String [] commandArray = 
     {"java", "-cp", "your/class/path", "org.mydomain.myClass", ...}; 
     Map<String, String> envVarsForThisTest = new HashMap<String, String>(); 
     envVarsForThisTest.put("newProperty", "value1"); 
     List<String> staleVars = new List<String>(); 
     stateVars.add("oldProperty"); 
     File workingDir = new File("myDir")); 
     Process p = runVariant(
       commandArray, envVarsForThisTest, staleVars, workingDir); 
     Assert.assert(p.waitFor(), 0); 
     checkAssertions(p.getOutputStream(), p.getErrorStream()); 
} 

void checkAssertions(OutputStream output, InputStream errorStream){ 
     // where you'll check the return values against your expectations 
} 

void runVariant(String commandArray[], 
      Map<String, 
      String> newEnvironmentVariables, 
      List<String> environemntVariablesToRemove, 
      File workingDirectory){ 
     ProcessBuilder pb = new ProcessBuilder(commandArray); 
     Map<String, String> env = pb.environment(); 
     for(Map.Entry<String, String> entry : newEnvironmentVariables){ 
      env.put(entry.key(), entry.value()); 
     } 
     for(String staleVariable : environemntVariablesToRemove){ 
      env.remove(staleVariable); 
     } 
     pb.directory(workingDirectory); 
     return pb.start(); 
} 
1

我需要与一些传统代码工作期间隔离JUnit测试所以我开发小行家插件黄麻,其允许启动在分离的外部过程中的每个JUnit测试方法,I have published it in GitHub和在maven central,可以是插件将是适合您的问题的解决方案,插件也允许使用不同的JVM启动此类测试

相关问题