2017-07-19 19 views
6

Mam klasę BaseTest, która składa się z kilku testów. Każde badanie zostanie wykonane dla KAŻDEGO profilu I listy.Spring Boot/JUnit, uruchom wszystkie testy jednostkowe dla wielu profili

Myślałem o użyciu wartości Sparametryzowana takich jak:

@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")) 
} 

Jak mówię Wiosna uruchomić każdy test z tych różnych profilach? W rzeczywistości każdy profil będzie rozmawiał z różnymi źródłami danych (w pamięci h2, zewnętrznym mysql, zewnętrznym wyroczni ...), więc moje repozytorium/źródło danych musi zostać ponownie zainicjowane.


wiem, że mogę określić @ActiveProfiles (...) i mogę nawet rozciągać się od BaseTest i przesłonić adnotacji ActiveProfile. Chociaż to zadziała, pokazuję tylko część mojego zestawu testowego. Wiele z moich testów rozszerza się z BaseTest i nie chcę tworzyć kilku różnych profilów pośrednich dla każdej klasy. Obecnie pracuje, ale brzydki rozwiązanie:

  • BaseTest (@ActiveProfiles ("mysql"))
    • FooClassMySQL (adnotacja z BaseTest)
      • FooClassH2 (@ActiveProfiles ("H2"))
    • BarClassMySQL (uwagi z BaseTest)
      • BarClassH2 (@ActiveProfiles ("H2"))

Dzięki

+0

Dlaczego nie uruchomić wszystkich testów z parametrem, np. jeśli używasz Mavena, może to być 'mvn test -Dspring.profiles.active = test'. Nie jestem pewien, czy można to osiągnąć za pomocą tej sparametryzowanej klasy, głównie dlatego, że Spring najprawdopodobniej uruchomi swój kontekst, zanim rozpocznie wykonywanie testu i musisz wcześniej skonfigurować aktywny profil. –

+0

Dzięki. Bardzo fajne rozwiązanie, o którym nie myślałem. To na pewno zrobi, jeśli nie ma eleganckiego sposobu radzenia sobie z tym w kodzie! Myślę, że jedynym problemem z tym może być to, że tylko kilka testów (w rzeczywistości wszystkie moje testy repozytorium/jpa), muszą mieć różne profile, podczas gdy inne nie muszą/muszą mieć dostępu do różnych konfiguracji. – Frame91

+0

Fajnie! Dodam to jako odpowiedź, jeśli zadziała dla ciebie. –

Odpowiedz

3

Jeśli używasz Maven rzeczywiście można określić aktywny profil z linii poleceń (lub env zmiennej if potrzebne):

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

Podejście z sparametryzowanym testem może nie działać w tym przypadku, ponieważ profil musi zostać określony zanim Spring uruchomi swój kontekst. W takim przypadku po uruchomieniu sparametryzowanego testu integracji kontekst zostanie uruchomiony przed uruchomieniem testu przez użytkownika testowego. Również sparametryzowane testy JUnita zostały wymyślone z innych powodów (przeprowadzając testy jednostkowe z różnymi seriami danych).

EDYCJA: Jeszcze jedno - gdy zdecydujesz się użyć @RunWith(Parameterized.class), nie będziesz w stanie użyć innego runnera. W wielu przypadkach (jeśli nie wszystkie, jeśli chodzi o testowanie integracyjne), chcesz określić inny program, np. SpringRunner.class - z parametryzowanym testem nie będziesz mógł tego zrobić.

+0

Edytowałem mój kod, który pokazuje, jak mogę obejść SpringRunner.class (zasadniczo używając TestContextManager) – Frame91

4

Profile sprężyn nie są zaprojektowane do pracy w ten sposób.
W twoim przypadku każdy profil używa określonego źródła danych.
Więc każdy wymaga obciążenia Spring Boot, aby uruchomić testy z oczekiwanym źródłem danych.

Rzeczywiście, chcesz zrobić jak najwięcej Maven w wersji Spring, którą chcesz przetestować.

Poza tym kompilacje w lokalnym środowisku powinny być tak szybkie, jak to tylko możliwe.
Powielanie testów zautomatyzowanych przez wdrożenie DBMS, które wymaga przeładowania Spring Boot dla każdego, nie pomoże.

Nie trzeba określać @ActiveProfiles.

Wygląda raczej jak zadanie dla Continuous Integration narzędzia, gdzie można zdefiniować zadania, które wykonuje (sekwencyjnie lub równolegle) każda Maven zbudować podając konkretny profil Wiosna Boot:

mvn clean test -Dspring.profiles.active=h2 

mvn clean test -Dspring.profiles.active=mysql 

etc ...

Możesz również spróbować wykonać to w języku lokalnym, pisząc skrypt wykonujący wykonywanie buildów maven.
Ale, jak powiedziałem, spowolni to twoją lokalną kompilację, a także ją skomplikuje.

Powiązane problemy