{"id":72415,"date":"2018-01-12T19:00:51","date_gmt":"2018-01-12T17:00:51","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=72415"},"modified":"2023-12-11T10:20:29","modified_gmt":"2023-12-11T08:20:29","slug":"docker-java-developers-test-docker","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html","title":{"rendered":"Docker for Java Developers: Test on Docker"},"content":{"rendered":"<p><em>This article is part of our Academy Course titled <a href=\"https:\/\/www.javacodegeeks.com\/2018\/02\/docker-tutorial-java-developers.html\">Docker Tutorial for Java Developers<\/a>.<\/em><\/p>\n<p><em>In this course, we provide a series of tutorials so that you can develop your own Docker based applications. We cover a wide range of topics, from Docker over command line, to development, testing, deployment and continuous integration. With our straightforward tutorials, you will be able to get your own projects up and running in minimum time. Check it out <a href=\"https:\/\/www.javacodegeeks.com\/2018\/02\/docker-tutorial-java-developers.html\">here<\/a>!<\/em><\/p>\n<div class=\"toc\">\n<h3>Table Of Contents<\/h3>\n<dl>\n<dt><a href=\"#introduction\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#before\">2. Before getting started<\/a><\/dt>\n<dt><a href=\"#ram\">3. Storing data in RAM<\/a><\/dt>\n<dt><a href=\"#scenario\">4. The Scenario<\/a><\/dt>\n<dt><a href=\"#testcontainers\">5. Testcontainers<\/a><\/dt>\n<dt><a href=\"#arquillian\">6. Arquillian<\/a><\/dt>\n<dt><a href=\"#overcast\">7. Overcast<\/a><\/dt>\n<dt><a href=\"#compose\">8. Docker Compose Rule<\/a><\/dt>\n<dt><a href=\"#conclusions\">9. Conclusions<\/a><\/dt>\n<dt><a href=\"#next\">10. What\u2019s next<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2><a name=\"introduction\"><\/a>1. Introduction<\/h2>\n<p>If we think about the areas of software engineering where the impact of the <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> and container-based virtualization is most noticeable, testing and test automation is certainly one of those. As the software systems become more and more complex, so do the software stacks they are built upon, with many moving parts involved.<\/p>\n<p>In this section of the tutorial we are going to learn a couple of the frameworks which enormously simplify the integration, component and end-to-end testing of JVM-based applications by leveraging <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> and the tooling around it.<\/p>\n<h2><a name=\"before\"><\/a>2. Before getting started<\/h2>\n<p>In the <a href=\"https:\/\/www.javacodegeeks.com\/2017\/09\/docker-java-developers-docker-command-line.html\">second part of this tutorial<\/a> we have briefly mentioned that Java applications deployed as <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> containers should use at least <code>Java 8 update 131<\/code> or later but we have not had chance to elaborate on importance of this fact just yet.<\/p>\n<p>To understand the issue, let us focus on how JVM deal with two most important resources for Java applications: memory (heap) and CPU. For the purpose of the illustration, we are going to have <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> installed on a dedicated virtual machine which has <code>2 CPU cores<\/code> and <code>4GB of memory<\/code> allocated. Keeping this configuration in mind, let us take a look on that from JVM perspective:<\/p>\n<div>\n<div id=\"highlighter_240081\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">$ docker run --<\/code><code class=\"bash functions\">rm<\/code> <code class=\"bash plain\">openjdk:8-jdk-alpine java -XshowSettings:vm -XX:+UseParallelGC -XX:+PrintFlagsFinal \u2013version<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>There are going to be a lot of information printed out in the console, but there most interesting pieces for us are <code>ParallelGCThreads<\/code> and <code>VM settings<\/code>.<\/p>\n<div>\n<div id=\"highlighter_841454\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">uintx ParallelGCThreads = 2<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">VM settings:<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Max. Heap Size (Estimated): 992.00M<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Ergonomics Machine Class: server<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Using VM: OpenJDK 64-Bit Server VM<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash plain\">openjdk version <\/code><code class=\"bash string\">\"1.8.0_131\"<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">OpenJDK Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-r2)<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash plain\">OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>On the machines with less than (or equal to) 8 cores, the <code>ParallelGCThreads<\/code> is <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/vm\/gctuning\/parallel.html\">equal to number of cores<\/a>, while the default maximum limit for heap is roughly <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/vm\/gc-ergonomics.html\">25% of available physical memory<\/a>. Cool, the numbers which JVM reports make sense so far.<\/p>\n<p>Let us push it a bit further and use <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> resource management capabilities to restrict container CPU and memory usage to <code>1 core<\/code> and <code>256Mb<\/code> respectively.<\/p>\n<div>\n<div id=\"highlighter_177148\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">$ docker run --<\/code><code class=\"bash functions\">rm<\/code> <code class=\"bash plain\">--cpuset-cpus=0 --memory=256m openjdk:8-jdk-alpine java -XshowSettings:vm -XX:+UseParallelGC -XX:+PrintFlagsFinal -version<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The picture is a bit different this time:<\/p>\n<div>\n<div id=\"highlighter_10624\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">uintx ParallelGCThreads = 1<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">VM settings:<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Max. Heap Size (Estimated): 992.00M<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Ergonomics Machine Class: client<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Using VM: OpenJDK 64-Bit Server VM<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>JVM was able to adjust the <code>ParallelGCThreads<\/code> accordingly but memory constraints seem to be ignored completely. That is right, to make JVM aware of containerized environment we need to unlock experimental JVM options: <code>-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap<\/code>.<\/p>\n<div>\n<div id=\"highlighter_867699\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">$ docker run --<\/code><code class=\"bash functions\">rm<\/code> <code class=\"bash plain\">--cpuset-cpus=0 --memory=256m openjdk:8-jdk-alpine java -XshowSettings:vm -XX:+UseParallelGC -XX:+PrintFlagsFinal\u00a0 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap \u2013version<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The results are looking much better now:<\/p>\n<div>\n<div id=\"highlighter_293902\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">uintx ParallelGCThreads = 1<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">VM settings:<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Max. Heap Size (Estimated): 112.00M<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Ergonomics Machine Class: client<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Using VM: OpenJDK 64-Bit Server VM<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The curious reader may be wondering why the maximum heap size is quite over the expected <code>25%<\/code> of the available physical memory allocated to the container. The answer is that <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> also allocates memory for swap (which, if not specified, is equal to desired memory limit) so the true value JVM sees is <code>256Mb + 256Mb = 512Mb<\/code>.<\/p>\n<p>But even here we could make improvements. Usually, when we are running Java applications inside <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> containers, there is only place for a single JVM process in there, so why don\u2019t we just give it all the available memory container has? That is actually very simple to do by adding <code>-XX:MaxRAMFraction=1<\/code> command line option.<\/p>\n<div>\n<div id=\"highlighter_705197\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">$ docker run --<\/code><code class=\"bash functions\">rm<\/code> <code class=\"bash plain\">--cpuset-cpus=0 --memory=256m openjdk:8-jdk-alpine java -XshowSettings:vm -XX:+UseParallelGC -XX:+PrintFlagsFinal\u00a0 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1\u00a0 -version<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>And let us check what JVM reports:<\/p>\n<div>\n<div id=\"highlighter_865695\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash plain\">uintx ParallelGCThreads = 1<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">...<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash plain\">VM settings:<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Max. Heap Size (Estimated): 228.00M<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Ergonomics Machine Class: client<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">Using VM: OpenJDK 64-Bit Server VM<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash plain\">openjdk version <\/code><code class=\"bash string\">\"1.8.0_131\"<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash plain\">OpenJDK Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-r2)<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash plain\">OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>It looks just perfect. Please be aware of this experimental JVM options and use them appropriately, so you could adjust the resources your Java applications should be using.<\/p>\n<h2><a name=\"ram\"><\/a>3. Storing data in RAM<\/h2>\n<p>It is rarely the case that the application has no dependency on some kind of data store (sometimes even more than one). And, unsurprisingly, most of such stores persist the data on some kind of durable storage. This is great indeed, but quite often the presence of such data stores makes the testing a challenge, specifically when summoning the isolation of the test cases on the data level.<\/p>\n<p>You may have already guessed, <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> could enormously reduce the efforts required to create reproducible test scenarios. But still, the data stores serve as the major contributor to overall test execution time.<\/p>\n<p>As we are going to see in a moment, <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> has something in the sleeve to help us out: <a href=\"https:\/\/docs.docker.com\/engine\/admin\/volumes\/tmpfs\/\">tmpfs<\/a>. It effectively gives the container a way to manage the data without writing it anywhere permanently, keeping it in the host machine\u2019s memory (or swap, if memory is running low).<\/p>\n<p>There are multiple options available which allow to attach <a href=\"https:\/\/docs.docker.com\/engine\/admin\/volumes\/tmpfs\/\">tmpfs<\/a>-backed volumes to your container, but the recommended one these days is to use <code>--mount<\/code> command line argument (or <a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/#tmpfs\">tmpfs<\/a> section of the specification in case of <a href=\"https:\/\/docs.docker.com\/compose\/reference\/overview\/\">docker-compose<\/a>).<\/p>\n<div>\n<div id=\"highlighter_33037\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">docker run --<\/code><code class=\"bash functions\">rm<\/code> <code class=\"bash plain\">-d \\<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">--name mysql \\<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">--<\/code><code class=\"bash functions\">mount<\/code> <code class=\"bash functions\">type<\/code><code class=\"bash plain\">=tmpfs,destination=<\/code><code class=\"bash plain\">\/var\/lib\/mysql<\/code> <code class=\"bash plain\">\\<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">-e MYSQL_ROOT_PASSWORD=<\/code><code class=\"bash string\">'p$ssw0rd'<\/code> <code class=\"bash plain\">\\<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">-e MYSQL_DATABASE=my_app_db \\<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">-e MYSQL_ROOT_HOST=% \\<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">mysql:8.0.2<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The speed gains for test executions could be tremendous, but you should not use this feature in production (and very likely, in any other environments), ever, because when the container stops, the <a href=\"https:\/\/docs.docker.com\/engine\/admin\/volumes\/tmpfs\/\">tmpfs<\/a> mount disappears. Even if the container is committed, the <a href=\"https:\/\/docs.docker.com\/engine\/admin\/volumes\/tmpfs\/\">tmpfs<\/a> mount is not saved.<\/p>\n<h2><a name=\"scenario\"><\/a>4. The Scenario<\/h2>\n<p>Armed with these tricks and tips, we could discuss the test scenario we are going to implement. Essentially, it would be great to run end-to-end test for one of the applications we have developed in the previous parts of the tutorial. The eventual goal of the test scenario would be to verify that <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST(ful) APIs<\/a> for tasks management is available and returning the expected results.<\/p>\n<p>From the deployment stack perspective, it means we have to have the instance of <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and the instance of the application (let us pick the <a href=\"https:\/\/projects.spring.io\/spring-boot\/\">Spring Boot<\/a> based one we have developed before but it does not really matter much). This application exposes the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST(ful) APIs<\/a> and should be able to communicate with <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> instance. Surely, we would like those instances to live as <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> containers.<\/p>\n<p>The test scenario is going to call the task managements <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST(ful) APIs<\/a> to get the list of all available tasks, using terrific <a href=\"http:\/\/rest-assured.io\/\">REST-assured<\/a> framework for test scaffolding. Also, all our test scenarios are going to be based on <a href=\"http:\/\/junit.org\/\">JUnit<\/a> framework.<\/p>\n<h2><a name=\"testcontainers\"><\/a>5. Testcontainers<\/h2>\n<p>The first framework we are going to look at is <a href=\"https:\/\/www.testcontainers.org\/\">TestContainers<\/a>, a Java library that supports <a href=\"http:\/\/junit.org\/junit4\/\">JUnit<\/a> tests and provides lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> container.<\/p>\n<p>Let us see how we could project the test scenario we have outlined before into the running <a href=\"http:\/\/junit.org\/junit4\/\">JUnit<\/a> test using <a href=\"https:\/\/www.testcontainers.org\/\">TestContainers<\/a> to our benefits. At the end, it looks pretty straightforward.<\/p>\n<div>\n<div id=\"highlighter_709471\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<div class=\"line number37 index36 alt2\">37<\/div>\n<div class=\"line number38 index37 alt1\">38<\/div>\n<div class=\"line number39 index38 alt2\">39<\/div>\n<div class=\"line number40 index39 alt1\">40<\/div>\n<div class=\"line number41 index40 alt2\">41<\/div>\n<div class=\"line number42 index41 alt1\">42<\/div>\n<div class=\"line number43 index42 alt2\">43<\/div>\n<div class=\"line number44 index43 alt1\">44<\/div>\n<div class=\"line number45 index44 alt2\">45<\/div>\n<div class=\"line number46 index45 alt1\">46<\/div>\n<div class=\"line number47 index46 alt2\">47<\/div>\n<div class=\"line number48 index47 alt1\">48<\/div>\n<div class=\"line number49 index48 alt2\">49<\/div>\n<div class=\"line number50 index49 alt1\">50<\/div>\n<div class=\"line number51 index50 alt2\">51<\/div>\n<div class=\"line number52 index51 alt1\">52<\/div>\n<div class=\"line number53 index52 alt2\">53<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">package<\/code> <code class=\"java plain\">com.javacodegeeks;<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">io.restassured.RestAssured.when;<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java keyword\">import<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">org.hamcrest.CoreMatchers.equalTo;<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">org.junit.BeforeClass;<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">org.junit.ClassRule;<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">org.junit.Test;<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">org.testcontainers.containers.GenericContainer;<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">org.testcontainers.containers.Network;<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">org.testcontainers.containers.wait.HostPortWaitStrategy;<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java keyword\">import<\/code> <code class=\"java plain\">io.restassured.RestAssured;<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">SpringBootAppIntegrationTest {<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">Network network = Network.newNetwork();<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">GenericContainer&lt;?&gt; mysql = <\/code><code class=\"java keyword\">new<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">GenericContainer&lt;&gt;(<\/code><code class=\"java string\">\"mysql:8.0.2\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnv(<\/code><code class=\"java string\">\"MYSQL_ROOT_PASSWORD\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"p$ssw0rd\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnv(<\/code><code class=\"java string\">\"MYSQL_DATABASE\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"my_app_db\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnv(<\/code><code class=\"java string\">\"MYSQL_ROOT_HOST\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"%\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withExposedPorts(<\/code><code class=\"java value\">3306<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withNetwork(network)<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withNetworkAliases(<\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.waitingFor(<\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">HostPortWaitStrategy());<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">GenericContainer&lt;?&gt; javaApp = <\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">GenericContainer&lt;&gt;(<\/code><code class=\"java string\">\"jcg\/spring-boot-webapp:latest\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnv(<\/code><code class=\"java string\">\"DB_HOST\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withExposedPorts(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withStartupAttempts(<\/code><code class=\"java value\">3<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withNetwork(network)<\/code><\/div>\n<div class=\"line number37 index36 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.waitingFor(<\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">HostPortWaitStrategy());<\/code><\/div>\n<div class=\"line number38 index37 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number39 index38 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@BeforeClass<\/code><\/div>\n<div class=\"line number40 index39 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">setUp() {<\/code><\/div>\n<div class=\"line number41 index40 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.baseURI = <\/code><code class=\"java string\">\"<a href=\"http:\/\/\">http:\/\/<\/a>\"<\/code> <code class=\"java plain\">+ javaApp.getContainerIpAddress();<\/code><\/div>\n<div class=\"line number42 index41 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.port = javaApp.getMappedPort(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number43 index42 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number44 index43 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number45 index44 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@Test<\/code><\/div>\n<div class=\"line number46 index45 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">getAllTasks() {<\/code><\/div>\n<div class=\"line number47 index46 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">when()<\/code><\/div>\n<div class=\"line number48 index47 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.get(<\/code><code class=\"java string\">\"\/tasks\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number49 index48 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.then()<\/code><\/div>\n<div class=\"line number50 index49 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.statusCode(<\/code><code class=\"java value\">200<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number51 index50 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.body(equalTo(<\/code><code class=\"java string\">\"[]\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number52 index51 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number53 index52 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><a href=\"https:\/\/www.testcontainers.org\/\">TestContainers<\/a> comes with a predefined set of specialized containers (for <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>, <a href=\"https:\/\/www.postgresql.org\/\">PostgreSQL<\/a>, <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/database-technologies\/express-edition\/overview\/index.html\">Oracle XE<\/a> and others) but you always have a choice to use your own (like we have done in the snippet above). The <a href=\"https:\/\/www.testcontainers.org\/usage\/docker_compose.html\">Docker Compose<\/a> specifications are also supported out of the box.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>In case you are using Windows as a development platform, please be warned that <a href=\"https:\/\/www.testcontainers.org\/\">TestContainers<\/a> is not regularly tested on Windows. If you want to try it out nonetheless, the recommendation at the moment is to use <a href=\"https:\/\/www.testcontainers.org\/usage\/windows_support.html\">alpha release<\/a>.<br \/>\n[ulp id=&#8217;MD25RnPuC2vrVItl&#8217;]<br \/>\n&nbsp;<\/p>\n<h2><a name=\"arquillian\"><\/a>6. Arquillian<\/h2>\n<p>Next one in the list is <a href=\"http:\/\/arquillian.org\/\">Arquillian<\/a><em>,<\/em> an innovative and highly extensible testing platform for the JVM that enables developers to easily create automated integration, functional and acceptance tests for Java middleware. <a href=\"http:\/\/arquillian.org\/\">Arquillian<\/a> is indeed more a testing platform than framework, where <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> support is just one of many options available.<\/p>\n<p>Let us take a look on how the same test case we have seen in the previous section may look like when translated to <a href=\"http:\/arquillian.org\/arquillian-cube\/\">Arquillian Cube<\/a>, an <a href=\"http:\/\/arquillian.org\/\">Arquillian<\/a> extension that can be used to manager <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> containers from <a href=\"http:\/\/arquillian.org\/\">Arquillian<\/a>.<\/p>\n<div>\n<div id=\"highlighter_234278\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<div class=\"line number37 index36 alt2\">37<\/div>\n<div class=\"line number38 index37 alt1\">38<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">SpringBootAppIntegrationTest {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">NetworkDslRule network = <\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">NetworkDslRule(<\/code><code class=\"java string\">\"my-app-network\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">ContainerDslRule mysql = <\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">ContainerDslRule(<\/code><code class=\"java string\">\"mysql:8.0.2\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnvironment(<\/code><code class=\"java string\">\"MYSQL_ROOT_PASSWORD\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"p$ssw0rd\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnvironment(<\/code><code class=\"java string\">\"MYSQL_DATABASE\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"my_app_db\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnvironment(<\/code><code class=\"java string\">\"MYSQL_ROOT_HOST\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"%\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withExposedPorts(<\/code><code class=\"java value\">3306<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withNetworkMode(<\/code><code class=\"java string\">\"my-app-network\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withAwaitStrategy(AwaitBuilder.logAwait(<\/code><code class=\"java string\">\"\/usr\/sbin\/mysqld: ready for connections\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">ContainerDslRule javaApp = <\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">ContainerDslRule(<\/code><code class=\"java string\">\"jcg\/spring-boot-webapp:latest\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"spring-boot-webapp*\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withEnvironment(<\/code><code class=\"java string\">\"DB_HOST\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withPortBinding(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withNetworkMode(<\/code><code class=\"java string\">\"my-app-network\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withLink(<\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.withAwaitStrategy(AwaitBuilder.logAwait(<\/code><code class=\"java string\">\"Started AppStarter\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@BeforeClass<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">setUp() {<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.baseURI = <\/code><code class=\"java string\">\"<a href=\"http:\/\/\">http:\/\/<\/a>\"<\/code> <code class=\"java plain\">+ javaApp.getIpAddress();<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.port = javaApp.getBindPort(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@Test<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">getAllTasks() {<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">when()<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.get(<\/code><code class=\"java string\">\"\/tasks\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.then()<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.statusCode(<\/code><code class=\"java value\">200<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.body(equalTo(<\/code><code class=\"java string\">\"[]\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number37 index36 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number38 index37 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>There are a couple of differences from <a href=\"https:\/\/www.testcontainers.org\/\">TestContainers<\/a> but, by and large, the test case should be looking familiar already. The key feature which seems to be unavailable in the <a href=\"http:\/\/arquillian.org\/arquillian-cube\/\">Arquillian Cube<\/a> at the moment (at least, when using <a href=\"http:\/\/arquillian.org\/arquillian-cube\/#_container_objects_dsl\">Container Objects DSL<\/a>) is support for network aliasing so we had to fall back to <a href=\"https:\/\/docs.docker.com\/engine\/userguide\/networking\/default_network\/dockerlinks\/\">legacy container linking<\/a> in order to connect our <a href=\"https:\/\/projects.spring.io\/spring-boot\/\">Spring Boot<\/a> application with <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> backend.<\/p>\n<p>It is worth to mention that <a href=\"http:\/\/arquillian.org\/arquillian-cube\/\">Arquillian Cube<\/a> has quite a few alternative ways to manage <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> containers from the test scenarios, including <a href=\"https:\/\/www.testcontainers.org\/usage\/docker_compose.html\">Docker Compose<\/a> specifications support. On a side note, the pace of development around <a href=\"http:\/\/arquillian.org\/\">Arquillian<\/a> is just incredible, it has all the chances to be one stop shop testing platform for modern Java applications.<\/p>\n<h2><a name=\"overcast\"><\/a>7. Overcast<\/h2>\n<p><a href=\"https:\/\/github.com\/xebialabs\/overcast\">Overcast<\/a> is a Java library from <a href=\"https:\/\/xebialabs.com\/\">XebiaLabs<\/a> intended to be used to test against hosts in the cloud. <a href=\"https:\/\/github.com\/xebialabs\/overcast\">Overcast<\/a> was one of the first test frameworks to offer the extensive <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> support while aiming for more ambitious goals to abstract away the host management in the test scenarios. It has a lot of very interesting features but sadly seems to be not actively maintained anymore, with last release dated 2015. Nonetheless, it is worth looking as it has some unique values.<\/p>\n<p><a href=\"https:\/\/github.com\/xebialabs\/overcast\">Overcast<\/a> uses configuration driven approach to describe the hosts under the test, stemming from the fact that it is not oriented only on containers or\/and <a href=\"https:\/\/www.docker.com\/\">Docker<\/a>.<\/p>\n<div>\n<div id=\"highlighter_816003\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">mysql {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">name=<\/code><code class=\"bash string\">\"mysql\"<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">dockerImage=<\/code><code class=\"bash string\">\"mysql:8.0.2\"<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">remove=<\/code><code class=\"bash functions\">true<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">removeVolume=<\/code><code class=\"bash functions\">true<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">env<\/code><code class=\"bash plain\">=[<\/code><code class=\"bash string\">\"MYSQL_ROOT_PASSWORD=p$ssw0rd\"<\/code><code class=\"bash plain\">, <\/code><code class=\"bash string\">\"MYSQL_DATABASE=my_app_db\"<\/code><code class=\"bash plain\">, <\/code><code class=\"bash string\">\"MYSQL_ROOT_HOST=%\"<\/code><code class=\"bash plain\">]<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash plain\">}<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash plain\">spring-boot-webapp {<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">dockerImage=<\/code><code class=\"bash string\">\"jcg\/spring-boot-webapp:latest\"<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">exposeAllPorts=<\/code><code class=\"bash functions\">true<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">remove=<\/code><code class=\"bash functions\">true<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">removeVolume=<\/code><code class=\"bash functions\">true<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">env<\/code><code class=\"bash plain\">=[<\/code><code class=\"bash string\">\"DB_HOST=mysql\"<\/code><code class=\"bash plain\">]<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">links=[<\/code><code class=\"bash string\">\"mysql:mysql\"<\/code><code class=\"bash plain\">]<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"bash plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>With such configuration in place, stored in the <code>overcast.conf<\/code>, we could refer to containers by their names from the test scenarios.<\/p>\n<div>\n<div id=\"highlighter_929963\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<div class=\"line number37 index36 alt2\">37<\/div>\n<div class=\"line number38 index37 alt1\">38<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">SpringBootAppIntegrationTest {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">private<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">CloudHost mysql = CloudHostFactory.getCloudHost(<\/code><code class=\"java string\">\"mysql\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">private<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">CloudHost javaApp = CloudHostFactory.getCloudHost(<\/code><code class=\"java string\">\"spring-boot-webapp\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@BeforeClass<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">setUp() {<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">mysql.setup();<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">javaApp.setup();<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.baseURI = <\/code><code class=\"java string\">\"<a href=\"http:\/\/\">http:\/\/<\/a>\"<\/code> <code class=\"java plain\">+ javaApp.getHostName();<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.port = javaApp.getPort(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">await()<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.atMost(<\/code><code class=\"java value\">20<\/code><code class=\"java plain\">, TimeUnit.SECONDS)<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.ignoreExceptions()<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.pollInterval(<\/code><code class=\"java value\">1<\/code><code class=\"java plain\">, TimeUnit.SECONDS)<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.untilAsserted(() -&gt; <\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">when()<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.get(<\/code><code class=\"java string\">\"\/application\/health\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.then()<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.statusCode(<\/code><code class=\"java value\">200<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@AfterClass<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">tearDown() {<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">javaApp.teardown();<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">mysql.teardown();<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@Test<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">getAllTasks() {<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">when()<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.get(<\/code><code class=\"java string\">\"\/tasks\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.then()<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.statusCode(<\/code><code class=\"java value\">200<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.body(equalTo(<\/code><code class=\"java string\">\"[]\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number37 index36 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number38 index37 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>It looks pretty straightforward except the health check part. <a href=\"https:\/\/github.com\/xebialabs\/overcast\">Overcast<\/a> does not provide the means to verify that containers are up and ready to serve the requests, so we on-boarded another great library, <a href=\"https:\/\/github.com\/awaitility\/awaitility\">Awaitility<\/a>, to compensate that.<\/p>\n<p>There is a lot of potential and benefits which <a href=\"https:\/\/github.com\/xebialabs\/overcast\">Overcast<\/a> could provide, hopefully we would see it back to active development one day. As for this example, in order to use the latest <a href=\"https:\/\/github.com\/xebialabs\/overcast\">Overcast<\/a> features we had to build it from the sources.<\/p>\n<h2><a name=\"compose\"><\/a>8. Docker Compose Rule<\/h2>\n<p>Last but not least, let us discuss the <a href=\"https:\/\/github.com\/palantir\/docker-compose-rule\">Docker Compose Rule<\/a>, a library from <a href=\"https:\/\/www.palantir.com\/\">Palantir Technologies<\/a> for executing <a href=\"http:\/\/junit.org\/junit4\/\">JUnit<\/a> tests that interact with <a href=\"https:\/\/docs.docker.com\/compose\/reference\/overview\/\">Docker Compose<\/a>-managed containers. Under the hood it uses the <a href=\"https:\/\/docs.docker.com\/compose\/reference\/overview\/\">docker-compose<\/a> command line tool and, as of now, the Windows platform is not supported.<\/p>\n<p>As you may guess, we have to start off from the <code>docker-compose.yml<\/code> specification so it could be read by <a href=\"https:\/\/github.com\/palantir\/docker-compose-rule\">Docker Compose Rule<\/a> later on. Here is an example of one.<\/p>\n<div>\n<div id=\"highlighter_408821\" class=\"syntaxhighlighter  bash\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"bash plain\">version: <\/code><code class=\"bash string\">'2.1'<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"bash plain\">services:<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">mysql:<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">image: mysql:8.0.2<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">environment:<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- MYSQL_ROOT_PASSWORD=p$ssw0rd<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- MYSQL_DATABASE=my_app_db<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- MYSQL_ROOT_HOST=%<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">expose:<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- 3306<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">healthcheck:<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash functions\">test<\/code><code class=\"bash plain\">: [<\/code><code class=\"bash string\">\"CMD-SHELL\"<\/code><code class=\"bash plain\">, <\/code><code class=\"bash string\">\"ss -ltn src :3306 | grep 3306\"<\/code><code class=\"bash plain\">]<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">interval: 10s<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">timeout: 5s<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">retries: 3<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">tmpfs:<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- <\/code><code class=\"bash plain\">\/var\/lib\/mysql<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">networks:<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- my-app-network<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"bash spaces\">\u00a0\u00a0<\/code><code class=\"bash plain\">java-app:<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">image: jcg<\/code><code class=\"bash plain\">\/spring-boot-webapp<\/code><code class=\"bash plain\">:latest<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">environment:<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- DB_HOST=mysql<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">ports:<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- 19900<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">depends_on:<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">mysql:<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">condition: service_healthy<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">networks:<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">- my-app-network<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"bash plain\">networks:<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">my-app-network:<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><code class=\"bash spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"bash plain\">driver: bridge<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>With that, we just need to feed this specification to <a href=\"https:\/\/github.com\/palantir\/docker-compose-rule\">Docker Compose Rule<\/a>, like in the code snippet below. Please also notice that we have augmented the scenario with a health check to make sure that our <a href=\"https:\/\/projects.spring.io\/spring-boot\/\">Spring Boot<\/a> application has fully started.<\/p>\n<div>\n<div id=\"highlighter_679405\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">SpringBootAppIntegrationTest {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@ClassRule<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java plain\">DockerComposeRule docker = DockerComposeRule.builder()<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.file(<\/code><code class=\"java string\">\"src\/test\/resources\/docker-compose.yml\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.waitingForService(<\/code><code class=\"java string\">\"java-app\"<\/code><code class=\"java plain\">, <\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">HealthChecks.toRespond2xxOverHttp(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">, (port) -&gt; <\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">port.inFormat(<\/code><code class=\"java string\">\"<a href=\"http:\/\/\">http:\/\/<\/a>$HOST:$EXTERNAL_PORT\/application\/health\"<\/code><code class=\"java plain\">)),<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">Duration.standardSeconds(<\/code><code class=\"java value\">30<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.shutdownStrategy(ShutdownStrategy.GRACEFUL)<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.build();<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@BeforeClass<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">static<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">setUp() {<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">final<\/code> <code class=\"java plain\">DockerPort port = docker.containers().container(<\/code><code class=\"java string\">\"java-app\"<\/code><code class=\"java plain\">).port(<\/code><code class=\"java value\">19900<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.baseURI = port.inFormat(<\/code><code class=\"java string\">\"<a href=\"http:\/\/\">http:\/\/<\/a>$HOST\"<\/code><code class=\"java plain\">);<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">RestAssured.port = port.getExternalPort();<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java color1\">@Test<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">void<\/code> <code class=\"java plain\">getAllTasks() {<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">when()<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.get(<\/code><code class=\"java string\">\"\/tasks\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.then()<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.statusCode(<\/code><code class=\"java value\">200<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">.body(equalTo(<\/code><code class=\"java string\">\"[]\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>This is probably the simplest way to integrate <a href=\"https:\/\/www.docker.com\/\">Docker<\/a>\u00a0 into your <a href=\"http:\/\/junit.org\/\">JUnit<\/a> test scenarios. And, coincidentally, the same <a href=\"https:\/\/docs.docker.com\/compose\/reference\/overview\/\">Docker Compose<\/a> specifications may be shared and reused for other purposes.<\/p>\n<h2><a name=\"conclusions\"><\/a>9. Conclusions<\/h2>\n<p>It this section of the tutorial we have talked about how <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> disrupted and literally revolutionized some of the most complicated testing strategies we use in the real projects. As we have seen by familiarizing with different Java testing frameworks, the support of <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> is outstanding but choosing the right tool for your project could be the challenge, depending on the operating systems and <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> installations you rely upon.<\/p>\n<p>However, with a great power comes great responsibility. <a href=\"https:\/\/www.docker.com\/\">Docker<\/a> is not a silver bullet, please always keep in mind the <a href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\">test pyramid<\/a> close by and try to find the balance which works for you the best.<\/p>\n<h2><a name=\"next\"><\/a>10. What\u2019s next<\/h2>\n<p>In the next section of the tutorial we are going to talk about quite a few typical deployment orchestrations where <a href=\"https:\/\/www.docker.com\/\">Docker<\/a>\u00a0 containers (and containers in general) are first class citizens.<\/p>\n<p>The complete project sources are <a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/02\/docker-testing.zip\">available for download<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can develop your own Docker based applications. We cover a wide range of topics, from Docker over command line, to development, testing, deployment and continuous integration. With our straightforward &hellip;<\/p>\n","protected":false},"author":141,"featured_media":24013,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[936],"class_list":["post-72415","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-docker"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Docker for Java Developers: Test on Docker - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Docker for Java Developers: Test on Docker - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2018-01-12T17:00:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-11T08:20:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2014\/04\/docker-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrey Redko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrey Redko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html\"},\"author\":{\"name\":\"Andrey Redko\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\"},\"headline\":\"Docker for Java Developers: Test on Docker\",\"datePublished\":\"2018-01-12T17:00:51+00:00\",\"dateModified\":\"2023-12-11T08:20:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html\"},\"wordCount\":1866,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2014\\\/04\\\/docker-logo.jpg\",\"keywords\":[\"Docker\"],\"articleSection\":[\"DevOps\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html\",\"name\":\"Docker for Java Developers: Test on Docker - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2014\\\/04\\\/docker-logo.jpg\",\"datePublished\":\"2018-01-12T17:00:51+00:00\",\"dateModified\":\"2023-12-11T08:20:29+00:00\",\"description\":\"This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2014\\\/04\\\/docker-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2014\\\/04\\\/docker-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/01\\\/docker-java-developers-test-docker.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DevOps\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/devops\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Docker for Java Developers: Test on Docker\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\",\"name\":\"Andrey Redko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"caption\":\"Andrey Redko\"},\"description\":\"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\\\/EE, C#\\\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).\",\"sameAs\":[\"http:\\\/\\\/aredko.blogspot.com\\\/\",\"http:\\\/\\\/ca.linkedin.com\\\/in\\\/aredko\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrey-redko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Docker for Java Developers: Test on Docker - Java Code Geeks","description":"This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html","og_locale":"en_US","og_type":"article","og_title":"Docker for Java Developers: Test on Docker - Java Code Geeks","og_description":"This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can","og_url":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-01-12T17:00:51+00:00","article_modified_time":"2023-12-11T08:20:29+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2014\/04\/docker-logo.jpg","type":"image\/jpeg"}],"author":"Andrey Redko","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrey Redko","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html"},"author":{"name":"Andrey Redko","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413"},"headline":"Docker for Java Developers: Test on Docker","datePublished":"2018-01-12T17:00:51+00:00","dateModified":"2023-12-11T08:20:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html"},"wordCount":1866,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2014\/04\/docker-logo.jpg","keywords":["Docker"],"articleSection":["DevOps"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html","url":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html","name":"Docker for Java Developers: Test on Docker - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2014\/04\/docker-logo.jpg","datePublished":"2018-01-12T17:00:51+00:00","dateModified":"2023-12-11T08:20:29+00:00","description":"This article is part of our Academy Course titled Docker Tutorial for Java Developers. In this course, we provide a series of tutorials so that you can","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2014\/04\/docker-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2014\/04\/docker-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2018\/01\/docker-java-developers-test-docker.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"DevOps","item":"https:\/\/www.javacodegeeks.com\/category\/devops"},{"@type":"ListItem","position":3,"name":"Docker for Java Developers: Test on Docker"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413","name":"Andrey Redko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","caption":"Andrey Redko"},"description":"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\/EE, C#\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).","sameAs":["http:\/\/aredko.blogspot.com\/","http:\/\/ca.linkedin.com\/in\/aredko"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrey-redko"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/72415","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/141"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=72415"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/72415\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/24013"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=72415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=72415"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=72415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}