SlideShare a Scribd company logo
Integration tests:
use the containers, Luke!
Roberto “Frank” Franchini
@robfrankie
whoami(1)
https://www.linkedin.com/in/robfrank/
Former CTO of Arcade Analytics
Joined Activiti team in Alfresco
More use cases!
Arcade Analytics
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
Same output from different data-sources
One new connector per month
New features every week for every connector
Tests: features x connectors
Test Feature B
Test Feature A
Test Feature C
Test Feature D
Deploy without
How to avoid fear?
Integration tests
Integration tests: use the containers, Luke!
Activiti Cloud
Activiti Cloud is the first Cloud Native BPM framework built to
provide a scalable and transparent solution for BPM
implementations in cloud environments.
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
Each microservice has its own integration testing suite that
needs RabbiMQ and KeyCloack to be started before
Every morning a developer wakes up and starts containers
docker run -it -p 5672:5672 -p 15672:15672 --rm rabbitmq:management
docker run -it --rm -p 8180:8180 activiti/activiti-keycloak
Then run tests in the IDE
(Poor developer experience)
Don’t start containers manually anymore
Integration testing is hard
Image credits https://magnasoma.com
Monolith era
Microservices
Unit tests
Integration tests
UI
Tests
Slower
Faster
More
integration
More
isolation
Integration tests: use the containers, Luke!
Testcontainers is a Java library that supports JUnit tests,
providing lightweight, throwaway instances of common
databases, Selenium web browsers, or anything else that can
run in a Docker container.
Prerequisites
Integration tests: use the containers, Luke!
Ports for GO, .NET, Rust, Js
Main features
Temporary database containers: specialized PostgreSQL,
MySQL, MsSQL Server, MariaDB, Oracle XE, Virtuoso
RDBMS containers
@Container
public static PostgreSQLContainer container = new PostgreSQLContainer();
@Container
public static MySQLContainer container = new MySQLContainer();
@Container
public static OracleContainer container = new OracleContainer();
Others containers: neo4j, couchbase, toxy-proxy, kafka, redis,
influxDB, elasticSearch, rabbitMQ
Others containers
@Container
public static Neo4jContainer container = new Neo4jContainer();
@Container
public static InfluxDBContainer container = new InfluxDBContainer();
@Container
public static KafkaContainer container = new KafkaContainer();
@Container
public static RabbitMQContainer container = new RabbitMQContainer();
Webdriver containers: run a Dockerized Chrome or Firefox
browser ready for Selenium/Webdriver operations - complete
with automatic video recording
Selenium
private val chrome: BrowserWebDriverContainer<Nothing> = BrowserWebDriverContainer<Nothing>()
.apply {
withDesiredCapabilities(DesiredCapabilities.chrome())
withRecordingMode(RECORD_ALL, File("target"))
start()
}
Generic containers: run any Docker container as a test
dependency
Generic container, image based
@Container
public static GenericContainer container = new GenericContainer("orientdb:3.0.23")
.withExposedPorts(2424, 2480)
.withEnv("ORIENTDB_ROOT_PASSWORD", "rootpassword")
.waitingFor(Wait.forListeningPort());
ROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers
<docker-maint@nginx.com>"
ENV NGINX_VERSION 1.15.5-1~stretch
ENV NJS_VERSION 1.15.5.0.2.4-1~stretch
RUN set -x 
&& apt-get update 
&& apt-get install --no-install-recommends
--no-install-suggests -y gnupg1 apt-transport-https
ca-certificates 
&& 
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9B
F62; 
found=''; 
for server in 
ha.pool.sks-keyservers.net 
hkp://keyserver.ubuntu.com:80 
hkp://p80.pool.sks-keyservers.net:80 
version: '2'
services:
elasticsearch:
build:
context: elasticsearch/
args:
ELK_VERSION: $ELK_VERSION
volumes:
-
./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch
.yml:ro
ports:
- "9200:9200"
- "9300:9300"
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
logstash:
build:
context: logstash/
args:
ELK_VERSION: $ELK_VERSION
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports:
- "5000:5000"
- "9600:9600"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
depends_on:
- elasticsearch
kibana:
build:
Use a compose
Start from a Dockerfile
Generic container from Dockerfile
private val container: GenericContainer<Nothing> = GenericContainer<Nothing>(
ImageFromDockerfile("robfrank/ngnix")
.withFileFromPath("Dockerfile", Paths.get("./src/main/docker/nginx/Dockerfile"))
).apply {
withExposedPorts(80)
waitingFor(Wait.forListeningPort())
start()
followOutput(Slf4jLogConsumer(log))
}
Whatever is containerized by your team(s)
DB’s containers? Isn’t
enough?
H2 is fast, BUT doesn’t emulate specific features
Testcontainers is slower*, BUT gives 100% db compatibility
*not so slower
Use in your CI env
Jenkins
DOOD: Docker outside of Docker
DIND: Docker inside of Docker
DOOD: Dockerfile
FROM jenkins/jenkins:lts
USER root
RUN apt-get update 
&& apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common 
&& curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg 
| apt-key add - 
&& add-apt-repository 
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") 
$(lsb_release -cs) 
stable" 
&& apt-get update 
&& apt-get install -y docker-ce 
&& apt-get clean 
&& rm -rf /var/lib/apt/lists/*
RUN usermod -aG docker jenkins
USER jenkins
version: '2'
services:
jenkins:
image: robfrank/jenkins:latest
ports:
- 8080:8080
- 50000:50000
privileged: false
volumes:
- ~/volumes/jenkins_home:/var/jenkins_home
- /usr/bin/docker:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
- /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
/usr/bin/docker
/usr/bin/docker
Travis: declare the service docker
language: java
service: docker
notifications:
email:
- builder@mycompany.com
before_install:
- docker version
- docker info
- cd ./src/main/docker/orientdb && ./build.sh && cd -
- cd ./src/main/docker/postgresql-dvdrental && ./build.sh && cd -
jdk:
- openjdk8
- openjdk12
Github Actions: just works
Scenarios
Test over different versions of a single database with
parametric test
Test a feature over multiple databases
Test your app against (or supported by) a complex env:
queue, kv-store, log aggregator, search engine
Use a compose file if necessary
Let’s code!
PostgreSQL container
@Container
public static PostgreSQLContainer container = new PostgreSQLContainer();
@Test
public void shouldTestSimpleQuery() throws SQLException {
Connection conn = DriverManager.getConnection(container.getJdbcUrl(),
container.getUsername(), container.getPassword());
Statement stmt = conn.createStatement();
stmt.execute("SELECT 1");
ResultSet resultSet = stmt.getResultSet();
resultSet.next();
assertThat(resultSet.getInt(1)).isEqualTo(1);
}
Jdbc url and init method
@Test
public void shouldSelectFromBar() throws SQLException {
String jdbcUrl =
"jdbc:tc:postgresql:9.6.8://hostname/databasename?&TC_INITFUNCTION=io.github.robfrank.testc
ontainers.JavaJdbcUrlTest::sampleInitFunction";
Connection conn = DriverManager.getConnection(jdbcUrl);
Statement stmt = conn.createStatement();
stmt.execute("SELECT * FROM bar");
ResultSet resultSet = stmt.getResultSet();
resultSet.next();
assertThat(resultSet.getString("foo")).isEqualTo("hello world");
}
Jdbc url and init method
public static void sampleInitFunction(Connection connection) throws SQLException {
connection.createStatement().execute("CREATE TABLE bar (n" +
" foo VARCHAR(255)n" +
");");
connection.createStatement().execute("INSERT INTO bar (foo) VALUES ('hello world');");
connection.createStatement().execute("CREATE TABLE my_counter (n" +
" n INTn" +
");");
}
Jdbc url script
@Test
public void shouldSelectFromBar() throws SQLException {
String jdbcUrl =
"jdbc:tc:postgresql:9.6.8://hostname/databasename?&TC_INITSCRIPT=initdb.sql";
Connection conn = DriverManager.getConnection(jdbcUrl);
Statement stmt = conn.createStatement();
stmt.execute("SELECT * FROM bar");
ResultSet resultSet = stmt.getResultSet();
resultSet.next();
assertThat(resultSet.getString("foo")).isEqualTo("hello world");
}
Generic container, image based
@Container
public static GenericContainer container = new GenericContainer("orientdb:3.0.23")
.withExposedPorts(2424, 2480)
.withEnv("ORIENTDB_ROOT_PASSWORD", "rootpassword")
.waitingFor(Wait.forListeningPort());
Generic container, image based
@Test
internal fun `should select beers vertexes`() {
OrientDB("remote:${container.containerIpAddress}:${container.firstMappedPort}", OrientDBConfig.defaultConfig()).use {
orientDB ->
orientDB.open("openbeer", "admin", "admin").use { db ->
db.query("select from Beer limit 10").use { resultSet ->
resultSet.asSequence()
.toList().apply {
assertThat(this).hasSize(10)
}.map { record ->
assertThat(record.isVertex).isTrue()
assertThat(record.hasProperty("name")).isTrue()
assertThat(record.hasProperty("descript")).isTrue()
record.vertex.get()
}.forEach { vertex: OVertex ->
assertThat(vertex.getEdges(ODirection.OUT)).isNotEmpty
}
}
}
}
Recap
Add to your project
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>MODULE_NAME</artifactId>
<version>1.12.0</version>
<scope>test</scope>
</dependency>
Use in test
@Container
val container = PostgreSQLContainer<Nothing>()
@Test fun `should perform simple query`() {
val conn = DriverManager.getConnection(container.jdbcUrl,
container.username,
container.password)
val stmt = conn.createStatement()
stmt.execute("SELECT 1")
val resultSet = stmt.resultSet
resultSet.next()
assertThat(resultSet.getInt(1)).isEqualTo(1)
}
https://github.com/robfrank/testcontainers-examples
ArcadeAnalytics connectors: https://github.com/arcadeAnalytics/arcade-connectors/
Kotlin and Java
Single container for multiple test classes
Neo4j, Postgres, Mysql, OrientDB, JanusGraph test and custom images
Alfresco Activiti: https://github.com/Activiti/activiti-cloud-query-service
Use of Testcontainers instead of maven plugin for lifecycle
Other examples
Thank you!

More Related Content

What's hot (20)

PPT
[Java] Khái niệm về RMI trong Java và cách sử dụng RMI
Tí Bụng Bự
 
DOC
Search engine viet
Duy Vọng
 
PPT
Testing concepts ppt
Rathna Priya
 
PPTX
Eleven step of software testing process
Himanshu
 
PDF
Automated Testing for Embedded Software in C or C++
Lars Thorup
 
PPTX
Software_Testing_ppt.pptx
BharathReddy615859
 
PPTX
College Notificatoin system Mini Project Slides
Saleeh Kalluvetti
 
PDF
Đồ Án Tìm Hiểu Phần Mềm Loadrunner Kiểm Tra Hiệu Năng Website
nataliej4
 
PPTX
Automation using Appium
Livares Technologies Pvt Ltd
 
PPT
Softwaretesting
nazeer pasha
 
DOC
Srs sample
Prakash Dhanasekar
 
PPT
Manual testing ppt
Santosh Maranabasari
 
PPTX
[Seminar] Hướng dẫn viết test case
Le Vu Trung Thanh
 
PDF
Paraphrase Detection in NLP
Yuriy Guts
 
PPTX
Unit 6 SDET Web Services Testing.pptx
Dr. Pallawi Bulakh
 
PDF
Testing types functional and nonfunctional - Kati Holasz
Holasz Kati
 
PDF
How to start performance testing project
NaveenKumar Namachivayam
 
DOC
Hướng dẫn đổi tên máy domain controller
laonap166
 
PDF
API Testing. Streamline your testing process.
Andrey Oleynik
 
PPTX
Learn software development
Eduonix Learning Solutions
 
[Java] Khái niệm về RMI trong Java và cách sử dụng RMI
Tí Bụng Bự
 
Search engine viet
Duy Vọng
 
Testing concepts ppt
Rathna Priya
 
Eleven step of software testing process
Himanshu
 
Automated Testing for Embedded Software in C or C++
Lars Thorup
 
Software_Testing_ppt.pptx
BharathReddy615859
 
College Notificatoin system Mini Project Slides
Saleeh Kalluvetti
 
Đồ Án Tìm Hiểu Phần Mềm Loadrunner Kiểm Tra Hiệu Năng Website
nataliej4
 
Automation using Appium
Livares Technologies Pvt Ltd
 
Softwaretesting
nazeer pasha
 
Srs sample
Prakash Dhanasekar
 
Manual testing ppt
Santosh Maranabasari
 
[Seminar] Hướng dẫn viết test case
Le Vu Trung Thanh
 
Paraphrase Detection in NLP
Yuriy Guts
 
Unit 6 SDET Web Services Testing.pptx
Dr. Pallawi Bulakh
 
Testing types functional and nonfunctional - Kati Holasz
Holasz Kati
 
How to start performance testing project
NaveenKumar Namachivayam
 
Hướng dẫn đổi tên máy domain controller
laonap166
 
API Testing. Streamline your testing process.
Andrey Oleynik
 
Learn software development
Eduonix Learning Solutions
 

Similar to Integration tests: use the containers, Luke! (20)

PDF
Testcontainers - Geekout EE 2017 presentation
Richard North
 
PDF
Level Up Your Integration Testing With Testcontainers
VMware Tanzu
 
PDF
Prod-Like Integration Testing for Distributed Containerized Applications
VMware Tanzu
 
PDF
JUnit5 and TestContainers
Sunghyouk Bae
 
PDF
JavaOne 2017 - TestContainers: integration testing without the hassle
Anton Arhipov
 
PDF
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
PDF
Scala, docker and testing, oh my! mario camou
J On The Beach
 
PPTX
Easy Java Integration Testing with Testcontainers​
Payara
 
PPTX
Simplifying Integration Testing in a Containerized World
ssuser9d4fc7
 
PDF
Containerized End-2-End Testing - Agile Testing Meetup at Süddeutsche Zeitung...
Tobias Schneck
 
PDF
GeeCON Prague 2017 - TestContainers
Anton Arhipov
 
PPTX
JBCN_Testing_With_Containers
Grace Jansen
 
PDF
Testing your application on Google App Engine
Inphina Technologies
 
PDF
Testing Your Application On Google App Engine
IndicThreads
 
PDF
OOP2017: Containerized End-2-End Testing – automate it!
Tobias Schneck
 
PPTX
JLove - Replicating production on your laptop using the magic of containers
Grace Jansen
 
PDF
ContainerCon - Test Driven Infrastructure
Yury Tsarev
 
PDF
Integration testing - A&BP CC
JWORKS powered by Ordina
 
PDF
ExpoQA 2017 Docker and CI
ElasTest Project
 
PDF
Docker & ci
Patxi Gortázar
 
Testcontainers - Geekout EE 2017 presentation
Richard North
 
Level Up Your Integration Testing With Testcontainers
VMware Tanzu
 
Prod-Like Integration Testing for Distributed Containerized Applications
VMware Tanzu
 
JUnit5 and TestContainers
Sunghyouk Bae
 
JavaOne 2017 - TestContainers: integration testing without the hassle
Anton Arhipov
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
Scala, docker and testing, oh my! mario camou
J On The Beach
 
Easy Java Integration Testing with Testcontainers​
Payara
 
Simplifying Integration Testing in a Containerized World
ssuser9d4fc7
 
Containerized End-2-End Testing - Agile Testing Meetup at Süddeutsche Zeitung...
Tobias Schneck
 
GeeCON Prague 2017 - TestContainers
Anton Arhipov
 
JBCN_Testing_With_Containers
Grace Jansen
 
Testing your application on Google App Engine
Inphina Technologies
 
Testing Your Application On Google App Engine
IndicThreads
 
OOP2017: Containerized End-2-End Testing – automate it!
Tobias Schneck
 
JLove - Replicating production on your laptop using the magic of containers
Grace Jansen
 
ContainerCon - Test Driven Infrastructure
Yury Tsarev
 
Integration testing - A&BP CC
JWORKS powered by Ordina
 
ExpoQA 2017 Docker and CI
ElasTest Project
 
Docker & ci
Patxi Gortázar
 
Ad

More from Roberto Franchini (8)

PDF
OrientDB - The 2nd generation of (multi-model) NoSQL
Roberto Franchini
 
PPTX
Where are yours vertexes and what are they talking about?
Roberto Franchini
 
PDF
What the hell is your software doing at runtime?
Roberto Franchini
 
PDF
Java application monitoring with Dropwizard Metrics and graphite
Roberto Franchini
 
PDF
Codemotion Rome 2015. GlusterFS
Roberto Franchini
 
PDF
GlusterFs: a scalable file system for today's and tomorrow's big data
Roberto Franchini
 
PDF
Redis for duplicate detection on real time stream
Roberto Franchini
 
ODP
TDD - una introduzione
Roberto Franchini
 
OrientDB - The 2nd generation of (multi-model) NoSQL
Roberto Franchini
 
Where are yours vertexes and what are they talking about?
Roberto Franchini
 
What the hell is your software doing at runtime?
Roberto Franchini
 
Java application monitoring with Dropwizard Metrics and graphite
Roberto Franchini
 
Codemotion Rome 2015. GlusterFS
Roberto Franchini
 
GlusterFs: a scalable file system for today's and tomorrow's big data
Roberto Franchini
 
Redis for duplicate detection on real time stream
Roberto Franchini
 
TDD - una introduzione
Roberto Franchini
 
Ad

Recently uploaded (20)

PPTX
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PDF
Add Background Images to Charts in IBM SPSS Statistics Version 31.pdf
Version 1 Analytics
 
PPTX
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Driver Easy Pro 6.1.1 Crack Licensce key 2025 FREE
utfefguu
 
PDF
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PPTX
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
Add Background Images to Charts in IBM SPSS Statistics Version 31.pdf
Version 1 Analytics
 
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Driver Easy Pro 6.1.1 Crack Licensce key 2025 FREE
utfefguu
 
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 

Integration tests: use the containers, Luke!

  • 1. Integration tests: use the containers, Luke! Roberto “Frank” Franchini @robfrankie
  • 3. Former CTO of Arcade Analytics Joined Activiti team in Alfresco
  • 9. Same output from different data-sources
  • 10. One new connector per month
  • 11. New features every week for every connector
  • 12. Tests: features x connectors
  • 13. Test Feature B Test Feature A Test Feature C Test Feature D
  • 15. How to avoid fear?
  • 19. Activiti Cloud is the first Cloud Native BPM framework built to provide a scalable and transparent solution for BPM implementations in cloud environments.
  • 22. Each microservice has its own integration testing suite that needs RabbiMQ and KeyCloack to be started before
  • 23. Every morning a developer wakes up and starts containers docker run -it -p 5672:5672 -p 15672:15672 --rm rabbitmq:management docker run -it --rm -p 8180:8180 activiti/activiti-keycloak
  • 24. Then run tests in the IDE (Poor developer experience)
  • 25. Don’t start containers manually anymore
  • 31. Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
  • 34. Ports for GO, .NET, Rust, Js
  • 36. Temporary database containers: specialized PostgreSQL, MySQL, MsSQL Server, MariaDB, Oracle XE, Virtuoso
  • 37. RDBMS containers @Container public static PostgreSQLContainer container = new PostgreSQLContainer(); @Container public static MySQLContainer container = new MySQLContainer(); @Container public static OracleContainer container = new OracleContainer();
  • 38. Others containers: neo4j, couchbase, toxy-proxy, kafka, redis, influxDB, elasticSearch, rabbitMQ
  • 39. Others containers @Container public static Neo4jContainer container = new Neo4jContainer(); @Container public static InfluxDBContainer container = new InfluxDBContainer(); @Container public static KafkaContainer container = new KafkaContainer(); @Container public static RabbitMQContainer container = new RabbitMQContainer();
  • 40. Webdriver containers: run a Dockerized Chrome or Firefox browser ready for Selenium/Webdriver operations - complete with automatic video recording
  • 41. Selenium private val chrome: BrowserWebDriverContainer<Nothing> = BrowserWebDriverContainer<Nothing>() .apply { withDesiredCapabilities(DesiredCapabilities.chrome()) withRecordingMode(RECORD_ALL, File("target")) start() }
  • 42. Generic containers: run any Docker container as a test dependency
  • 43. Generic container, image based @Container public static GenericContainer container = new GenericContainer("orientdb:3.0.23") .withExposedPorts(2424, 2480) .withEnv("ORIENTDB_ROOT_PASSWORD", "rootpassword") .waitingFor(Wait.forListeningPort());
  • 44. ROM debian:stretch-slim LABEL maintainer="NGINX Docker Maintainers <[email protected]>" ENV NGINX_VERSION 1.15.5-1~stretch ENV NJS_VERSION 1.15.5.0.2.4-1~stretch RUN set -x && apt-get update && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 apt-transport-https ca-certificates && NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9B F62; found=''; for server in ha.pool.sks-keyservers.net hkp://keyserver.ubuntu.com:80 hkp://p80.pool.sks-keyservers.net:80 version: '2' services: elasticsearch: build: context: elasticsearch/ args: ELK_VERSION: $ELK_VERSION volumes: - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch .yml:ro ports: - "9200:9200" - "9300:9300" environment: ES_JAVA_OPTS: "-Xmx256m -Xms256m" networks: - elk logstash: build: context: logstash/ args: ELK_VERSION: $ELK_VERSION volumes: - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro - ./logstash/pipeline:/usr/share/logstash/pipeline:ro ports: - "5000:5000" - "9600:9600" environment: LS_JAVA_OPTS: "-Xmx256m -Xms256m" networks: - elk depends_on: - elasticsearch kibana: build: Use a compose Start from a Dockerfile
  • 45. Generic container from Dockerfile private val container: GenericContainer<Nothing> = GenericContainer<Nothing>( ImageFromDockerfile("robfrank/ngnix") .withFileFromPath("Dockerfile", Paths.get("./src/main/docker/nginx/Dockerfile")) ).apply { withExposedPorts(80) waitingFor(Wait.forListeningPort()) start() followOutput(Slf4jLogConsumer(log)) }
  • 46. Whatever is containerized by your team(s)
  • 48. H2 is fast, BUT doesn’t emulate specific features
  • 49. Testcontainers is slower*, BUT gives 100% db compatibility *not so slower
  • 50. Use in your CI env
  • 51. Jenkins DOOD: Docker outside of Docker DIND: Docker inside of Docker
  • 52. DOOD: Dockerfile FROM jenkins/jenkins:lts USER root RUN apt-get update && apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common && curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | apt-key add - && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") $(lsb_release -cs) stable" && apt-get update && apt-get install -y docker-ce && apt-get clean && rm -rf /var/lib/apt/lists/* RUN usermod -aG docker jenkins USER jenkins
  • 53. version: '2' services: jenkins: image: robfrank/jenkins:latest ports: - 8080:8080 - 50000:50000 privileged: false volumes: - ~/volumes/jenkins_home:/var/jenkins_home - /usr/bin/docker:/usr/bin/docker - /var/run/docker.sock:/var/run/docker.sock - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
  • 55. Travis: declare the service docker
  • 56. language: java service: docker notifications: email: - [email protected] before_install: - docker version - docker info - cd ./src/main/docker/orientdb && ./build.sh && cd - - cd ./src/main/docker/postgresql-dvdrental && ./build.sh && cd - jdk: - openjdk8 - openjdk12
  • 59. Test over different versions of a single database with parametric test
  • 60. Test a feature over multiple databases
  • 61. Test your app against (or supported by) a complex env: queue, kv-store, log aggregator, search engine
  • 62. Use a compose file if necessary
  • 64. PostgreSQL container @Container public static PostgreSQLContainer container = new PostgreSQLContainer(); @Test public void shouldTestSimpleQuery() throws SQLException { Connection conn = DriverManager.getConnection(container.getJdbcUrl(), container.getUsername(), container.getPassword()); Statement stmt = conn.createStatement(); stmt.execute("SELECT 1"); ResultSet resultSet = stmt.getResultSet(); resultSet.next(); assertThat(resultSet.getInt(1)).isEqualTo(1); }
  • 65. Jdbc url and init method @Test public void shouldSelectFromBar() throws SQLException { String jdbcUrl = "jdbc:tc:postgresql:9.6.8://hostname/databasename?&TC_INITFUNCTION=io.github.robfrank.testc ontainers.JavaJdbcUrlTest::sampleInitFunction"; Connection conn = DriverManager.getConnection(jdbcUrl); Statement stmt = conn.createStatement(); stmt.execute("SELECT * FROM bar"); ResultSet resultSet = stmt.getResultSet(); resultSet.next(); assertThat(resultSet.getString("foo")).isEqualTo("hello world"); }
  • 66. Jdbc url and init method public static void sampleInitFunction(Connection connection) throws SQLException { connection.createStatement().execute("CREATE TABLE bar (n" + " foo VARCHAR(255)n" + ");"); connection.createStatement().execute("INSERT INTO bar (foo) VALUES ('hello world');"); connection.createStatement().execute("CREATE TABLE my_counter (n" + " n INTn" + ");"); }
  • 67. Jdbc url script @Test public void shouldSelectFromBar() throws SQLException { String jdbcUrl = "jdbc:tc:postgresql:9.6.8://hostname/databasename?&TC_INITSCRIPT=initdb.sql"; Connection conn = DriverManager.getConnection(jdbcUrl); Statement stmt = conn.createStatement(); stmt.execute("SELECT * FROM bar"); ResultSet resultSet = stmt.getResultSet(); resultSet.next(); assertThat(resultSet.getString("foo")).isEqualTo("hello world"); }
  • 68. Generic container, image based @Container public static GenericContainer container = new GenericContainer("orientdb:3.0.23") .withExposedPorts(2424, 2480) .withEnv("ORIENTDB_ROOT_PASSWORD", "rootpassword") .waitingFor(Wait.forListeningPort());
  • 69. Generic container, image based @Test internal fun `should select beers vertexes`() { OrientDB("remote:${container.containerIpAddress}:${container.firstMappedPort}", OrientDBConfig.defaultConfig()).use { orientDB -> orientDB.open("openbeer", "admin", "admin").use { db -> db.query("select from Beer limit 10").use { resultSet -> resultSet.asSequence() .toList().apply { assertThat(this).hasSize(10) }.map { record -> assertThat(record.isVertex).isTrue() assertThat(record.hasProperty("name")).isTrue() assertThat(record.hasProperty("descript")).isTrue() record.vertex.get() }.forEach { vertex: OVertex -> assertThat(vertex.getEdges(ODirection.OUT)).isNotEmpty } } } }
  • 70. Recap
  • 71. Add to your project <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <version>1.12.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>MODULE_NAME</artifactId> <version>1.12.0</version> <scope>test</scope> </dependency>
  • 72. Use in test @Container val container = PostgreSQLContainer<Nothing>() @Test fun `should perform simple query`() { val conn = DriverManager.getConnection(container.jdbcUrl, container.username, container.password) val stmt = conn.createStatement() stmt.execute("SELECT 1") val resultSet = stmt.resultSet resultSet.next() assertThat(resultSet.getInt(1)).isEqualTo(1) }
  • 74. ArcadeAnalytics connectors: https://github.com/arcadeAnalytics/arcade-connectors/ Kotlin and Java Single container for multiple test classes Neo4j, Postgres, Mysql, OrientDB, JanusGraph test and custom images Alfresco Activiti: https://github.com/Activiti/activiti-cloud-query-service Use of Testcontainers instead of maven plugin for lifecycle Other examples