Thursday, May 24, 2018

Testcontainers, using Docker containers in JUnit tests

Junit sucks, use at least 5.0 or better switch to TestNG (see http://www.baeldung.com/junit-vs-testng for comparison)


https://www.javacodegeeks.com/2018/05/testcontainers-and-spring-boot.html

https://github.com/bijukunjummen/cities

https://www.testcontainers.org/usage.html#maven-dependencies

https://github.com/testcontainers/testcontainers-java-examples

https://github.com/testcontainers/testcontainers-java


https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.testcontainers%22


To keep it really minimalistic, I have created a Maven Java project:

<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.pierre</groupId>
 <artifactId>testcontainer</artifactId>
 <version>1.0</version>
 <dependencies>
  <dependency>
   <groupId>org.testcontainers</groupId>
   <artifactId>testcontainers</artifactId>
   <version>1.7.3</version>
  </dependency>
  
  <dependency>
   <groupId>org.testcontainers</groupId>
   <artifactId>selenium</artifactId>
   <version>1.7.3</version>
  </dependency>
  
   
  
  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-remote-driver</artifactId>
   <version>2.45.0</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.7.7</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.1.2</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <properties>
  <maven.compiler.target>1.8</maven.compiler.target>
  <maven.compiler.source>1.8</maven.compiler.source>
 </properties>
</project>


and copied this example


package org.pierre.testcontainer;

import org.junit.Rule;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.containers.BrowserWebDriverContainer;

import java.io.File;

import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue;
import static org.testcontainers.containers.BrowserWebDriverContainer.VncRecordingMode.RECORD_ALL;


public class SeleniumContainerTest {

    @Rule
    public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer()
                                                    .withDesiredCapabilities(DesiredCapabilities.chrome())
                                                    .withRecordingMode(RECORD_ALL, new File("target"));

    @Test
    public void simplePlainSeleniumTest() {
        RemoteWebDriver driver = chrome.getWebDriver();

        driver.get("https://wikipedia.org");
        WebElement searchInput = driver.findElementByName("search");

        searchInput.sendKeys("Rick Astley");
        searchInput.submit();

        WebElement otherPage = driver.findElementByLinkText("Rickrolling");
        otherPage.click();

        boolean expectedTextFound = driver.findElementsByCssSelector("p")
                .stream()
                .anyMatch(element -> element.getText().contains("meme"));

        assertTrue("The word 'meme' is found on a page about rickrolling", expectedTextFound);
}

}




The first time it failed with a SocketTimeoutException.... the second time it succeeded... I guess simply the Docker container was taking too much time to start.

If I do "docker images" I see richnorth/vnc-recorder and selenium/standalone-chrome-debug. If I do "docker ps -a" I see no trace of containers, probably they are removed at the end of test.


It looks really interesting! Convenient way to prepare a test environment in a fully automated way.






No comments: