2017-07-19 467 views
6

我有一個BaseTest類,它由幾個測試組成。每個測試都應針對每個配置文件I列表執行。Spring Boot/JUnit,運行多個配置文件的所有單元測試

我想過使用參數值,如:

@RunWith(Parameterized.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
// @ActiveProfiles("h2-test") // <-- how to iterate over this? 
public abstract class BaseTest { 

@Autowired 
private TestRepository test; 

// to be used with Parameterized/Spring 
private TestContextManager testContextManager; 

public BaseTest(String profile) { 
    System.setProperty("spring.profiles.active", profile); 
    // TODO what now? 
} 

@Parameterized.Parameters 
public static Collection<Object[]> data() { 
    Collection<Object[]> params = new ArrayList<>(); 
    params.add(new Object[] {"h2-test" }); 
    params.add(new Object[] {"mysql-test" }); 
    return params; 
} 

@Before 
public void setUp() throws Exception { 
    this.testContextManager = new TestContextManager(getClass()); 
    this.testContextManager.prepareTestInstance(this); 
    // maybe I can spinup Spring here with my profile? 
} 

@Test 
public void testRepository() { 
    Assert.assertTrue(test.exists("foo")) 
} 

我怎麼會告訴Spring來運行這些不同的配置文件每個測試?實際上,每個配置文件都會與不同的數據源(內存中的h2,外部的mysql,外部oracle,...)進行通信,因此我的存儲庫/數據源必須重新初始化。


我知道,我可以指定@ActiveProfiles(...),我甚至可以從BaseTest延伸和覆蓋ActiveProfile註解。雖然這會起作用,但我只顯示我的測試套件的一部分。很多我的測試類都是從BaseTest擴展而來的,我不想爲每個類創建幾個不同的配置文件存根。目前的工作,但醜陋的解決方案:

  • BaseTest(@ActiveProfiles( 「MySQL的」))
    • FooClassMySQL(註釋從BaseTest)
      • FooClassH2(@ActiveProfiles( 「H2」))
    • BarClassMySQL(註釋從BaseTest)
      • BarClassH2(@ActiveProfiles( 「H2」))

感謝

+0

爲什麼不用參數運行所有測試,例如如果你使用Maven,它可能是'mvn test -Dspring.profiles.active = test'。我不確定你是否可以通過這個參數化的類來實現它,主要是因爲在它開始執行測試之前,Spring很可能會啓動它的上下文,並且在此之前必須設置活動配置文件。 –

+0

謝謝。非常好的解決方案,我沒有想過。如果沒有一種優雅的方式來處理它,這肯定會做到!我認爲唯一的問題可能是隻有少數測試(實際上,我所有的存儲庫/ jpa測試)需要不同的配置文件,而其他的則不需要訪問不同的配置。 – Frame91

+0

酷!如果它適用於您,我會將其添加爲答案。 –

回答

3

如果你使用Maven,你實際上可以從指定命令行(或者,如果環境變量活動的配置文件需要):

mvn clean test -Dspring.profiles.active=h2-test 

帶參數化測試的方法可能不起作用在這種情況下,因爲配置文件必須在Spring啓動它的上下文之前指定。在這種情況下,當您運行參數化集成測試時,在測試運行器開始運行測試之前,上下文已經啓動。此外,JUnit的參數化測試是由於其他原因(運行具有不同數據系列的單元測試)而發明的。

編輯:還有一件事 - 當你決定使用@RunWith(Parameterized.class)你將無法使用不同的亞軍。在許多情況下(如果不是全部涉及集成測試),您希望指定不同的參賽者,例如SpringRunner.class - 通過參數化測試,您將無法做到這一點。

+0

我編輯了我的代碼,顯示瞭如何解決SpringRunner.class(實質上使用TestContextManager來) – Frame91

4

春季配置文件不旨在以這種方式工作。
就你而言,每個配置文件使用特定的數據源。
因此,每個人都需要Spring Boot加載來運行預期數據源的測試。

事實上,你想要做的就像創建與你想測試的Spring配置文件一樣多的Maven構建。

此外,建立本地環境應該儘可能快。
通過DBMS實現乘以自動化測試執行,需要每次執行Spring Boot重新加載都無濟於事。

您不應指定@ActiveProfiles

它看起來有點像一個持續集成工具,您可以定義執行作業(順序或平行)每個Maven構建通過指定一個特定的春天引導配置任務:

mvn clean test -Dspring.profiles.active=h2 

mvn clean test -Dspring.profiles.active=mysql 

等..

你也可以嘗試通過編寫執行maven構建的腳本來在本地執行它。但是如上所述,它會減慢你的本地構建並且使它複雜化。

相關問題