我有一个基于Maven的Web应用程序项目,它生成一个可在Tomcat中运行的WAR。让我们假设,为了论证,该项目的单元测试通过网络实际发送/接收请求是非常重要的(而不是简单地用模拟请求调用servlet方法)。
我的测试工具是否有办法在同一个JVM中运行Tomcat实例,加载当前项目,并让测试用例在localhost
上点击它?如果做不到这一点,我将如何以编程方式将当前项目(以及依赖项)打包到WAR中,以便我可以使用Cargo以编程方式将其上载到其他Tomcat实例中?有没有更好的选择,而不仅仅是炮轰mvn
?
我知道我的请求很不寻常,单元测试应该更加独立,等等,但请让我们一起玩:)
答案 0 :(得分:7)
您可以使用embedded Tomcat来实现此目的。只需在测试工具中设置静态实例,并在最后将其关闭。这是一些示例代码:
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class TomcatIntegrationTest {
private static Tomcat t;
private static final int TOMCAT_PORT = 9999;
@BeforeClass
public static void setUp() throws LifecycleException {
t = new Tomcat();
t.setBaseDir(".");
t.setPort(TOMCAT_PORT);
/* There needs to be a symlink to the current dir named 'webapps' */
t.addWebapp("/service", "src/main/webapp");
t.init();
t.start();
}
@AfterClass
public static void shutDownTomcat() throws LifecycleException {
t.stop();
}
}
答案 1 :(得分:6)
Jetty非常适合这个目的。如果你没有被迫拥有Tomcat,你可以在集成测试阶段很容易地使用它。预集成启动jetty,后集成停止它,你可以在war文件中抛出请求,因为它在一个实际的容器中运行。
答案 2 :(得分:2)
我建议创建适当的集成测试,并使用以下设置在maven构建期间进行集成测试。
您可以使用以下部分下载tomcat,或者如果您需要使用存储库中的工件。
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<wait>false</wait>
<container>
<containerId>tomcat${tomcat.major}x</containerId>
<zipUrlInstaller>
<url>http://archive.apache.org/dist/tomcat/tomcat-${tomcat.major}/v${tomcat.version}/bin/apache-tomcat-${tomcat.version}.tar.gz</url>
<extractDir>${project.build.directory}/extract/</extractDir>
<downloadDir>${project.build.directory}/download/</downloadDir>
</zipUrlInstaller>
<output>${project.build.directory}/tomcat${tomcat.major}x.log</output>
<log>${project.build.directory}/cargo.log</log>
</container>
<configuration>
<home>${project.build.directory}/tomcat-${tomcat.version}/container</home>
<properties>
<cargo.logging>high</cargo.logging>
<cargo.servlet.port>9080</cargo.servlet.port>
<cargo.tomcat.ajp.port>9008</cargo.tomcat.ajp.port>
</properties>
</configuration>
</configuration>
下一部分用于启动并将您的应用程序部署到给定的tomcat中(也使用jetty)。
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
<configuration>
<deployer>
<deployables>
<deployable>
<groupId>${project.groupId}</groupId>
<artifactId>mod-war</artifactId>
<type>war</type>
<pingURL>http://localhost:9080/mod-war</pingURL>
<pingTimeout>30000</pingTimeout>
<properties>
<context>mod-war</context>
</properties>
</deployable>
</deployables>
</deployer>
</configuration>
</execution>
当然最终通过以下方式停止启动的服务器:
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
最好的办法是将这种配置等放入一个单独的maven模块中,该模块可能被称为app-it(用于集成测试)。
可以简单地调用完整的测试周期mvn verify
而在验证生命周期中,集成测试阶段将运行并启动上述配置。但是配置maven-failsafe-plugin以使集成测试本身正在运行非常重要。有关此内容的详细说明,请参阅Maven Unit- and Integration Test Guide
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
答案 3 :(得分:0)
你可以做的是用Apache生成一个带有tomcat maven插件的原型,见http://tomcat.apache.org/maven-plugin-2.0/archetype.html。
您将拥有各种样本:
HTH