Docker成为事实上的项目,用于隔离地在轻量级软件容器内部署应用程序。 由于它们确实很轻巧,因此不仅非常适合在生产中使用,而且非常适合在developer / qa / CI机器内部使用。 因此,自然的步骤是开始编写针对这些容器运行的软件测试。
实际上,如果您正在生产环境中运行Docker ,则可以开始编写基础结构测试,并在发布生产之前将其作为发布链的一个过程(甚至在开发人员机器中进行调试)运行。
那很酷,但是您需要一种从开发人员的角度来看自动化所有这些步骤的方法。 如果我们能够启动Docker容器,在此处部署项目并从JUnit像简单的JUnit一样简单地执行测试,那将是惊人的。 这就是Arquillian Cube所做的。
Arquillian Cube是Arquillian扩展,可用于管理Arquillian中的 Docker容器。
扩展名为Cube的原因有两个:
- 因为Docker就像一个立方体
- 因为Borg星际飞船被命名为cube,而且因为我们正将测试移至生产附近,所以我们可以说“任何抵抗都是徒劳的,虫子会被吸收”。
使用此扩展,您可以启动安装了服务器的Docker容器,在其中部署所需的可部署文件并执行Arquillian测试。
这里的关键点是,如果将Docker用作生产环境中的可部署平台,则您的测试将在生产环境中在同一容器中执行,因此您的测试比以前更加真实。
而且,您还可以使用每个必需的服务(例如数据库,邮件服务器等)来启动一个容器,而无需存根或使用伪造的对象,您的测试可以使用真实的服务器。
让我们看一个非常简单的示例,该示例向您展示Arquillian Cube多么强大和易于使用。 请记住,此扩展可以与其他Arquillian扩展(例如Arquillian Drone / Graphene)一起使用来运行功能测试。
Arquillian Cube依赖docker -java API 。
要使用Arquillian Cube,您需要在计算机上运行Docker守护程序(它可以是本地的,也可以不是本地的),但是可能是在本地。
默认情况下, Docker服务器使用UNIX套接字与Docker客户端进行通信,但是docker-java客户端使用TCP / IP连接到Docker服务器,因此您需要确保Docker服务器正在侦听TCP端口。 要允许Docker服务器使用TCP,请将以下行添加到/ etc / default / docker :
DOCKER_OPTS =”-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock”
重新启动Docker守护程序后,您需要确保Docker已启动并正在侦听TCP 。
$ docker -H tcp://127.0.0.1:2375版本
客户端版本:0.8.0
Go版本(客户端):go1.2
Git提交(客户端):cc3a8c8 服务器版本:1.2.0 Git提交(服务器):fa7b24f Go版本(服务器):go1.3.1
如果看不到客户端和服务器版本,则表示Docker安装中出了点问题。
安装Docker服务器后,我们可以开始使用Arquillian Cube了 。
在这种情况下,我们将在Apache Tomcat中使用Docker映像,并且将测试Servlet。
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("Hello World");
}
}
和测试:
@RunWith(Arquillian.class)
public class HelloWorldServletTest {
@Deployment(testable=false)
public static WebArchive create() {
return ShrinkWrap.create(WebArchive.class, "hello.war").addClass(HelloWorldServlet.class);
}
@Test
public void should_parse_and_load_configuration_file(@ArquillianResource URL resource) throws IOException {
URL obj = new URL(resource, "HelloWorld");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
assertThat(response.toString(), is("Hello World"));
}
}
请注意,该测试与任何其他Arquillian测试相似 。
下一步是按照http://arquillian.org/guides/getting_started中的描述添加Arquillian依赖关系,并添加arquillian-cube- docker依赖关系:
<dependency>
<groupId>org.arquillian.cube</groupId>
<artifactId>arquillian-cube-docker</artifactId>
<version>1.0.0.Alpha1</version>
<scope>test</scope>
</dependency>
因为我们使用的是Tomcat ,并且是在远程主机上执行的(实际上,这是正确的,因为Tomcat在Arquillian外部的Docker内部运行),所以我们需要添加Tomcat远程适配器。
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-tomcat-remote-7</artifactId>
<version>1.0.0.CR7</version>
<scope>test</scope>
</dependency>
最后配置arquillian.xml :
<?xml version="1.0"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<extension qualifier="docker"> (1)
<property name="serverVersion">1.12</property> (2)
<property name="serverUri">http://localhost:2375</property> (3)
<property name="dockerContainers"> (4)
tomcat:
image: tutum/tomcat:7.0
exposedPorts: [8089/tcp]
await:
strategy: polling
env: [TOMCAT_PASS=mypass, JAVA_OPTS=-Dcom.sun.management.jmxremote.port=8089 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false]
portBindings:
- exposedPort: 8089/tcp
port: 8089
- exposedPort: 8080/tcp
port: 8080
</property>
</extension>
<container qualifier="tomcat" default="true"> (5)
<configuration>
<property name="host">localhost</property> (6)
<property name="httpPort">8080</property> (7)
<property name="user">admin</property> (8)
<property name="pass">mypass</property>
</configuration>
</container>
</arquillian>
(1)已注册Arquillian Cube扩展名。
(2)需要Docker服务器版本。
(3)Docker服务器URI是必需的。 如果您使用的是远程Docker主机或Boot2Docker ,则需要设置远程主机ip,但在这种情况下, Docker服务器位于同一台计算机上。
(4)Docker容器包含许多可以配置的参数。 为了避免为每个属性创建一个XML属性,可以将YAML内容直接嵌入为属性。
(5) Tomcat远程适配器的配置。 当多维数据集在与具有相同名称的Arquillian容器相同的上下文中运行时, 多维数据集将启动Docker容器。
(6)主机可以是localhost,因为容器和Docker服务器之间存在端口转发。
(7) 端口也暴露在外。
(8)需要 用户和密码才能将war文件部署到远程Tomcat 。
就这样。 现在,您可以运行测试,您将看到tutum / tomcat:7.0映像是如何下载和启动的。 然后执行测试,最后停止docker容器。
这是一个简单的示例,但是您可以做更多的事情,例如从Dockerfile创建映像,编排多个Docker映像或丰富测试以编程方式操作容器。
有关更多信息,您可以阅读https://github.com/arquillian/arquillian-cube ,当然,任何反馈都将受到欢迎。