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

Author: Michał Herman, 2013-06-05

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:

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ę w Test z Surefire i uruchamiać testy rozpoczynające / kończące się w IT 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 najmniej mvn 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 artefakt war, 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 w src/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.
[[54]}Szkoła 2.5-Failsafe z przypadkami testowymi uruchamiającymi własny serwer Tomcat7 [55]} Jest to rodzaj hybrydy obu podejść.

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.

 113
Author: Stephen Connolly,
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>
 1
Author: Matt,
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.

Oto przykład. Tutaj wpisz opis obrazka

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.

 0
Author: GPrathap,
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