旧服务器上的Arquillian

在大多数情况下,当某事不起作用时,您只需Google错误并已基本完成。 对于在技术方面落后的组织工作,一件好事是,它通常更具挑战性,并且您一定具有创造力。 我,我坚持使用JBoss 5.1 EAP,但这并不能阻止我尝试在软件工程中使用现代方法。 在质量领域,这样的尝试是能够为我的开发人员提供一种在容器中测试其代码的方法。 由于我们是EJB3领域的新手,因此这意味着他们将需要进行真正的集成测试。

考虑到撰写本文时可用的堆栈,我决定选择Arquillian,这似乎是实现此目的的最佳(也是唯一的)工具。 有了这个框架(以及我忠实的TestNG),我就可以在JBoss 5.1 EAP上测试Java EE组件。 本文介绍了如何做到这一点(以及提及我必须克服的陷阱)。

Arquillian基础

Arquillian基本上为开发人员提供了一种管理应用程序服务器生命周期并在其中部署JavaEE工件的方法,该方法可以自动化并与您喜欢的测试引擎集成(如果需要,请阅读TestNG-或JUnit)。 Arquillian体系结构基于通用引擎和特定应用程序服务器的适配器。 如果您的应用程序服务器没有可用的适配器,那真是不幸。 如果您觉得很有趣,请尝试搜索WebSphere适配器...开发一个适配器。 第一个困难是,在我工作时,没有JBoss EAP 5.1适配器,但是我从网络上得知它介于5.0 GA和6.0 GA之间:冗长的反复试验过程(现在,至少有一些文档 ,这要感谢Arquillian的人在Twitter上听到我的请求-谢谢!)。

服务器类型和版本不足以获取正确的适配器,您还需要选择与应用程序服务器交互的方式:

  • 嵌入式:下载所有依赖项,提供配置和权限,Arquillian神奇地创建了一个正在运行的嵌入式应用程序服务器。 专业人士:您不必在每台开发人员计算机上都安装应用服务器; 缺点:配置很可能是一场噩梦,最终平台可能会有巨大差异,无法达到集成测试的目的。
  • 远程:使用现有且正在运行的应用程序服务器。 在适合所有开发人员的专用服务器(他们将共享相同的配置,但也使用相同的资源)和每个开发人员的单个应用程序服务器(谁说维护噩梦?)之间明智地选择。
  • 托管:与远程相同,但是测试将启动和停止服务器。 每个开发人员更适合一台应用服务器。
  • 当地人:即使发现它很深,我也发现了它的痕迹。 这似乎与托管相同,但是它使用文件系统而不是有线来完成其工作(通过调用脚本来启动/停止,通过将归档文件复制到期望的位置来进行部署...),因此称为本地。

可以根据需要通过arquilian.xml文件配置每个适配器。 对于Maven用户,它发生在src/test/resources的根目录下。 不用担心,每个适配器都有适当的配置参数文档。 我的看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<arquillianxmlns="http://jboss.org/schema/arquillian"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
    <containerqualifier="jboss"default="true">
        <configuration>
            <propertyname="javaHome"> ${jdk.home} </property>
            <propertyname="jbossHome"> ${jboss.home} </property>
            <propertyname="httpPort"> 8080 </property>
            <propertyname="rmiPort"> 1099 </property>
            <propertyname="javaVmArguments"> -Xmx512m -Xmx768m -XX:MaxPermSize=256m
                -Djava.net.preferIPv4Stack=true
                -Djava.util.logging.manager=org.jboss.logmanager.LogManager
                -Djava.endorsed.dirs=${jboss.home}/lib/endorsed
                -Djboss.boot.server.log.dir=${jboss.home}
                -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
            </property>
        </configuration>
    </container>
</arquillian>

最后,测试类本身必须扩展org.jboss.arquillian.testng.Arquillian (或者如果坚持使用JUnit,请使用@RunWith )。 以下代码片段显示了使用Arquillian的TestNG测试类的示例:

publicclassWebITextendsArquillian{

    @Test
    publicvoidtestMethod(){...}

    @Deployment
    publicstaticWebArchivecreateDeployment(){...}
}

创建档案

关于容器内测试的Arquillian策略是仅部署您需要的内容。 因此,它附带了一个名为ShrinkWrap的工具,可让您仅打包要测试的相关部分。

例如,以下示例创建一个名为web-test.war的存档,将ListPersonServlet类和Web部署描述符绑定ListPersonServlet 。 更高级的用途将包括库。

WebArchivearchive=ShrinkWrap.create(WebArchive.class,"web-test.war")
    .addClass(ListPersonServlet.class)
    .setWebXML(newFile("src/main/webapp/WEB-INF/web.xml"));

Arquillian框架将寻找一个static方法,该方法以@Deployment批注并返回此类存档,以便将其部署到应用程序服务器(通过适配器)。

提示:如果有错误,请在存档上使用toString()方法查看其中包含的内容。

Maven蛋糕上的糖霜

即使您不是Maven爱好者,我也认为这一点值得关注。 恕我直言,集成测试不应该是构建过程的一部分,因为它们本质上更加脆弱:在应用服务器上发生简单的配置错误,并且构建失败而没有真正的原因。

因此,我建议将您的测试放在一个单独的模块中,而不由其父级调用。

此外,我还使用了Maven Failsafe插件,而不是Surefire插件,这样我就可以清晰地分离单元测试和集成测试,甚至使用分离的模块,也可以同时获得不同的度量标准(例如在Sonar中)。 为了使分离立即可用,只需确保测试类以IT结尾(例如Integration Test)。 请注意,就在install之前,集成测试已绑定到integration-test生命周期阶段。

JBoss EAP来了

现在是最困难的部分,即在JBoss 5.1 EAP上的实际部署。 这个阶段可能会持续很长时间,并且涉及很多来回过程。 为了尽可能提高生产力,要做的第一件事就是找到日志。 如果保留上述配置,则它们位于JBoss <profile>/logs目录中。 如果您觉得日志过于冗长(我确实如此),只需将根优先级从${jboss.server.log.threshold}更改为<profile>/conf/jboss-log4j.xml文件中的INFO

在我的机器上,我不断收到JVM绑定端口错误。 因此,我更改了server.xml文件中的有罪连接器端口(仅供参考,这是AJP连接器,当我将8009更改为8010时,JBoss停止抱怨了)。

EAP的最后一步是禁用安全性。 由于它是面向企业的,因此默认情况下在EAP中启用了安全性:在测试上下文中,我对身份验证以部署我的工件并不在乎。 打开<profile>/deploy/profileservice-jboss-beans.xml配置文件,然后搜索“注释此列表以禁用对profileservice的身份验证检查”。 按照提示进行操作🙂或者,您也可以走硬路并配置身份验证: 适配器页面上提供了详细说明。

自行完成工作

到目前为止,我们或多或少遵循了此处和此处的指示。 现在,我们必须钉住指甲并使用一些灰质。

  • 首先要解决的是启动测试时出现的一些奇怪的java.lang.IllegalStateException。 奇怪的是,这是由于Arquillian缺少一些必须与实际代码一起被ShrinkWrapped的库而引起的。 就我而言,我的网络归档文件必须包含以下代码段:
    MavenDependencyResolverresolver=DependencyResolvers.use(MavenDependencyResolver.class);
    archive.addAsLibraries(
    resolver.artifact("org.jboss.arquillian.testng:arquillian-testng-container:1.0.0.Final")
            .artifact("org.jboss.arquillian.testng:arquillian-testng-core:1.0.0.Final")
            .artifact("org.testng:testng:6.5.2").resolveAsFiles());
  • 下一个错误要严重得多,它来自Arquillian内部工作原理。
    java.util.NoSuchElementException
        atjava.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:375)
        atjava.util.LinkedHashMap$KeyIterator.next(LinkedHashMap.java:384)
        atorg.jboss.arquillian.container.test.spi.util.TestRunners.getTestRunner(TestRunners.java:60)

查看代码时,您会看到Arquillian使用Service Provider功能(有关更多信息, 请参见此处 )。 但是令我非常恼火的是,它没有配置org.jboss.arquillian.container.test.spi.TestRunner服务应该使用的实现,因此失败了。 我们必须手动创建这样的配置:该文件应仅包含org.jboss.arquillian.testng.container.TestNGTestRunner (因为这是服务提供商的强大功能)。别忘了将其打包在归档文件中以包含任何内容成功的机会:

archive.addAsResource(newFile("src/test/resources/META-INF/services"),"META-INF/services");

更新[5月28日] :如果使用正确的Maven依赖项(Arquillian BOM),则可以忽略上述两点。 检查附加项目中的POM。

最后,除了测试中的最终消息日志外,其他所有东西都应该工作正常:

Shutting down server: default
Writing server thread dump to /path/to/jboss-as/server/default/log/threadDump.log

这意味着Arquillian无法关闭服务器,因为它无法进行身份验证。 这不会有任何后果,但会将测试标记为失败,因此需要进行更正。 编辑<profile>/conf/props/jmx-console-users.properties文件,并取消注释admin = admin行。

结论

之前的全部步骤使我大约花了半个星期的时间分散在一周内(由于我的大脑启动了一些解决问题的后台线程,因此我似乎在不全职工作时效率更高)。 这并非易事,但我为击败该死的事情感到自豪。 此外,本文省略了几个专有的配置设置。 总之,Arquillian似乎是一个不错的容器内测试框架,但似乎必须加以完善:我认为使用TestNG可能是这里的罪魁祸首。

您可以在此处以Eclipse / Maven格式找到本文的资源。

翻译自: https://blog.frankel.ch/arquillian-on-legacy-servers/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值