当前位置: 首页 > 知识库问答 >
问题:

Maven-在JUnit测试之前将webapp部署到tomcat

庄宇
2023-03-14

我有提供Web服务的webapp。我想使用SoapUI执行JUnit测试以检查此服务是否正常工作。
但是要测试Web服务应用程序必须部署到我的Tomcat 7服务器上。

我不知道如何配置maven来构建war,然后将其部署到tomcat(理想情况下:为此运行单独的tomcat实例),然后运行JUnit测试。< br >我将感谢任何帮助。

我正在使用 maven 2.2.1

共有3个答案

赫连宏伯
2023-03-14

正如Stephen Connolly解释的那样,没有直接的方法来配置它。我将解释如何使用故障安全插件解决这个问题。在maven生命周期中,可以测试测试类型。其中一个是单元测试,另一个是集成测试。单元测试可以在maven生命周期的测试阶段运行。当你想做集成测试时,可以在验证阶段完成。如果你想知道单元测试和集成测试的区别,这是一个很好的方法。默认情况下,单元测试类应该采用< code>***/*Test.java和< code>**/*TestCase.java这种格式。故障保护插件将寻找< code>**/IT*。java、< code>**/*IT.java和< code>**/*ITCase.java。

这里我有一个单元测试类和一个集成测试类。现在我将解释,maven配置的构建部分应该是这样的。

<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>

单元测试在部署Web应用程序(war文件)之前运行。但是集成测试是在验证阶段运行的。我希望您的要求在这个阶段得到满足。

岑叶秋
2023-03-14

@斯蒂芬·康诺利-你上面的回答真的很好。我想我应该开始并展示你所说的学校1响应的完整配置。

此配置:

  • 独立于集成测试运行单元测试。它使用单元测试和集成测试扩展的根类上的@Category批注。
  • 集成测试之前,它通过查找打开的端口在本地计算机上启动依赖应用程序(在运行时作为 Maven 依赖项加载)
  • 集成测试后,它会拆除依赖的应用程序

还有其他内容,比如如何只在依赖的应用程序上设置某些系统属性。

到目前为止,这种配置运行得很好。。

<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>
满玉泽
2023-03-14

关于如何使用Maven处理这种类型的集成测试,有很多流派。

我应该指出,当您将应用程序部署到应用程序服务器时,您不再处于单元测试的领域。因为整个应用程序都部署在一个容器中,所以您正在测试这两个组件的集成。

现在使用JUnit运行集成测试没有错(尽管您可能会遇到一些限制,例如单元测试不应该关心单个测试的顺序——假设您编写的是正确的——所以JUnit通过不保证任何执行顺序来强制执行这一点…在Java1.7之前,执行顺序是由类中测试方法的顺序偶然暗示的,但它不是JUnit契约的一部分…有些人会切换到其他测试框架进行集成测试,例如TestNG,如果他们发现JUnit的单元测试焦点妨碍了他们的测试开发)

要记住的关键点是,Maven 生命周期使用测试阶段来执行单元测试

当谈到集成测试时,有两个(半个)学派认为如何用Maven处理测试。

这一思想流派使用之后的阶段来启动容器、运行集成测试、拆除容器,最后检查测试结果并在测试失败时使构建失败。

永远不要运行 MVN 集成测试,因为这不会正确拆除容器,任何时候您认为要键入 MVN 集成测试时,您实际上都想键入 MVN 验证(哦,看,它更短,更容易键入也......奖金)

因此,您可以执行以下操作:

    < li >绑定tomcat7:运行到< code > fork < code > = true 的< code >预集成测试阶段 < li >将故障保护:集成测试绑定到< code >集成测试阶段 < li >将tomcat7:shutdown绑定到< code >集成后测试阶段 < li >绑定故障保护:验证到< code >验证阶段。

对于额外的加分,您可以使用build-helper-maven-plugin:reserve-network-port绑定到< code>validate阶段,以确保测试服务器是在一个未使用的网络端口上启动的,然后或者对测试资源使用资源过滤来将端口传递给测试,或者使用通过systemPropertyVariables传递的系统属性来使端口号对测试可用。

    < li >清除Maven版本 < li >如果测试失败,您将无法发布该项目 如果测试太慢而不能运行每个构建,那么< li >可以将集成测试移到一个单独的概要文件中(习惯上称为< code>run-its)。

> < li >很难从IDE中运行测试。所有的集成测试都在< code>IT中开始/结束,虽然Maven知道用Surefire运行在< code>Test中开始/结束的测试,用Failsafe运行在< code>IT中开始/结束的测试,但是您的IDE可能不知道。此外,您的IDE不会为您启动容器,因此您必须手动做大量的工作来实际手动运行测试。 < li>

调试测试可能需要附加两个调试器,例如,一个调试器用于调试在container中运行的应用程序,另一个调试器用于调试测试用例。

mvnDebug -Dmaven.failsafe.debug=true verify

将您的测试与Maven构建过程结合起来。

这个学派将集成测试移到一个独立的模块中,该模块依赖于< code>war模块,并使用例如绑定到< code > generate-test-resources 阶段的< code > dependency:copy-dependencies 将< code>war复制到测试资源中,并结合一个Tomcat7依赖项进行测试。

测试用例本身使用嵌入式模式启动Tomcat7容器

  • 测试可以在IDE中运行
  • 集成测试与单元测试分开,因此要求IDE运行所有测试不会启动较慢的测试
  • warartifact仅当您通过阶段时才会重新生成,因此,在使用IDE时,您需要至少定期运行
  • 集成测试的失败不会破坏war模块的构建,因此您可以最终发布一个损坏的war工件,然后使集成测试模块的Reactor构建失败。一些人通过在src/it中使用集成测试模块并使用MavenInvoker插件来运行测试来解决这个问题……尽管这提供了较差的IDE集成,所以我不建议使用这一行
  • 很难从Maven获得一份综合测试覆盖率报告
  • 必须对容器进行编码,从测试用例中启动/停止自己

这是两种方法的混合。

您使用Failsafe来执行测试,但是测试本身负责启动和停止您想要在其中进行测试的Tomcat7容器。

  • 不必在Maven pom中配置服务器启动/停止
  • IDE可以安全地运行所有测试(尽管集成测试可能会更慢,您可能不想运行它们,但除非有测试失败,否则它们不会全部失败)
  • 更容易从IDE调试测试(只有一个进程可以附加,IDE通常通过提供特殊的测试运行程序来轻松调试测试)
  • 必须从测试用例中编写容器启动/停止代码

我希望以上能帮助您理解您所拥有的选项。可能还有其他调整,但总的来说,以上被认为是目前与Maven集成测试的最佳实践。

 类似资料:
  • 我对Tomcat和Docker还很陌生--所以我可能在这个问题中遗漏了一个Tomcat基础知识。 我试图做的是构建一个Docker容器,该容器运行一个springboot Restful web服务,该服务只返回一些静态数据。这都是在OSX上运行的,所以我也使用了Boot2Docker。 我编写了自己的Dockerfile来构建我的应用程序运行的容器: 这个Dockerfile工作良好,并且我能够

  • 我有根项目,然后是子模块。这些模块是相互依赖的,当我为一个模块运行maven测试时,它会抛出类未找到异常。 ProjectA --ProjectSubA --ProjectSubB --ProjectSubC(依赖项ProjectA和ProjectB) ProjectSubC有Maven测试,所以当它运行时,类在ProjectSubB和ProjectSubA中。现在如何解决这个问题。

  • 我正在尝试构建/部署/运行这个maven/apache tomcat项目LODE。 这是我第一次看到这种风格的java web应用程序。我遵循了该项目网站上提供的说明。从maven clean安装开始。然后生成一个src文件夹,其中包含一个java文件夹(包含java类)和一个webapp文件夹(包含web资源),见图。 我习惯于有一个WebContent文件夹,可以生成WAR文件。 如何将此项目

  • 我是一名Azure新手,试图以自动CI/CD方式安装WebApp。 如果我在CLI shell中登录,我可以通过 az webapp部署源配置--name${webapp_name}--资源组${RESOURCEGROUP_name}--插槽暂存--repo url${GIT_url}--分支${branch}--手动集成 我想使用Jenkins中的shell(不使用Azure插件)来实现这一点。

  • 我主要使用本教程为Maven配置Junit:http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html 我有一个测试类,当我执行“mvn测试”时,这个测试类被Maven捕获,但Maven没有检查它(结果应该是失败)。 我的测试类位于src/main/resources中(控制台显示“复制1个资源”): 我的P

  • 我正在开发简单的JAX-WS WebService。我正在使用ANT构建脚本创建WAR文件。该文件在部署到Tomcat7服务器时,抛出以下异常,并出现如下部署错误。 JAXB 2.1 API是从bootstrap classloader加载的,但是这个RI(从jar:file:/d:/dreamsoln/server/apache-tomcat-7.0.29/webapps/webserviced