Arquillian功能测试中如何使用Maven耳神器?
How to use a Maven ear artifact in Arquillian functional testing?
到目前为止,我遇到的所有示例都使用 Arquillian 的 @Deployment(testable = false) public static Archive<?> createDeployment()
来构建自己的 WebArchive
或 EnterpriseArchive
,这允许以快速和独立的方式测试应用程序的各个部分。但是,据我所知,在 install
阶段完成后,即在单独的模块 运行 在 EAR 组件之后,例如与
@Deployment(testable = false)
public static Archive<?> createDeployment() {
EnterpriseArchive retValue = Maven.configureResolver().workOffline().resolve("richtercloud:arquillian-ear-it-ear:ear:1.0-SNAPSHOT").withoutTransitivity().asSingle(EnterpriseArchive.class);
retValue.writeTo(System.out, Formatters.VERBOSE);
return retValue;
}
这样就可以进行类似
的测试
@Drone
private WebDriver browser;
@ArquillianResource
private URL deploymentUrl;
@FindBy(id = "mainForm:saveButton")
private WebElement saveButton;
@Test
public void testWebFrontend() throws IOException {
browser.get(deploymentUrl+ "/index.xhtml");
seleniumHelper.screenshot(browser);
Assert.assertTrue(saveButton.isDisplayed());
}
这目前失败了,因为注入的部署 URL 忽略了应用程序的 context-path
,导致对 index.xhtml
的请求由于 The requested resource is not available
和 HTTP 错误 404 而失败.
有趣的是,EAR 的 web 模块存在于本地 Maven 缓存安装中,但在列表中缺失。在用 retValue.addAsModule(Maven.configureResolver().workOffline().resolve("richtercloud:arquillian-ear-it-web:war:1.0-SNAPSHOT").withTransitivity().asSingle(WebArchive.class));
明确添加它之后仍然是这种情况,我根本不理解。也许我误解了 Shrinkwrap 解决的问题。
版本是
<properties>
<powermock.version>1.7.0RC4</powermock.version>
<version.org.jboss.arquillian>1.1.5.Final</version.org.jboss.arquillian>
<version.org.wildfly>8.1.0.Final</version.org.wildfly>
<version.junit>4.12</version.junit>
<browser>phantomjs</browser>
</properties>
<dependencies>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>arquillian-ear-it-jar</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.1</version>
</dependency>
<dependency>
<groupId>net.glxn</groupId>
<artifactId>qrgen</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>validation-tools</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sf.jmimemagic</groupId>
<artifactId>jmimemagic</artifactId>
<version>0.1.3</version>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.ocpsoft.prettytime</groupId>
<artifactId>prettytime</artifactId>
<version>3.2.7.Final</version>
</dependency>
<dependency>
<groupId>org.bitbucket.cowwoc</groupId>
<artifactId>diff-match-patch</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.rauschig</groupId>
<artifactId>jarchivelib</artifactId>
<version>0.7.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- Java EE integration testing -->
<dependency>
<groupId>org.jboss.shrinkwrap.descriptors</groupId>
<artifactId>shrinkwrap-descriptors-api-javaee</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.graphene</groupId>
<artifactId>graphene-webdriver</artifactId>
<version>2.3.2</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.codeborne</groupId>
<artifactId>phantomjsdriver</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>phantomjsdriver</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>htmlunit-driver</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.26</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>jsf-validation-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>selenium-tools</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.14.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.selenium</groupId>
<artifactId>selenium-bom</artifactId>
<version>3.7.0</version>
<!-- - 3.3.1, 3.2.0 and 3.1.0 cause required: java.util.function.Function<? super org.openqa.selenium.WebDriver,V>
found: org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement>
reason: cannot infer type-variable(s) V
(argument mismatch; org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement> cannot be converted to java.util.function.Function<? super org.openqa.selenium.WebDriver,V>)
- 3.0.1 causes java.lang.IllegalAccessError: tried to access class org.openqa.selenium.os.ExecutableFinder from class org.openqa.selenium.phantomjs.PhantomJSDriverService when using phantomjs driver
- 3.6.0 causes `Unrecognized platform: linux-unknown-64bit`
which one is supposed to work around using 3.5.3
<ref>https://github.com/SeleniumHQ/selenium/issues/4781</ref>-->
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-drone-bom</artifactId>
<version>2.4.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>arquillian-glassfish-embedded</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3.1</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>fish.payara.extras</groupId>
<artifactId>payara-embedded-all</artifactId>
<version>4.1.2.174</version>
<!-- - 4.1.2.173 causes `java.lang.NoClassDefFoundError: fish/payara/nucleus/healthcheck/stuck/StuckThreadsStore`
- 4.1.2.172 causes `java.lang.ClassNotFoundException: fish.payara.notification.eventbus.EventbusMessage`
- 4.1.153 and 4.1.2.174 cause `java.lang.NullPointerException
at org.omnifaces.application.OmniApplication.createValidator(OmniApplication.java:114)` when using OmniFaces -->
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>src/test/resources-glassfish-embedded</directory>
</testResource>
</testResources>
</build>
</profile>
</profiles>
SSCCE arquillian-ear-it 说明了这个问题。
上述场景可以通过将上下文路径附加到部署 URL 来实现,例如
browser.get(deploymentUrl+ "/arquillian-ear-it-web/index.xhtml");
在 SSCCE 中。 web-frontend-test
branch.
上提供了工作版本
请注意,使用 enterpriseArchive.writeTo(System.out, Formatters.VERBOSE)
打印内容时,奇怪的是没有列出 Web 模块,但它存在。
到目前为止,我遇到的所有示例都使用 Arquillian 的 @Deployment(testable = false) public static Archive<?> createDeployment()
来构建自己的 WebArchive
或 EnterpriseArchive
,这允许以快速和独立的方式测试应用程序的各个部分。但是,据我所知,在 install
阶段完成后,即在单独的模块 运行 在 EAR 组件之后,例如与
@Deployment(testable = false)
public static Archive<?> createDeployment() {
EnterpriseArchive retValue = Maven.configureResolver().workOffline().resolve("richtercloud:arquillian-ear-it-ear:ear:1.0-SNAPSHOT").withoutTransitivity().asSingle(EnterpriseArchive.class);
retValue.writeTo(System.out, Formatters.VERBOSE);
return retValue;
}
这样就可以进行类似
的测试@Drone
private WebDriver browser;
@ArquillianResource
private URL deploymentUrl;
@FindBy(id = "mainForm:saveButton")
private WebElement saveButton;
@Test
public void testWebFrontend() throws IOException {
browser.get(deploymentUrl+ "/index.xhtml");
seleniumHelper.screenshot(browser);
Assert.assertTrue(saveButton.isDisplayed());
}
这目前失败了,因为注入的部署 URL 忽略了应用程序的 context-path
,导致对 index.xhtml
的请求由于 The requested resource is not available
和 HTTP 错误 404 而失败.
有趣的是,EAR 的 web 模块存在于本地 Maven 缓存安装中,但在列表中缺失。在用 retValue.addAsModule(Maven.configureResolver().workOffline().resolve("richtercloud:arquillian-ear-it-web:war:1.0-SNAPSHOT").withTransitivity().asSingle(WebArchive.class));
明确添加它之后仍然是这种情况,我根本不理解。也许我误解了 Shrinkwrap 解决的问题。
版本是
<properties>
<powermock.version>1.7.0RC4</powermock.version>
<version.org.jboss.arquillian>1.1.5.Final</version.org.jboss.arquillian>
<version.org.wildfly>8.1.0.Final</version.org.wildfly>
<version.junit>4.12</version.junit>
<browser>phantomjs</browser>
</properties>
<dependencies>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>arquillian-ear-it-jar</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.1</version>
</dependency>
<dependency>
<groupId>net.glxn</groupId>
<artifactId>qrgen</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>validation-tools</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sf.jmimemagic</groupId>
<artifactId>jmimemagic</artifactId>
<version>0.1.3</version>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.ocpsoft.prettytime</groupId>
<artifactId>prettytime</artifactId>
<version>3.2.7.Final</version>
</dependency>
<dependency>
<groupId>org.bitbucket.cowwoc</groupId>
<artifactId>diff-match-patch</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.rauschig</groupId>
<artifactId>jarchivelib</artifactId>
<version>0.7.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- Java EE integration testing -->
<dependency>
<groupId>org.jboss.shrinkwrap.descriptors</groupId>
<artifactId>shrinkwrap-descriptors-api-javaee</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.graphene</groupId>
<artifactId>graphene-webdriver</artifactId>
<version>2.3.2</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.codeborne</groupId>
<artifactId>phantomjsdriver</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>phantomjsdriver</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>htmlunit-driver</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.26</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>jsf-validation-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>richtercloud</groupId>
<artifactId>selenium-tools</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.14.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.selenium</groupId>
<artifactId>selenium-bom</artifactId>
<version>3.7.0</version>
<!-- - 3.3.1, 3.2.0 and 3.1.0 cause required: java.util.function.Function<? super org.openqa.selenium.WebDriver,V>
found: org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement>
reason: cannot infer type-variable(s) V
(argument mismatch; org.openqa.selenium.support.ui.ExpectedCondition<org.openqa.selenium.WebElement> cannot be converted to java.util.function.Function<? super org.openqa.selenium.WebDriver,V>)
- 3.0.1 causes java.lang.IllegalAccessError: tried to access class org.openqa.selenium.os.ExecutableFinder from class org.openqa.selenium.phantomjs.PhantomJSDriverService when using phantomjs driver
- 3.6.0 causes `Unrecognized platform: linux-unknown-64bit`
which one is supposed to work around using 3.5.3
<ref>https://github.com/SeleniumHQ/selenium/issues/4781</ref>-->
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-drone-bom</artifactId>
<version>2.4.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>arquillian-glassfish-embedded</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3.1</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>fish.payara.extras</groupId>
<artifactId>payara-embedded-all</artifactId>
<version>4.1.2.174</version>
<!-- - 4.1.2.173 causes `java.lang.NoClassDefFoundError: fish/payara/nucleus/healthcheck/stuck/StuckThreadsStore`
- 4.1.2.172 causes `java.lang.ClassNotFoundException: fish.payara.notification.eventbus.EventbusMessage`
- 4.1.153 and 4.1.2.174 cause `java.lang.NullPointerException
at org.omnifaces.application.OmniApplication.createValidator(OmniApplication.java:114)` when using OmniFaces -->
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>src/test/resources-glassfish-embedded</directory>
</testResource>
</testResources>
</build>
</profile>
</profiles>
SSCCE arquillian-ear-it 说明了这个问题。
上述场景可以通过将上下文路径附加到部署 URL 来实现,例如
browser.get(deploymentUrl+ "/arquillian-ear-it-web/index.xhtml");
在 SSCCE 中。 web-frontend-test
branch.
请注意,使用 enterpriseArchive.writeTo(System.out, Formatters.VERBOSE)
打印内容时,奇怪的是没有列出 Web 模块,但它存在。