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

What's hot (20)

Getting Started with Kubernetes
Getting Started with Kubernetes Getting Started with Kubernetes
Getting Started with Kubernetes
 
Jenkins tutorial
Jenkins tutorialJenkins tutorial
Jenkins tutorial
 
Kubernetes Introduction
Kubernetes IntroductionKubernetes Introduction
Kubernetes Introduction
 
Automation with ansible
Automation with ansibleAutomation with ansible
Automation with ansible
 
Automating with Ansible
Automating with AnsibleAutomating with Ansible
Automating with Ansible
 
Jenkins-CI
Jenkins-CIJenkins-CI
Jenkins-CI
 
Kubernetes #1 intro
Kubernetes #1   introKubernetes #1   intro
Kubernetes #1 intro
 
(Declarative) Jenkins Pipelines
(Declarative) Jenkins Pipelines(Declarative) Jenkins Pipelines
(Declarative) Jenkins Pipelines
 
Jenkins
JenkinsJenkins
Jenkins
 
Introduction to Docker Compose
Introduction to Docker ComposeIntroduction to Docker Compose
Introduction to Docker Compose
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Containers and Docker
Containers and DockerContainers and Docker
Containers and Docker
 
Introduction to Kubernetes Workshop
Introduction to Kubernetes WorkshopIntroduction to Kubernetes Workshop
Introduction to Kubernetes Workshop
 
Docker and the Linux Kernel
Docker and the Linux KernelDocker and the Linux Kernel
Docker and the Linux Kernel
 
Testcontainers - Geekout EE 2017 presentation
Testcontainers - Geekout EE 2017 presentationTestcontainers - Geekout EE 2017 presentation
Testcontainers - Geekout EE 2017 presentation
 
How to write a Dockerfile
How to write a DockerfileHow to write a Dockerfile
How to write a Dockerfile
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
 
infrastructure as code
infrastructure as codeinfrastructure as code
infrastructure as code
 
Introduction to GitHub Actions
Introduction to GitHub ActionsIntroduction to GitHub Actions
Introduction to GitHub Actions
 
Jenkins presentation
Jenkins presentationJenkins presentation
Jenkins presentation
 

Similar to Integration tests: use the containers, Luke!

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
Using Kubernetes for Continuous Integration and Continuous DeliveryUsing Kubernetes for Continuous Integration and Continuous Delivery
Using Kubernetes for Continuous Integration and Continuous Delivery
 
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
 
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
 
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
 
Omaha (Google Update) server
Omaha (Google Update) serverOmaha (Google Update) server
Omaha (Google Update) server
 

More from Roberto 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

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Recently uploaded (20)

The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 

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