2012-09-03 55 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啓動此類測試

相關問題