129
Testing Java Microservices From Unit to Deployment Tests Alex Soto @alexsotob Andy Gumbrecht @AndyGeeDe

Testing Java Microservices Devoxx be 2017

Embed Size (px)

Citation preview

Page 1: Testing Java Microservices Devoxx be 2017

Testing Java MicroservicesFrom Unit to Deployment TestsAlex Soto@alexsotob

Andy Gumbrecht@AndyGeeDe

Page 2: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe2

Alex Soto

Red Hat Engineer www.lordofthejars.com@alexsotob

Who Am I?

Page 3: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe3

Andy Gumbrecht

Tomitribe Consultant Developerwww.tomitribe.com

Apache TomEE PMCTomee.apache.org

@AndyGeeDeAlso a dad

Who Am I?

Page 4: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe4

https://www.manning.com/books/testing-java-microservices

Oops! Shameless plug alert

Page 5: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe5

What Are Microservices?

Page 6: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe6

Anatomy of Microservice

http://microprofile.io

https://projects.eclipse.org/proposals/eclipse-microprofile

Page 7: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe7

Resources

Domain

Controllers

RepositoriesGatew

ays

External Service

Page 8: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe8

Testing Evolution

Manual Tests

After Code Automatic

Test

Test First TDD and BDD

Service Virtualization

and CDC

Testing in Production

Page 9: Testing Java Microservices Devoxx be 2017

@alexsotob

Unit

Component

DeploymentIntegration

Contract

What does this mean in terms of testing?Testing Strategies

9

Production

Page 10: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe10

Page 11: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe11

Page 12: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe12

Questions

Page 13: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe13

Unit Testing

Page 14: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe14

Page 15: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe15

Test Doubles

Page 16: Testing Java Microservices Devoxx be 2017

@alexsotob

DummiesPassed but not used

FakesImplementation with shortcuts

StubsProvide predefined answers

MocksPre-programmed expectations,

SpiesRecord information

Test DoublesKind of test doubles

16

Page 17: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

JUnit Test

@Test

public void should_find_composer_by_name() {

// Given:

Composers composers = new Composers();

// When:

final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart");

// Then:

assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName);

}

17

Readable name

BDD style

Assertions

Page 18: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe18

Questions

Page 19: Testing Java Microservices Devoxx be 2017

@alexsotob19

AssertJ

Page 20: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

AssertJ Test

import static org.assertj.core.api.Assertions.assertThat;

@Test

public void should_find_composer_by_name() {

// Given:

Composers composers = new Composers();

// When:

final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart”);

// Then:

assertThat(mozart.getName()).isEqualTo("Wolfgang Amadeus Mozart”);

assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName);

assertThat(mozart.getBirthdate()).isEqualTo(LocalDate.of(1756, 1, 27));

assertThat(mozart).isEqualToComparingFieldByField(expectedMozart);

assertThat(mozart).isEqualToIgnoringNullFields(expectedMozart);

}

20

Static Import

Readable Assertions

Not Depending on Equals

Page 21: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

AssertJ Test Collections@Test

public void should_find_operas_by_composer_name() {

// Given:

Composers composers = new Composers();

// When:

final List<Opera> operas = composers.findOperasByComposerName("Wolfgang Amadeus Mozart");

// Then:

assertThat(operas)

.hasSize(2)

.extracting(Opera::getName)

.containsExactlyInAnyOrder("Die Zauberflöte", "Don Giovanni”);

}

21

Chained method (IDE support)

Creates a list of getName results

Methods for String

Page 22: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

AssertJ Soft Assertions@Test

public void should_find_composer_by_name_soft_assertions() {

// Given:

Composers composers = new Composers();

// When:

final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart");

// Then:

SoftAssertions.assertSoftly(softly -> {

softly.assertThat(mozart.getName()).isEqualTo("Wolfgang Amadeus Mozart");

softly.assertThat(mozart.getEra()).isEqualTo(Era.CLASSICAL);

softly.assertThat(mozart.getBirthdate()).isEqualTo(LocalDate.of(1756, 1, 27));

softly.assertThat(mozart.getDied()).isEqualTo(LocalDate.of(1791, 12, 5));

});

}

22

Java 8 Lambda

All assertions in Block

Page 23: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

AssertJ Exceptions@Test

public void should_throw_exception_if_composer_not_found_version_3() {

// Given:

Composers composers = new Composers();

// When:

Throwable thrown = catchThrowable(() -> composers.findComposerByName("Antonio Salieri"));

// Then:

assertThat(thrown).isInstanceOf(IllegalArgumentException.class)

.withFailMessage("Composer Antonio Salieri is not found”);

}

23

Catch Exception of Lambda

Assertion Methods for Exceptions

Page 24: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe24

Questions

Page 25: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe25

Page 26: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Init Mocks

@RunWith(MockitoJUnitRunner.class)

public class Test {

@Mock EmailService email;

}

public class Test {

@Mock EmailService email;

@Before public void before() {

MockitoAnnotations.initMocks(this)

}

}

@Rule public MockitoRule mockito = MockitoJUnit.rule();

EmailService emailService = Mockito.mock(EmailService.class);

26

Using JUnit Runner

Defines Mock

Init programmatically

Without annotation

With JUnit Rule

Page 27: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Using Mocks@Mock EmailService email;

Mockito.when(email.receiveBodyMessagesWithSubject("My Subject”))

.thenReturn("This is My Message")

Mockito.when(email.receiveBodyMessagesWithSubject(Matchers.anyString()))

.thenReturn(“This is My Message");

27

Record expectation

Concrete Parameter

Any parameter

Page 28: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Verifying Mocks

@Mock EmailService email;

InvoiceService invoiceService = new InvoiceService(email);

invoiceService.send();

Mockito.verify(email, Mockito.times(1))

.sendMessage(Matchers.anyString(), Matchers.anyString());

28

Mock used as collaborator

Verify mocked method is called once

Page 29: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Capturing Arguments Mocks@Mock EmailService email;

InvoiceService invoiceService = new InvoiceService(email);

invoiceService.send();

verify(email, times(1))

.sendMessage(

argThat(subject -> subject.startsWith(“Invoice:")),

Matchers.anyString()

);

29

Mock used as collaborator

Verify content first param value of sendMessage

Page 30: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Bonus Track (JUnit 5)@ExtendWith(MockitoExtension.class)

class MyMockitoTest {

@BeforeEach

void init(@Mock Person person) {

when(person.getName()).thenReturn("Dilbert");

}

@Test

void simpleTestWithInjectedMock(@Mock Person person) {

assertThat(person.getName()).isEqualTo("Dilbert");

}

}

30

Mockito Extension

Initialize Mock before each test

Use injected Mock

Page 31: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

DEMO

31

Page 32: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe32

Questions

Page 33: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe33

Component Testing

Page 34: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Arquillian@RunWith(Arquillian.class)

public class ColorServiceTest {

@Deployment(testable = false)

public static WebArchive createDeployment() {

return ShrinkWrap.create(WebArchive.class).addClasses(ColorService.class, Color.class);

}

@ArquillianResource

private URL webappUrl;

@Test

public void getColorObject() throws Exception {

final WebClient webClient = WebClient.create(webappUrl.toURI());

final Color color =

webClient.accept(MediaType.APPLICATION_JSON).path("color/object").get(Color.class);

}

}

34

Arquillian Runner

WAR Deployment

Injects the application URL

Real REST call

Page 35: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Spring Boot@RunWith(SpringRunner.class)

@SpringBootTest

public class MyTests {

@Autowired

Invoice invoice;

@Test

public void should_generate_invoice_report() {

}

}

35

Spring Runner

Mock Servlet Runner

Inject Invoice

Page 36: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Spring Boot REST@RunWith(SpringRunner.class)

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

public class RandomPortExampleTests {

@Autowired

private TestRestTemplate restTemplate;

@LocalServerPort

int port;

@Test

public void exampleTest() {

String body = this.restTemplate.getForObject("/", String.class);

// assertions

}

}

36

Spring Runner Starts Embedded Servlet Runner

REST calls to running server

Port where servlet is started

Executes REST call

Page 37: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Wildfly Swarm

@RunWith(Arquillian.class)

@DefaultDeployment

public class InContainerTest {

@Inject

private Invoice invoice;

@Test

public void should_generate_an_invoice() {

}

}

37

Arquillian Runner

Create the deployment of the entire application.

CDI injects Invoice and its deps

Page 38: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Vert.X@RunWith(VertxUnitRunner.class)

public class CalculatorVerticleTest {

@Rule

public RunTestOnContext rule = new RunTestOnContext();

@Before

public void before(TestContext context) throws IOException {

rule.vertx().deployVerticle(CalculatorVerticle.class.getName(), options,

context.asyncAssertSuccess());

}

@After

public void after(TestContext context) {

rule.vertx().close(context.asyncAssertSuccess());

}

@Test

public void should_add_two_numbers(TestContext context) {}

38

VertX runner

Deploy Verticle under test

Shutdown VertX server

Page 39: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

DEMO

39

https://github.com/tomitribe/tomee-jaxrs-starter-project

Page 40: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe40

Questions

Page 41: Testing Java Microservices Devoxx be 2017

@alexsotob41

REST API

Page 42: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe42

Page 43: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

REST-assured Example

@Test

public void should_find_composer() {

given()

.when()

.get("{composer}", "Ludwig van Beethoven")

.then()

.assertThat()

.body("name", is("Ludwig van Beethoven"))

.body("operas.size()", is(1))

.body("operas.name", hasItems("Fidelio"));

}

43

GET Http Method with Placeholders

GPath Expression

Page 44: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

REST-assured Request Specification

.get("http://example.com/{composer}", "Ludwig van Beethoven")

RequestSpecBuilder builder = new RequestSpecBuilder();

builder.setBaseUri("http://example.com");

given().spec(builder.build())...

44

Use domain directly

Use Spec Builder

Reuse Everywhere

Page 45: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

REST-assured Auth

given().auth().oauth2(accessToken).when()...

given().auth().form("John", "Doe", springSecurity().withCsrfFieldName("_csrf")).when()...

given().auth().basic("username", "password").when()...

45

Page 46: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Custom ParsersNot just JSON and XML

SSL Support.relaxedHTTPSValidation()

FiltersInput/Output modification

JSON Schema ValidationContent not Important

More Features

of Rest-Assured

46

Page 47: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

DEMO

47

Page 48: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe48

Questions

Page 49: Testing Java Microservices Devoxx be 2017

@alexsotob49

Service Virtualization

Page 50: Testing Java Microservices Devoxx be 2017

@alexsotob

Service Virtualization Capture Mode

50

Service A External Network Service B

Scripts

Proxy

Page 51: Testing Java Microservices Devoxx be 2017

@alexsotob

Service Virtualization Simulate Mode

51

Service A External Network Service B

Scripts

Proxy

Page 52: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe52

Page 53: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Hoverfly Example@ClassRule

public static HoverflyRule hoverflyRule =

HoverflyRule.inCaptureOrSimulationMode("getcomposers.json");

@Test

public void should_get_composers_from_composers_microservice() {

// Given:

ComposersGateway composersGateway = new ComposersGateway("operas.com", 8081);

// When:

Composer composer = composersGateway.getComposer("Ludwig van Beethoven");

// Then:

assertThat(composer.getName()).isEqualTo("Ludwig van Beethoven");

}

53

Start Hoverfly

Use Real Host

Get Data from Real

Proxied data is stored

Page 54: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Hoverfly Example{

"data" : {

"pairs" : [{

"request" : {

"path" : "/Ludwig van Beethoven",

"method" : "GET",

"destination" : “operas.com:8081",

...

}

"response" : {

"status" : 200,

"body" : "{\"name\":\"Ludwig van Beethoven\",}",

"encodedBody" : false,

"headers" : {

"Connection" : [ "keep-alive" ],

...

}

}

}

}

54

Page 55: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Simulate Mode

@ClassRule

public static HoverflyRule hoverflyRule =

HoverflyRule.inSimulationMode(classpath("simulation.json"));

SimulationSource.dsl(

service("api.flight.com")

.get("/api/bookings/1")

.willReturn(success("{\"bookingId\":\"1\"\}", "application/json"))

)

55

Hoverfly JUnit Rule

Loads from Hoverfly format Json

Build Request/Responses Programmatically

Page 56: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Verification

hoverfly.verify(

service(matches("*.flight.*"))

.get("/api/bookings")

.anyQueryParams());

//

hoverfly.verify(

service("api.flight.com")

.put("/api/bookings/1")

.anyBody()

.header("Authorization", "Bearer some-token"), times(2));

56

Verify exactly one request

Verify exactly two requests

Page 57: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

DEMO

57

Page 58: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe58

Questions

Page 59: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe59

Integration Tests

Page 60: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe60

Resources

Domain

Controllers

RepositoriesGatew

ays

External Service

Page 61: Testing Java Microservices Devoxx be 2017

@alexsotob61

Persistence Tests

Page 62: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

First attempt@Test

public void should_find_composer_by_name() {

// Given:

clearDatabase(jdbcUri);

insertComposersData(jdbcUri);

ComposersRepository composersRepository = new ComposersRepository();

// When:

Composer mozart = composersRepository.findComposerByName("Wolfgang Amadeus Mozart");

// Then:

assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName);

}

62

Prepare Database

Execute Query

Page 63: Testing Java Microservices Devoxx be 2017

@alexsotob63

APE

Page 64: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

APE SQL example@Rule

public ArquillianPersistenceRule arquillianPersistenceRule =

new ArquillianPersistenceRule();

@DbUnit

@ArquillianResource

RdbmsPopulator rdbmsPopulator;

@Before

public void populateData() {

// Given:

rdbmsPopulator.forUri(jdbcUri).withDriver(Driver.class).withUsername("sa")

.withPassword("").usingDataSet("composers.yml")

.execute();

}

64

APE JUnit Rule (not necessary with Arquillian

Runner)

Set DBUnit usage

Configure Connection and Dataset

Populate

Page 65: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

APE SQL example

@After

public void clean_database() {

// Given:

rdbmsPopulator.forUri(jdbcUri).withDriver(Driver.class).withUsername("sa")

.withPassword("").usingDataSet("composers.yml")

.clean();

}

65

Clean After Test

Clean Database

Page 66: Testing Java Microservices Devoxx be 2017

@alexsotob

Boilerplate Code

Programmatic/Declarative@UsingDataSet/@ShouldMatchDataSet

SQL SupportDBUnit and Flyway

REST API SupportPostman Collections

NoSQL SupportMongoDB, Couchbase, CouchDB, Vault, Redis, Infinispan

Benefits of Arquillian APE

66

Page 67: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

DEMO

67

Page 68: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe68

Questions

Page 69: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe69

Page 70: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Page 71: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe71

Page 72: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Arquillian Cube DSL

@RunWith(SpringRunner.class)

@SpringBootTest(classes = PingPongController.class, webEnvironment = RANDOM_PORT)

@ContextConfiguration(initializers = PingPongSpringBootTest.Initializer.class)

public class PingPongSpringBootTest {

@ClassRule

public static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6")

.withPortBinding(6379);

@Autowired

TestRestTemplate restTemplate;

@Test

public void should_get_data_from_redis() {

}

72

Spring Boot Test

Custom Initializer

Container DefinitionSets Container Environment

Page 73: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Arquillian Cube Example@RunWith(Arquillian.class)

public class HelloWorldTest {

@ArquillianResource

@DockerUrl(containerName = "helloworld", exposedPort = 8080)

RequestSpecBuilder requestSpecBuilder;

@Test

public void should_receive_ok_message() {

RestAssured

.given().spec(requestSpecBuilder.build())

.when().get().then()

.assertThat().body("status", equalTo("OK"));

}

}

73

Arquillian Runner

REST-Assured Integration Environment Resolver

Normal REST-Assured Call

src/test/docker/docker-compose.yml

Page 74: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

DEMO

74

Page 75: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe75

Questions

Page 76: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe76

Micro Services architecture

Page 77: Testing Java Microservices Devoxx be 2017

@alexsotob77

Villains Database Application

Consumer V1 Producer V1GET /crimes/Gru

[{ "name": "Moon", "villain": "Gru", "wiki": "/wiki/Moon"}]

GET /villains/Gru

"name": “Gru”,"areaOfInfluence": "World""crimes": [{ "name": "Moon", "wiki": "/wiki/Moon" }]

X

XV1.1

Page 78: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe78

Contract Tests

Page 79: Testing Java Microservices Devoxx be 2017

@alexsotob79

Consumer Side

Stub Server

ConsumerTest

Expectations

GET /crimes/Gru

[{"name":...]}

Sharing

Page 80: Testing Java Microservices Devoxx be 2017

Provider Side

Sharing

Test

Provider

GET /crimes/Gru

[{"name":...]}

Page 81: Testing Java Microservices Devoxx be 2017

@alexsotob81

> Pact FoundationPact specification v3

> Integration with several languagesJVM, Ruby, Python, Go, .Net, Swift, JS

> Pact BrokerSharing contracts, API documentation, Overview of services

> Arquillian AlgeronArquillian ecosystem + Pact, Publishers/Retrievers, JBoss Forge

Page 82: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Consumer Side@RunWith(Arquillian.class)

public class CrimesConsumerContractTest {

@StubServer

URL pactServer;

@Pact(provider = "crimes", consumer = "villains")

public RequestResponsePact returnListOfCrimes(PactDslWithProvider builder) {

return builder

.uponReceiving("Gru villain to get all Crimes")

.path("/crimes/Gru").method("GET").willRespondWith()

.status(200).body(RESPONSE)

.toPact();

}

@Test

@PactVerification(“crimes”)

public void should_get_list_of_crimes_by_villain() {}

82

Arquillian Runner

Location of Stub Server

Record expectations between C/P

Test execution and contract creation

Page 83: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Provider Side

@RunWith(Arquillian.class)

@Provider("crimes")

@ContractsFolder("~/crimescontract")

public class CrimesContractTest {

@ArquillianResource

Target target;

@Test

public void should_validate_contract() {

assertThat(target).withUrl(getCrimesServer()).satisfiesContract();

}

}

83

Arquillian Runner

Location of Contract

Http client player

Verification of real responses against contract

Page 84: Testing Java Microservices Devoxx be 2017

@alexsotob84

DEMO

Page 85: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe85

Questions

Page 86: Testing Java Microservices Devoxx be 2017

@alexsotob86

Deployment Tests

Page 87: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe87

Page 88: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Deployment Test@RunWith(ArquillianConditionalRunner.class)

@RequiresKubernetes

public class HelloWorldIT {

@ArquillianResource

@RouteURL("kubernetes-hello-world")

URL url;

@Test

public void service_should_be_accessible() throws IOException {

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder().get().url(url).build();

Response response = client.newCall(request).execute();

assertThat(response.isSuccessful()).isTrue();

}

}

88

Arquillian Runner

Precondition in test

URL for access to service

Verifies connection is possible

Page 89: Testing Java Microservices Devoxx be 2017

@alexsotob89

DEMO

Page 90: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe90

Questions

Page 91: Testing Java Microservices Devoxx be 2017

@alexsotob91

Continuous Delivery

Page 92: Testing Java Microservices Devoxx be 2017

@alexsotob92

Smart Testing

Page 93: Testing Java Microservices Devoxx be 2017

@alexsotob93

Production Sources Tests

https://martinfowler.com/articles/rise-test-impact-analysis.html

Page 94: Testing Java Microservices Devoxx be 2017

@alexsotob

Smart Testing Maven Extension

curl -sSL https://git.io/v5jy6 | bash

94

Installs extension

mvn clean test -Dsmart.testing="new, changed, affected"

Runs only new, changed and prod related tests

mvn clean test -Dsmart.testing.mode=ordering -Dsmart.testing="new, changed, affected”

Prioritize new, changed and prod related tests

Page 95: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe95

We are on Production

Page 96: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe96

Shit! We break Production Environment

Page 97: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe97

Blue-Green Deployments

Page 98: Testing Java Microservices Devoxx be 2017

Starts with a “git commit and git push”

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

BUILDSCM

CLUSTER

Page 99: Testing Java Microservices Devoxx be 2017

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

BUILDSCM

CLUSTER

Page 100: Testing Java Microservices Devoxx be 2017

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

BUILDSCM

CLUSTER

Page 101: Testing Java Microservices Devoxx be 2017

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

BUILDSCM

CLUSTER

Page 102: Testing Java Microservices Devoxx be 2017

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

BUILDSCM

CLUSTER

Page 103: Testing Java Microservices Devoxx be 2017

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

CLUSTER

Page 104: Testing Java Microservices Devoxx be 2017

Blue/Green Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

CLUSTER

Page 105: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe105

Questions

Page 106: Testing Java Microservices Devoxx be 2017

@alexsotob106

Canary Release

Page 107: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 108: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 109: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 110: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 111: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 112: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 113: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 114: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 115: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 116: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 117: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe117

Questions

Page 118: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe118

Dark Launches

Page 119: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

INTERNAL USERSSERVICE

Page 120: Testing Java Microservices Devoxx be 2017

Canary Deployment

DEVELOPMENT QA STAGING PRODUCTION ROUTER USERS

SCM

SERVICE

Page 121: Testing Java Microservices Devoxx be 2017

@alexsotob121

DEMO

Page 122: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe122

Lessons Learnt

Page 123: Testing Java Microservices Devoxx be 2017

@alexsotob

Unit

Component

DeploymentIntegration

Contract

What does it means in terms of Tests?Testing Strategies

123

Production

Page 124: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe124

Tests are a Team

Page 125: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe125

Secure Your Steps

Page 126: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe126

Automate Everything

Page 127: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe127

“Change is the essential process of all of existence.”

—Spock

Page 128: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe128

Questions

Page 129: Testing Java Microservices Devoxx be 2017

@alexsotob @AndyGeeDe

Useful Linkshttps://github.com/lordofthejars/composers-unicorn

https://github.com/lordofthejars/musicboxhttps://github.com/arquillian-testing-microservices/villains-service/tree/contract_testinghttps://github.com/arquillian-testing-microservices/crimes-service/tree/contract_testinghttps://github.com/arquillian/arquillian-extension-persistence/tree/2.0.0/arquillian-ape-nosqlhttps://github.com/lordofthejars/rest-springboot-openshift