与Arquillian的集成测试

自Java Enterprise Edition诞生以来,容器组件及其交互的测试一直是一个痛点。 传统上很难模拟他们与其他服务的合作。 随着容器功能的增加(依赖注入等),交叉链接和依赖关系也在增长。 一个完全自动化的集成测试套件以前由许多JUnit测试组成。 现在, Arquillian的目标是通过提供第一个完整的集成测试套件来进行集成测试,从而使这项任务变得更加容易。

JBoss项目Arquillian的任务很容易。 这是关于提供一个简单的测试框架。 目的是从实际的测试逻辑中删除所有容器生命周期和部署任务,并使开发人员能够为其企业Java应用程序构建广泛的集成测试。 与Arquillian轻松进行集成测试。 自Java EE诞生以来,测试企业应用程序一直是任何项目的主要挑战。 在某些情况下,不可能对技术组件进行单独的测试,因为简单的单元测试通常是不够的。 这样做的主要原因之一是组件的设计。 它们很少被完全隔离,并且经常依赖于它们的运行时和其他组件。

从总体上讲,这些方面与组件执行的技术工作一样重要。 即使进行了干净的层分离,也需要结合所谓的Mocks(接口模拟)和单元测试来对接口和组件的已实现逻辑进行集成测试。 尽管存在所有潜在的问题,但目标容器的实际行为仍然未经测试。 事务控制,依赖项注入或其他声明性服务都无法得到充分测试。 通常,这是最终的公开问题之一,即是否绑定了正确的服务或传输的数据实际上是否采用了正确的格式。 但是,确保这一点是公司开发过程中必不可少的部分,被称为集成测试。 只有少数经验丰富的开发人员才能设计自动集成测试并定期执行这些测试。 这导致了项目的许多稳定性问题。 JBoss项目Arquillian试图消除这种缺陷。 它使开发人员可以轻松地运行容器组件的集成测试。 这些部署在本地(嵌入式)容器还是远程容器上都没有关系。 Arquillian的想法是使集成测试与单元测试一样简单。

一般建筑

Arquillian(图1)连接一个单元测试框架(JUnit或TestNG),ShrinkWrap和一个或多个受支持的容器(Java EE容器,Servlet容器,Java SE CDI环境等)。

与Arquillian的集成测试

本质上,它是JUnit和TestNG的自定义测试运行程序,它将对各个测试实现的测试生命周期的控制权转移给Arquillian。 从那里Arquillian代表前往相应的环境,以在容器内或针对运行时进行测试。 Arquillian测试用例看起来仍然几乎与普通的JUnit或TestNG测试用例相似。 测试用例基本上涵盖了三个方面。 测试用例本身,即部署,必须打包到存档中,最后但并非最不重要的是,打包到运行时。

部署过程或实际的容器控制都不是很神奇的事情。 通过ShrinkWrap将测试用例打包成适合目标运行时的正确格式。 这也是Arquillian测试生命周期的真正开始。 它定义了测试用例的基础,在运行时提供了合适的存档,并将其部署在目标容器上。 之后,将开始实际执行测试用例并收集结果。 最后,存档将从运行时删除(取消部署)。 到目前为止,仅支持几个开源容器。 JBoss(> = 5),GlassFish(> = 3),Jetty(> = 6.1),Tomcat 6,Weld SE和EE 1.0或1.1、1.0,IronJacamar 1.0,OpenWebBeans Apache 1.0和Apache OpenEJB 3.1就是其中之一。 根据制造商的说法,未来的支持还将涵盖商业平台,例如Oracle的WebLogic或IBM的WebSphere。

第一步

如果您想今天就开始使用Arquillian,则应该注意,这仍然是Alpha版。 您可以从git下载完整的存档,也可以从源代码构建它。 以下示例使用基于Arquillian 1.0.0.Alpha4的Arquillian Examples项目。 如果您尝试此Alpha版本,则您不是早期追随者,而是领导者。 您需要一整套崭新的技术。

除了Maven 3.0,还需要当前的1.6 Java开发工具包(JDK)。 安装必要部分的最佳方法是安装完整的开发环境,并将带有示例的ZIP文件解压缩到任何目录中。 最有趣的用例当然是对Enterprise Java Bean(EJB)的测试。 与GlassFish Embedded Server 3.1结合使用时,它已作为预配置示例包含在内。 在文件夹ejb31-gfembedded中找到它。 所有示例都使用Maven运行。 要将嵌入式GlassFish用作容器,请在项目pom.xml中创建所需的配置文件“ glassfish-embedded-3”。 该示例使用“ mvn test-Pglassfish-embedded-3”命令执行。 一个简单的班轮响应任何运行或错误。 如果一切运行顺利,您将看到:测试运行:1,失败:0,错误:0,跳过:0,经过时间:9828秒。 如果这种方法不能立即生效,则必须检查并解决一些潜在问题。 导致任何错误的第一大原因是未知的或缺少Maven存储库条目。 Arquillian库位于公共JBoss存储库中 应该从您的pom.xml甚至settings.xml中引用它。 如果遇到任何java.net.ConnectExceptions,则可能是Embedded GlassFish中的一个已知错误。 它会阻止大于3.1 b04的版本脱机工作,因为它正在检查所需的xml模式文件。 如果您坐在代理或防火墙后面,也会发生同样的情况。 在这种情况下,您需要通过Surefire插件添加一些配置参数(SystemProperties,http.proxyHost和http.proxyPort)。 但是,在其他情况下,最新的Arquillian Alpha也无法与最新的GlassFish位一起运行。

在GlassFish 3.1的开发过程中,嵌入式API发生了变化。 这应该在Arquillian的下一个发行版中得到反映。 因此,如果您需要更新的版本,则应等待一点时间让Arquillian提供更新的版本。

如果遇到其他错误,一开始基本上是无助的。 Arquillian日志消息通常很少见。 因此,您需要对配置进行更深入的研究。 默认情况下,GlassFish的根目录保留在由Maven创建的目标文件夹中。 每次测试运行都会在此处创建一个新目录。 您可以通过更改arquillian.xml配置文件来更改此行为。 它属于srctestresources文件夹,应如下所示:

与Arquillian的集成测试

使用此配置,每次运行测试时使用的GlassFish目录始终位于同一位置。 现在,您可以通过更改domain.xml,*地对嵌入式GlassFish配置进行任何其他输入。 但是您是否仍然错过详细的日志记录? 然后,您必须动手使用logging.properties文件。 只需从现有GlassFish域中复制它,并将其添加到您的开发项目中(例如srctestgf)。 将其作为系统属性(java.util.logging.config.file)解析到Surefire插件。 如果现在重新运行测试,则可以看到容器日志消息。

另一个非常有用的工件是拥有Arquillian正在部署的打包档案的版本。 这也很简单。 将以下条目添加到arquillian.xml。

与Arquillian的集成测试

除了满足您的好奇心,这在将来的调试中尤其有用。 尤其是如果生成的归档文件可以成功地部署到独立的glassfish上,它可以确保您最有可能遇到一些并非项目开发人员的错的问题。

第一个简单的测试用例

完成所有准备工作后,就该投入时间进行实际的测试功能了。 要测试容器中的组件,必须存在该组件。 一个简单的无状态会话Bean HelloEJB就足以作为第一个示例:

与Arquillian的集成测试

目前,世界上最著名的示例EJB正在使用相应的测试用例进行审查:

与Arquillian的集成测试

@RunWith JUnit批注可确保使用Arquillian测试运行器。 之后,您只需注入HelloEJB。 @Deployment批注声明包装实际EJB归档的方法。 实际测试用例由JUnit中的注解@Test以已知样式启动。 assertEquals根据固定的输入字符串检查返回值。 如果两个字符串匹配,则测试成功。 所有其他情况都会产生错误。 乍一看,这个简单的错误通常不会说太多。 因此,您必须检查targetsurefire-reports文件夹以获取详细信息。 每个测试用例在文本和xml文件中产生一个结果。 这不是很方便,但是您必须为此责怪Surefire,而不是Arquillian。 如果将EJB调用更改为强制错误的任何内容(例如sayHelloEJB(“ Markus”)),则可以找到特定的错误:

与Arquillian的集成测试

更多容器功能

通过与上述类似的方式,您可以使用Arquillian测试几乎所有容器功能,最简单的情况就是无状态EJB。 当必须提供具有适当资源(例如数据库或接口)的运行时,或者需要上下文和依赖项注入(CDI)时,它将变得更加复杂。 但是即使对于这样的要求,Arquillian也有解决方案。 最简单的情况是使用CDI。 要在您的测试用例中启用CDI,您只需要将一个空的beans.xml文件添加到测试档案中。 这可以通过以下方法实现:

与Arquillian的集成测试

从现在开始,可以访问CDI函数,因为test.jar在META-INF文件夹中包含必需的beans.xml。 另一个选择是将适当的beans.xml与内容一起使用。 为此,必须将其放入项目的资源目录中并进行相应引用:

与Arquillian的集成测试

到目前为止,我们测试的所有内容都使用GlassFish Embedded API完成。 如果希望测试Java Persistence API(JPA)应用程序,则必须切换容器,因为仅远程GlassFish容器支持这些容器。 这要求更改整个Arquillian配置。 远程部署由JSR-88 API支持。 如果您正在寻找一些好的示例,则可以查阅《 Arquillian用户指南》。

Arquillian基本上设法测试了所有可以直接注入或通过促进CDI功能注入的内容。 除了前面的示例,您还可以使用它来测试JMS连接。 为此,就像添加适当的队列,主题和连接工厂一样简单:

与Arquillian的集成测试

Arquillian作为客户

对外部系统表示进行测试与从内部集中进行应用程序测试一样重要。 您应该在人们或程序用于与应用程序交互的界面上花费尽可能多的时间。 通常,应确保每个应用程序及其执行路径都经过全面测试。 第三方可以通过各种接口(例如Web服务,EJB)或通过http远程与应用程序进行交互。 如果您要解决此问题,则必须考虑很多事情,例如对象序列化和网络连接。 为了在环境上测试此视图,Arquillian提供了两种模式:IN_CONTAINER和AS_CLIENT。 IN_CONTAINER模式对应于上面显示的示例。 AS_CLIENT允许检查应用程序的外部视图。 运行AS_CLIENT模式就像向您的测试用例添加另一个注释一样简单:

与Arquillian的集成测试

与IN_CONTAINER方式进行直接比较,客户端尝试在容器中执行尽可能少的任务,并自然地充当客户端。 @Deployment方法仅控制容器的生命周期。

调试和Eclipse集成

如果您不喜欢Arquillian测试中痛苦的cmd线maven执行,则可以*地将其集成到您喜欢的IDE中,只要它是Eclipse或NetBeans或根本没有任何Maven集成即可。 Eclipse要求您使用m2eclipse插件。 您需要**相关的Maven配置文件,然后才能开始使用“运行方式| JUnit Test从IDE运行单独的测试。 NetBeans不需要单独的插件。 自6.8版以来,它已支持Maven。 在这里,也需要添加活动的Maven配置文件。 配置已经完成。 调试基本上遵循与其他已部署应用程序相同的特征。 测试运行程序和测试在与容器本身不同的JVM中运行。 因此,调试器必须附加到正确的JVM。 可以在您选择的容器文档中找到有关此内容的详细信息。

结论

使用Arquillian很有趣。 在无缝容器集成方面,没有任何可比的市场。 它使用起来非常简单,并且配置起来并不难。 只需几分钟即可创建简单的测试用例。 权衡是,它很快变得复杂。 容器的配置仅是一个区域。 您的部署越复杂(例如,依赖库,特殊的类路径配置),则设置难度就越大。 Arquillian仍然是Alpha版本,在撰写本文时尚未完成。 目前有些事情根本不起作用。 如果您遇到麻烦,可能会很快消耗时间。

要找出问题出在哪里,您需要时间和知识。 Arquillian的核心日志不会太多。 要找到真正的错误并不容易。 但是该项目尚未完成。 已经宣布了几个功能。 除了方法拦截器,所谓的Arquillian Resources应该在下一个版本中可用。 这将使所有特定于容器的对象(例如初始上下文)都可以通过通用@ArquillianResource注释注入。 对其他容器的支持也在列表中。

这将是令人兴奋的,值得进一步观察。 该项目的进度有些落后,应该尽快提出下一个发展里程碑。


翻译自: https://jaxenter.com/integration-tests-with-arquillian-103200.html