SlideShare a Scribd company logo
1 of 75
Download to read offline
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
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
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.
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
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
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

Docker introduction
Docker introductionDocker introduction
Docker introductiondotCloud
 
Jenkins Introduction
Jenkins IntroductionJenkins Introduction
Jenkins IntroductionPavan Gupta
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first stepsRenato Primavera
 
Terraform modules restructured
Terraform modules restructuredTerraform modules restructured
Terraform modules restructuredAmi Mahloof
 
CICD Pipeline Using Github Actions
CICD Pipeline Using Github ActionsCICD Pipeline Using Github Actions
CICD Pipeline Using Github ActionsKumar Shìvam
 
Jenkins tutorial for beginners
Jenkins tutorial for beginnersJenkins tutorial for beginners
Jenkins tutorial for beginnersBugRaptors
 
Unix shell scripting basics
Unix shell scripting basicsUnix shell scripting basics
Unix shell scripting basicsManav Prasad
 
(DVO401) Deep Dive into Blue/Green Deployments on AWS
(DVO401) Deep Dive into Blue/Green Deployments on AWS(DVO401) Deep Dive into Blue/Green Deployments on AWS
(DVO401) Deep Dive into Blue/Green Deployments on AWSAmazon Web Services
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to dockerWei-Ting Kuo
 
Automation with ansible
Automation with ansibleAutomation with ansible
Automation with ansibleKhizer Naeem
 
Manejo de packages en Kubernetes con Helm
Manejo de packages en Kubernetes con HelmManejo de packages en Kubernetes con Helm
Manejo de packages en Kubernetes con HelmMario IC
 

What's hot (20)

Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Docker, LinuX Container
Docker, LinuX ContainerDocker, LinuX Container
Docker, LinuX Container
 
Jenkins Introduction
Jenkins IntroductionJenkins Introduction
Jenkins Introduction
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Terraform modules restructured
Terraform modules restructuredTerraform modules restructured
Terraform modules restructured
 
Junit
JunitJunit
Junit
 
Devops
DevopsDevops
Devops
 
Maven tutorial
Maven tutorialMaven tutorial
Maven tutorial
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
CICD Pipeline Using Github Actions
CICD Pipeline Using Github ActionsCICD Pipeline Using Github Actions
CICD Pipeline Using Github Actions
 
Jenkins tutorial for beginners
Jenkins tutorial for beginnersJenkins tutorial for beginners
Jenkins tutorial for beginners
 
Unix shell scripting basics
Unix shell scripting basicsUnix shell scripting basics
Unix shell scripting basics
 
(DVO401) Deep Dive into Blue/Green Deployments on AWS
(DVO401) Deep Dive into Blue/Green Deployments on AWS(DVO401) Deep Dive into Blue/Green Deployments on AWS
(DVO401) Deep Dive into Blue/Green Deployments on AWS
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to docker
 
Jenkins CI presentation
Jenkins CI presentationJenkins CI presentation
Jenkins CI presentation
 
Automation with ansible
Automation with ansibleAutomation with ansible
Automation with ansible
 
Manejo de packages en Kubernetes con Helm
Manejo de packages en Kubernetes con HelmManejo de packages en Kubernetes con Helm
Manejo de packages en Kubernetes con Helm
 
Jenkins Automation
Jenkins AutomationJenkins Automation
Jenkins Automation
 

Similar to Integration tests: use the containers, Luke!

RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesPavol Pitoňák
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidenceJohn Congdon
 
OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersJavan Rasokat
 
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...Amazon Web Services
 
Continuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECSContinuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECSAmazon Web Services
 
Test Automation for NoSQL Databases
Test Automation for NoSQL DatabasesTest Automation for NoSQL Databases
Test Automation for NoSQL DatabasesTobias Trelle
 
DCSF 19 Building Your Development Pipeline
DCSF 19 Building Your Development Pipeline  DCSF 19 Building Your Development Pipeline
DCSF 19 Building Your Development Pipeline Docker, Inc.
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionBrennan Saeta
 
Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...
Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...
Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...Docker, Inc.
 
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2daysUsing Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2daysCarlos Sanchez
 
Using Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous DeliveryUsing Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous DeliveryCarlos Sanchez
 
Deploying windows containers with kubernetes
Deploying windows containers with kubernetesDeploying windows containers with kubernetes
Deploying windows containers with kubernetesBen Hall
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleSkills Matter
 
Javascript tdd byandreapaciolla
Javascript tdd byandreapaciollaJavascript tdd byandreapaciolla
Javascript tdd byandreapaciollaAndrea Paciolla
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 
Continuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL ServerContinuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL ServerChris Adkin
 
(Declarative) Jenkins Pipelines
(Declarative) Jenkins Pipelines(Declarative) Jenkins Pipelines
(Declarative) Jenkins PipelinesSteffen Gebert
 
Develop with docker 2014 aug
Develop with docker 2014 augDevelop with docker 2014 aug
Develop with docker 2014 augVincent De Smet
 
Docker presentasjon java bin
Docker presentasjon java binDocker presentasjon java bin
Docker presentasjon java binOlve Hansen
 
Server(less) Swift at SwiftCloudWorkshop 3
Server(less) Swift at SwiftCloudWorkshop 3Server(less) Swift at SwiftCloudWorkshop 3
Server(less) Swift at SwiftCloudWorkshop 3kognate
 

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

RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidence
 
OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA Testers
 
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
AWS December 2015 Webinar Series - Continuous Delivery to Amazon EC2 Containe...
 
Continuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECSContinuous Delivery with Docker and Amazon ECS
Continuous Delivery with Docker and Amazon ECS
 
Test Automation for NoSQL Databases
Test Automation for NoSQL DatabasesTest Automation for NoSQL Databases
Test Automation for NoSQL Databases
 
DCSF 19 Building Your Development Pipeline
DCSF 19 Building Your Development Pipeline  DCSF 19 Building Your Development Pipeline
DCSF 19 Building Your Development Pipeline
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline Execution
 
Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...
Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...
Build, Publish, Deploy and Test Docker images and containers with Jenkins Wor...
 
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2daysUsing Kubernetes for Continuous Integration and Continuous Delivery. Java2days
Using Kubernetes for Continuous Integration and Continuous Delivery. Java2days
 
Using Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous DeliveryUsing Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous Delivery
 
Deploying windows containers with kubernetes
Deploying windows containers with kubernetesDeploying windows containers with kubernetes
Deploying windows containers with kubernetes
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
Javascript tdd byandreapaciolla
Javascript tdd byandreapaciollaJavascript tdd byandreapaciolla
Javascript tdd byandreapaciolla
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
Continuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL ServerContinuous Integration With Jenkins Docker SQL Server
Continuous Integration With Jenkins Docker SQL Server
 
(Declarative) Jenkins Pipelines
(Declarative) Jenkins Pipelines(Declarative) Jenkins Pipelines
(Declarative) Jenkins Pipelines
 
Develop with docker 2014 aug
Develop with docker 2014 augDevelop with docker 2014 aug
Develop with docker 2014 aug
 
Docker presentasjon java bin
Docker presentasjon java binDocker presentasjon java bin
Docker presentasjon java bin
 
Server(less) Swift at SwiftCloudWorkshop 3
Server(less) Swift at SwiftCloudWorkshop 3Server(less) Swift at SwiftCloudWorkshop 3
Server(less) Swift at SwiftCloudWorkshop 3
 

More from Roberto Franchini

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

More from Roberto Franchini (8)

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

Recently uploaded

SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 

Recently uploaded (20)

SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 

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
  • 6.
  • 7.
  • 8.
  • 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?
  • 17.
  • 19. Activiti Cloud is the first Cloud Native BPM framework built to provide a scalable and transparent solution for BPM implementations in cloud environments.
  • 20.
  • 21.
  • 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
  • 30.
  • 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.
  • 33.
  • 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 <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
  • 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: - 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
  • 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