Maven-wdrożyć webapp do tomcat przed JUnit test
Mam webapp, który zapewnia usługi internetowe. Chcę wykonać testy JUnit z SoapUI, aby sprawdzić, czy ta usługa działa poprawnie.
Ale aby przetestować usługę webową, aplikacja musi zostać wdrożona na moim serwerze Tomcat 7.
Nie mam pojęcia, jak skonfigurować Mavena do budowania wojny, a następnie wdrożyć go do tomcat (najlepiej: uruchomić osobną instancję tomcat), a następnie uruchomić testy JUnit.
Będę wdzięczny za każdą pomoc.
Używam Mavena 2.2.1
3 answers
Istnieje wiele szkół myślenia o tym, jak poradzić sobie z tego typu testami Integracyjnymi z Maven.
Powinienem zauważyć, że kiedy wdrażasz aplikację na serwer aplikacji, nie jesteś już w sferze testów jednostkowych. Ponieważ cała aplikacja jest wdrażana w kontenerze, testujesz integrację tych dwóch komponentów.
Teraz nie ma nic złego w używaniu JUnit do uruchamiania integracja testy (choć istnieją pewne ograniczenia, które możesz napotkać, na przykład testy jednostkowe nie powinny przejmować się sekwencjonowaniem poszczególnych testów - zakładając, że piszesz je poprawnie - więc JUnit wymusza to, nie gwarantując żadnej sekwencji wykonania... przed wersją Java 1.7 kolejność wykonania była przez przypadek implikowana kolejnością metod testowych w obrębie klasy, ale nie była częścią kontraktu JUnit... Niektórzy przechodzą na inne frameworki testowe dla swoich Testy integracyjne, np. TestNG, jeśli znajdą unit test focus JUnit staje na drodze ich rozwoju testów)
Kluczową kwestią, o której należy pamiętać, jest to, że cykl życia Mavena wykorzystuje fazę test
do wykonania testów jednostki.
Jeśli chodzi o testy integracyjne istnieją dwie (i pół) szkoły myślenia o właściwym sposobie radzenia sobie z testami za pomocą Mavena.
Szkoła 1-Failsafe i integration-test/verify
Ta szkoła myślenia wykorzystuje fazy po package
, aby uruchomić kontener, uruchomić testy integracyjne, zburzyć kontener, a na koniec sprawdzić wyniki testów i zawieść kompilację w przypadku niepowodzenia testów.
nigdy przenigdy nie uruchamiaj mvn integration-test
, ponieważ to nie rozwali poprawnie kontenera, za każdym razem, gdy myślisz, że chcesz wpisać mvn integration-test
, naprawdę chcesz wpisać mvn verify
(spójrz, jest to krótsze i łatwiejsze do wpisania również... bonus)
Więc z tym zrobić po:
- Bind tomcat7: Uruchom do fazy
pre-integration-test
zfork
=true
- Bind failsafe: integration-test to the
integration-test
phase - Bind tomcat7: shutdown to the
post-integration-test
phase - Bind failsafe: verify to the
verify
phase.
Aby uzyskać dodatkowe punkty, należy użyć build-helper-maven-plugin: reserve-network-port przypisanego do fazy validate
, aby upewnić się, że serwer testowy zostanie uruchomiony na nieużywany port sieciowy, a następnie albo użyj filtrowania zasobów względem zasobów testowych, aby przekazać port testom, albo użyj właściwości systemowej przekazanej przez systemPropertyVariables , aby udostępnić numer portu testom.
Zalety
- Clean Maven build Jeśli testy nie powiodą się, nie można wydać projektu]}
- może przenieść testy integracyjne do osobnego profilu (według Konwencji o nazwie
run-its
), jeśli testy są zbyt wolne do sprawdźcie każdy budynek.
Wady
- trudno uruchomić testy z IDE. Wszystkie testy integracyjne rozpoczynają się / kończą w
IT
i chociaż Maven wie, aby uruchamiać testy rozpoczynające / kończące się wTest
z Surefire i uruchamiać testy rozpoczynające / kończące się wIT
z Failsafe, Twoje IDE prawdopodobnie tego nie robi. dodatkowo, Twoje IDE nie uruchomi kontenera za ciebie, więc musisz wykonać dużo pracy ręcznie, aby faktycznie uruchomić testy ręcznie. -
Debugowanie testów potencjalnie wymaga podłączenia dwóch debugerów, np. jeden do debugowania aplikacji uruchomionej w kontenerze, a drugi do debugowania przypadków testowych .
mvnDebug -Dmaven.failsafe.debug=true verify
Połącz swoje testy z procesem budowania Mavena.
Szkoła 2-osobny moduł
Ta szkoła myślenia przenosi testy integracyjne do oddzielnego modułu, który zależy od modułu war
i kopiuje war
do zasobów testowych za pomocą np. dependency:copy-dependencies
związany z generate-test-resources
Faza połączona z zależnością Tomcat7 do przetestowania.
Same przypadki testowe uruchamiają kontener Tomcat7 za pomocą trybu wbudowanego
Zalety
- testy mogą być uruchamiane w IDE Testy integracyjne są oddzielone od testów jednostkowych, więc poproszenie IDE o uruchomienie wszystkich testów nie spowoduje uruchomienia wolniejszych testów.]}
Wady
-
war
artefakt jest odbudowywany tylko wtedy, gdy przejdziesz przez fazępackage
, w konsekwencji, musisz uruchomić co najmniejmvn clean package
okresowo, aby odświeżyć testowany kod podczas korzystania z IDE. - niepowodzenie testów integracyjnych nie przerywa budowy modułu
war
, więc możesz zwolnić uszkodzony artefaktwar
, a następnie mieć niepowodzenie budowy reaktora dla modułu testów integracyjnych. Niektóre osoby przeciwdziałają temu problemowi, posiadając moduł testów integracyjnych wsrc/it
i używając wtyczki Maven Invoker do uruchamiania testów... chociaż zapewnia to gorszą integrację IDE, więc nie polecam tej linii.
Trudno uzyskać skonsolidowany raport z badań od Mavena.
- musisz zakodować kontener start/zatrzymaj się w swoich testowych przypadkach.
Używasz Failsafe do wykonywania testów, ale same testy są odpowiedzialne za uruchamianie i zatrzymywanie kontenera Tomcat7, który chcę przetestować.
Zalety
- nie trzeba konfigurować uruchamiania/zatrzymywania serwera w Maven pom IDE może bezpiecznie uruchamiać wszystkie testy (choć testy integracyjne mogą być wolniejsze i możesz chcieć ich nie uruchamiać, ale to nie tak, że wszystkie zawiodą, chyba że wystąpi błąd testu)
- łatwiej debugować testy z twojego IDE (tylko jeden proces do dołączenia, a IDE Zwykle ułatwia debugowanie testów, dostarczając specjalny test runner)
Wady
- musisz zakodować kontener start/zatrzymać się od wewnątrz swoich przypadków testowych
Mam nadzieję, że powyższe pomoże Ci zrozumieć opcje, które masz. Mogą wystąpić inne poprawki, ale ogólnie powyższe są obecnie uważane za najlepsze praktyki w testowaniu integracji z Maven.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 09:43:16
@Stephen Connolly - Twoja odpowiedź powyżej była naprawdę dobra. Pomyślałem, że zacznę i pokażę pełną konfigurację dla tego, co nazwałeś odpowiedzią School 1
.
Ta konfiguracja:
- uruchamia testy jednostkowe oddzielnie od testów integracyjnych. Używa adnotacji
@Category
na klasach głównych, które rozszerzają testy jednostkowe i testy integracyjne. - przed testami Integracyjnymi uruchamia aplikację zależną (ładowaną jako zależność Mavena w trybie runtime) na maszynie lokalnej, znajdując open port
- po testach integracyjnych rozkłada zależną aplikację
Są tam inne rzeczy, takie jak ustawianie pewnych właściwości systemu tylko w aplikacji zależnej.
Jak na razie ta konfiguracja działa rewelacyjnie..
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>reserve-network-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<portNames>
<portName>tomcat.maven.http.port</portName>
</portNames>
</configuration>
</execution>
<execution>
<id>get-local-ip</id>
<goals>
<goal>local-ip</goal>
</goals>
<configuration>
<!-- if not given, 'local.ip' name is used -->
<localIpProperty>local.ip</localIpProperty>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- http port from reserve-network-port-plugin-->
<port>${tomcat.maven.http.port}</port>
<!-- application path always starts with /-->
<path>/</path>
<webapps>
<webapp>
<groupId>com.company.other.app</groupId>
<artifactId>web-rest</artifactId>
<version>1.0.1-SNAPSHOT</version>
<type>war</type>
<contextPath>/webapi-loopback</contextPath>
<asWebapp>true</asWebapp>
</webapp>
</webapps>
</configuration>
<executions>
<execution>
<id>start-server</id>
<configuration>
<fork>true</fork>
<skip>${skipTests}</skip>
<systemProperties>
<spring.profiles.active>test,h2</spring.profiles.active>
</systemProperties>
</configuration>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<configuration>
<skip>${skipTests}</skip>
</configuration>
<phase>post-integration-test</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<excludedGroups>com.company.app.service.IntegrationTestRootClassAnnotatedWithAtCategory</excludedGroups>
</configuration>
<executions>
<execution>
<id>unit-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<argLine>-Xmx1024m -XX:MaxPermSize=256m @{jacocoArgLine}</argLine>
<excludedGroups> com.company.app.service.IntegrationTestRootClassAnnotatedWithAtCategory </excludedGroups>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.18</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>start-integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<argLine>-Xmx1024m -XX:MaxPermSize=256m @{jacocoArgLine}</argLine>
<groups>com.company.app.IntegrationTestRootClassAnnotatedWithAtCategory</groups>
<includes>
<include>**/*.java</include>
</includes>
<systemPropertyVariables>
<program.service.url>
http://${local.ip}:${tomcat.maven.http.port}/webapi-loopback
</program.service.url>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-30 17:30:46
Jak wyjaśnia Stephen Connolly, nie ma bezpośredniego sposobu, aby to skonfigurować. Wyjaśnię, jak rozwiązać ten problem za pomocą wtyczki failsafe. W cyklu życia maven można przetestować rodzaj testu. Testowanie jednostkowe jednym z nich, a drugim jest testowanie integracyjne. Testy jednostkowe mogą być przeprowadzane na etapie testowym cyklu życia maven. Jeśli chcesz zrobić test integracyjny, możesz to zrobić na etapie weryfikacji. Jeśli chcesz poznać różnicę między testami jednostkowymi a testami Integracyjnymi, jest to dobry . Przez domyślne klasy testów jednostkowych powinny znajdować się w ***/*Test.java
, oraz **/*TestCase.java
ten format. Wtyczka failsafe będzie szukać **/IT*.java
, **/*IT.java
, oraz **/*ITCase.java
.
Tutaj mam jedną klasę testów jednostkowych i jedną klasę testów integracyjnych. Teraz wyjaśnię, jak powinien wyglądać maven pom.xml. Sekcja budowania konfiguracji Mavena powinna wyglądać tak.
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<warName>${name}</warName>
<outputDirectory>/home/jobs/wso2/wso2as-5.3.0/repository/deployment/server/webapps</outputDirectory>
<goal>
</goal>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12.4</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Testy jednostkowe są przeprowadzane przed wdrożenie aplikacji internetowej (plik war). Ale testy integracyjne są uruchamiane na etapie weryfikacji. Mam nadzieję, że Twoje wymagania są spełnione na tym etapie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:50