SlideShare a Scribd company logo
1 of 217
Download to read offline
Tools, techniques and reflections
BDD-Driven Microservices
in Java
John
Ferguson
Smart
Introductions
“I help teams of smart people 

learn to work together more efficiently, 

to deliver better software faster”
Independently
Deployable
Bounded ContextsLoosely CoupledSingle
Responsibility
Microservices 101
Independently
Deployable
Bounded ContextsLoosely CoupledSingle
Responsibility
Microservices 101
Independently
Deployable
Bounded ContextsLoosely CoupledSingle
Responsibility
Microservices 101
Independently
Deployable
Bounded ContextsLoosely CoupledSingle
Responsibility
Microservices 101
Independently
Deployable
Bounded ContextsLoosely CoupledSingle
Responsibility
Microservices 101
Independently
Deployable
Bounded ContextsLoosely CoupledSingle
Responsibility
Microservices 101
Microservices 101
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
REST/HTTP
Microservices 101
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
Microservices 101
Movie Catalog Service
Microservices 101
Movie Catalog Service
Resource
Microservices 101
Movie Catalog Service
Resource
Service Layer
Domain model
Repositories
Microservices 101
Movie Catalog Service
Resource
Persistance Layer
Service Layer
Domain model
Repositories
Microservices 101
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
The testing pyramid
The testing pyramid
Unit Tests
The testing pyramid
Unit Tests
Integration Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Unit Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Integration
Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Integration
Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Integration
Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Integration
Tests
The testing pyramid
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Integration
Tests
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid End-to-End
Tests
Movie Catalog
Service
Authentication
Service
Shopping Cart
Service
Delivery
Service
Payment
Service
Event Bus
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
To document how
to interact with the
microservice
To document what
the microservice
does
To ensure the
service work
correctly
To ensure we
are delivering
valuable
functionality
Why test our micro-services?
“We test our micro-services so we can deploy new
features quickly and with confidence”
And with
aggressive
production
monitoring
Writing executable
specifications and
living
documentation
To a sufficient level
of confidence
Outside-in
testing
Pragmatic web service testing
And with
aggressive
production
monitoring
Writing executable
specifications and
living
documentation
To a sufficient level
of confidence
Outside-in
testing
Pragmatic web service testing
And with
aggressive
production
monitoring
Writing executable
specifications and
living
documentation
To a sufficient level
of confidence
Outside-in
testing
Pragmatic web service testing
And with
aggressive
production
monitoring
Writing executable
specifications and
living
documentation
To a sufficient level
of confidence
Outside-in
testing
Pragmatic web service testing
And with
aggressive
production
monitoring
Writing executable
specifications and
living
documentation
To a sufficient level
of confidence
Outside-in
testing
Pragmatic web service testing
And with
aggressive
production
monitoring
Writing executable
specifications and
living
documentation
To a sufficient level
of confidence
Outside-in
testing
Pragmatic web service testing
Outside-in development
To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
To deliver
software that
matters
And a common
language to build
a shared
understanding
Using examples at
multiple levels
Collaborate to
discover
requirements and
identify uncertainty
The essence of BDD
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
The business owner
tells the business
analyst what he wants
1
2
The business
analyst writes a
requirements
document
3
The developer
translates the
requirements
into software
4 The tester
translates the
requirements
into test cases 5 The technical
writer translates
the software
into functional
and technical
documentation
A traditional development process
How does it work?
How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
How does it work?
The business owner
and the business
analyst have a
conversation about
what he needs.
1
2
3
4 The tester uses
these scenarios
as the basis for
her tests
5
The automated tests provide
feedback on progress and help
document the application
The business analyst,
the developer and the
tester elaborate the
requirements together.
The scenarios guide the
developer and act as
automated tests
They define
requirements as
structured, English-
language format
"scenarios"
A BDD development process
But what about micro-services?
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
The testing pyramid
Unit Tests
Integration Tests
End-to-end Tests
A different testing pyramid
A different testing pyramid
Executable Business
Specifications
A different testing pyramid
Slow-running executable
technical specifications
Executable Business
Specifications
A different testing pyramid
Fast-running executable technical
specifications
Slow-running executable
technical specifications
Executable Business
Specifications
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Executable
Business specs
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Executable
Business specs
Scenario: Search movies by director

Given the catalog has the following movies:

| title | director | actors |

| Gladiator | Ridley Scott | Russel Crowe, Joaquin Phoenix |

| Letters from Iwo Jima | Clint Eastwood | Ken Watanabe |

| Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |

When I search for movies directed by Clint Eastwood

Then I should be presented with the following movies:

| title | director | actors |

| Letters from Iwo Jima | Clint Eastwood | Ken Watanabe |

| Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |

Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Slow-running
technical
specs
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Slow-running
technical
specs
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest("server.port:0")

class WhenFindingMoviesViaTheRestAPI extends Specification {



@Autowired

MovieRepository movieRepository;



@Value('${local.server.port}')

int port;



def "should list movies by director"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])

when:

List<Movie> movies = when().get("/movies/findByDirector/Clint Eastwood").as(List)

then:

movies.collect {movie -> movie.title} == ["Letters from Iwo Jima", "Gran Torino"]

}
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
def setup() {

repository = Mock(MovieRepository)

artistService = new ArtistService(movieRepository: repository)

}



def "should build actor details from films the artist has acted in and has directed"() {

given: "Clint Eastwood has directed some films"

repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

and: "Clint Eastwood has starred in some films"

repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]

when:

def artistDetails = artistService.findArtistByName("Clint Eastwood")

then:

artistDetails.isPresent()

and:

artistDetails.get().name == "Clint Eastwood" &&

artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&

artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

}
Spock
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
Outside-in development
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Fast-
running
technical
specs
class MovieControllerSpecs extends Specification {



MovieRepository movieRepository = Mock()



def "should find by director regardless of case (#director -> #filteredDirector)"() {

given:

def controller = new MovieController(repository: movieRepository)

when:

controller.findByDirector(director)

then:

1*movieRepository.findByDirector(filteredDirector)

where:

director | filteredDirector

"Clint Eastwood" | "Clint Eastwood"

"Clint eastwood" | "Clint Eastwood"
Spock
Micro-service Contracts
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping Cart
Service
Delivery Service
REST/HTTP
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Delivery
Service
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Consumer
Delivery
Service
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Consumer
Producer
Delivery
Service
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Consumer
Producer
Contract
Delivery
Service
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
REST/HTTP
Contract
Delivery
Service
Micro-service Contracts
Movie Catalog Service
Resource
Persistance Layer Gateway
Service Layer
Domain model
Repositories
Shopping
Cart Service
Delivery
Service
REST/HTTP
Contract
Mock
Shopping
Cart
Service
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Producer
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Consumer
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Consumer Consumer
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Consumer Consumer
Contract
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Consumer Consumer
Contract
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Consumer Consumer
Contract
Micro-service Contracts
REST/HTTP
Movie Catalog
Service
Web app iPhone app Android app
Consumer
Producer
Consumer Consumer
Contract
The Producer API is the sum
of the Consumer Contrats
Specialised ToolsPublished specificationsAutomated Acceptance
Criteria
Verifying the contracts
Specialised ToolsPublished specificationsAutomated Acceptance
Criteria
Verifying the contracts
Specialised ToolsPublished specificationsAutomated Acceptance
Criteria
Verifying the contracts
Specialised ToolsPublished specificationsAutomated Acceptance
Criteria
Verifying the contracts
Specialised ToolsPublished specificationsAutomated Acceptance
Criteria
Verifying the contracts
PactPactoMountebank
More specialised tools
PactPactoMountebank
More specialised tools
PactPactoMountebank
More specialised tools
PactPactoMountebank
More specialised tools
PactPactoMountebank
More specialised tools
PactPactoMountebank
More specialised tools
PactPactoMountebank
More specialised tools
Pact and Pacto

Consumer Driven Contract Testing
42
Consumer Movie Catalog
Service
Pact and Pacto

Consumer Driven Contract Testing
42
Consumer Movie Catalog
Service
Mock
Service
Pact help us create and
configure a mock service
Pact and Pacto

Consumer Driven Contract Testing
43
Consumer Movie Catalog
Service
Mock
Service
Pact and Pacto

Consumer Driven Contract Testing
43
Consumer Movie Catalog
Service
Mock
Service
We write specifications to
describe the expected
behaviour of the service
Pact and Pacto

Consumer Driven Contract Testing
44
Consumer Movie Catalog
Service
Mock
Service
Pact and Pacto

Consumer Driven Contract Testing
44
Consumer Movie Catalog
Service
Mock
Service
When we run these
specifications, the expected
behaviour is recorded in a
‘pact’ file
asdasdasda
asdasdasdas
asdasdasd
asdasdasda
asdasdasdasd
asdasdasdasd
asdasdasdas
Pact and Pacto

Consumer Driven Contract Testing
45
Consumer Movie Catalog
Service
Mock
Service
asdasdasda
asdasdasdas
asdasdasd
asdasdasda
asdasdasdasd
asdasdasdasd
asdasdasdas
Pact and Pacto

Consumer Driven Contract Testing
45
Consumer Movie Catalog
Service
Mock
Service
We can now use this ‘pact’ to
test(drive) the service
implementation
asdasdasda
asdasdasdas
asdasdasd
asdasdasda
asdasdasdasd
asdasdasdasd
asdasdasdas
Levels of confidence
From BDD to TDD
“How much automated testing?

As much as you need, but no more.”
Acceptance testing
Acceptance testing
Acceptance testing
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
@When("I add this movie to the catalog")

public void addMovieToCatalog() {

movieId = rest().given().contentType("application/json")

.content(newMovie)

.post("/movies")

.then().statusCode(200)

.and().extract().jsonPath().getString("id");

}
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
@Then("I should be able to find it in the catalog")

public void shouldBeAbleToFindMovieInCatalog() {

rest().given().contentType("application/json")

.get("/movies/{movieId}", movieId)

.then().statusCode(200)

.and().body("title", equalTo(newMovie.getTitle()))

.and().body("director", equalTo(newMovie.getDirector()));

}
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
@Then("I should be able to find it in the catalog")

public void shouldBeAbleToFindMovieInCatalog() {

rest().given().contentType("application/json")

.get("/movies/{movieId}", movieId)

.then().statusCode(200)

.and().body("title", equalTo(newMovie.getTitle()))

.and().body("director", equalTo(newMovie.getDirector()));

}
Rest Assured + Serenity
Feature: Adding new movies

In order to sell more movies

As an online movie seller

I want to be able to add movies to the catalog



Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
@Then("I should be able to find it in the catalog")

public void shouldBeAbleToFindMovieInCatalog() {

rest().given().contentType("application/json")

.get("/movies/{movieId}", movieId)

.then().statusCode(200)

.and().body("title", equalTo(newMovie.getTitle()))

.and().body("director", equalTo(newMovie.getDirector()));

}
Testing REST services with Rest-Assured
Testing REST services with Rest-Assured
get(“/movies/findByTitle/Gladiator")
.then().body("title", equalTo("Gladiator"));
Testing REST services with Rest-Assured
get(“/movies/findByTitle/Gladiator")
.then().body("title", equalTo("Gladiator"));
Testing REST services with Rest-Assured
when().get(“/movies/findByTitle/Gladiator”)
.then().body("nominations.category",
hasItems("Best Actor", "Special Effects"));
Testing REST services with Rest-Assured
when().get(“/movies/findByTitle/Gladiator”)
.then().body("nominations.category",
hasItems("Best Actor", "Special Effects"));
Testing REST services with Rest-Assured
given().contentType("application/json")

.content(newMovie)

.post("/movies")

.then().statusCode(200)

.and().extract().jsonPath().getString("id");
Testing REST services with Rest-Assured
given().contentType("application/json")

.content(newMovie)

.post("/movies")

.then().statusCode(200)

.and().extract().jsonPath().getString("id");
Posting data
Testing REST services with Rest-Assured
Movie matchingMovie
= get("/movies/findByTitle/Gladiator").as(Movie.class);
Testing REST services with Rest-Assured
Movie matchingMovie
= get("/movies/findByTitle/Gladiator").as(Movie.class);
Convert responses to Java objects
Testing REST services with Rest-Assured
given().param("title","Unknown").

when().get("/movies/search").

then().statusCode(404);
Testing REST services with Rest-Assured
given().param("title","Unknown").

when().get("/movies/search").

then().statusCode(404);
Check for errors
Resource-level testing
Resource-level testing
Spock
Resource-level testing
Spock
Resource-level testing
Spock
57
@ContextConfiguration(loader = SpringApplicationContextLoader.class,
classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest("server.port:0")

class WhenFindingMovies extends Specification {



@Autowired

MovieRepository movieRepository;



@Value('${local.server.port}')

int port;



def setup() {

movieRepository.deleteAll();

RestAssured.port = port;

}



def "should list all movies"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])

when:

def movies = when().get("/movies").as(List)

then:

movies.collect {movie -> movie.title} == ["Gladiator", 

"Letters from Iwo Jima", 

"Gran Torino"]

}
57
@ContextConfiguration(loader = SpringApplicationContextLoader.class,
classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest("server.port:0")

class WhenFindingMovies extends Specification {



@Autowired

MovieRepository movieRepository;



@Value('${local.server.port}')

int port;



def setup() {

movieRepository.deleteAll();

RestAssured.port = port;

}



def "should list all movies"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])

when:

def movies = when().get("/movies").as(List)

then:

movies.collect {movie -> movie.title} == ["Gladiator", 

"Letters from Iwo Jima", 

"Gran Torino"]

}
Spring Context
57
@ContextConfiguration(loader = SpringApplicationContextLoader.class,
classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest("server.port:0")

class WhenFindingMovies extends Specification {



@Autowired

MovieRepository movieRepository;



@Value('${local.server.port}')

int port;



def setup() {

movieRepository.deleteAll();

RestAssured.port = port;

}



def "should list all movies"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])

when:

def movies = when().get("/movies").as(List)

then:

movies.collect {movie -> movie.title} == ["Gladiator", 

"Letters from Iwo Jima", 

"Gran Torino"]

}
Spring Integration Tests
57
@ContextConfiguration(loader = SpringApplicationContextLoader.class,
classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest("server.port:0")

class WhenFindingMovies extends Specification {



@Autowired

MovieRepository movieRepository;



@Value('${local.server.port}')

int port;



def setup() {

movieRepository.deleteAll();

RestAssured.port = port;

}



def "should list all movies"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])

when:

def movies = when().get("/movies").as(List)

then:

movies.collect {movie -> movie.title} == ["Gladiator", 

"Letters from Iwo Jima", 

"Gran Torino"]

}
Rest Assured
57
@ContextConfiguration(loader = SpringApplicationContextLoader.class,
classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest("server.port:0")

class WhenFindingMovies extends Specification {



@Autowired

MovieRepository movieRepository;



@Value('${local.server.port}')

int port;



def setup() {

movieRepository.deleteAll();

RestAssured.port = port;

}



def "should list all movies"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])

when:

def movies = when().get("/movies").as(List)

then:

movies.collect {movie -> movie.title} == ["Gladiator", 

"Letters from Iwo Jima", 

"Gran Torino"]

}
Controller-level testing
Controller-level testing
Spock
Controller-level testing
Spock
@ContextConfiguration(loader = SpringApplicationContextLoader.class,

classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest

class WhenViewingActorDetailsViaTheController extends Specification {



@Autowired

ArtistController artistController;



def "should retrieve actor details for an artist"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,

THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])

when:

Artist artist = artistController.findArtistDetails("Clint Eastwood")

then:

artist.name == "Clint Eastwood"

and:

artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY,
GRAN_TORINO)

and:

artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)

}
@ContextConfiguration(loader = SpringApplicationContextLoader.class,

classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest

class WhenViewingActorDetailsViaTheController extends Specification {



@Autowired

ArtistController artistController;



def "should retrieve actor details for an artist"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,

THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])

when:

Artist artist = artistController.findArtistDetails("Clint Eastwood")

then:

artist.name == "Clint Eastwood"

and:

artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY,
GRAN_TORINO)

and:

artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)

}
Use a fully wired controller
@ContextConfiguration(loader = SpringApplicationContextLoader.class,

classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest

class WhenViewingActorDetailsViaTheController extends Specification {



@Autowired

ArtistController artistController;



def "should retrieve actor details for an artist"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,

THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])

when:

Artist artist = artistController.findArtistDetails("Clint Eastwood")

then:

artist.name == "Clint Eastwood"

and:

artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY,
GRAN_TORINO)

and:

artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)

}
Use domain objects rather than REST calls
@ContextConfiguration(loader = SpringApplicationContextLoader.class,

classes = MovieServiceApplication.class)

@WebAppConfiguration

@IntegrationTest

class WhenViewingActorDetailsViaTheController extends Specification {



@Autowired

ArtistController artistController;



def "should retrieve actor details for an artist"() {

given:

movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,

THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])

when:

Artist artist = artistController.findArtistDetails("Clint Eastwood")

then:

artist.name == "Clint Eastwood"

and:

artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY,
GRAN_TORINO)

and:

artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)

}
Service or domain-level testing
Service or domain-level testing
Spock
MovieRepository repository

def artistService



def setup() {

repository = Mock(MovieRepository)

artistService = new ArtistService(movieRepository: repository)

}



def "should build actor details from films the artist has acted in and has directed"() {

given: "Clint Eastwood has directed some films"

repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

and: "Clint Eastwood has starred in some films"

repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]

when:

def artistDetails = artistService.findArtistByName("Clint Eastwood")

then:

artistDetails.isPresent()

and:

artistDetails.get().name == "Clint Eastwood" &&

artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&

artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

}
MovieRepository repository

def artistService



def setup() {

repository = Mock(MovieRepository)

artistService = new ArtistService(movieRepository: repository)

}



def "should build actor details from films the artist has acted in and has directed"() {

given: "Clint Eastwood has directed some films"

repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

and: "Clint Eastwood has starred in some films"

repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]

when:

def artistDetails = artistService.findArtistByName("Clint Eastwood")

then:

artistDetails.isPresent()

and:

artistDetails.get().name == "Clint Eastwood" &&

artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&

artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

}
Mocked repositories
MovieRepository repository

def artistService



def setup() {

repository = Mock(MovieRepository)

artistService = new ArtistService(movieRepository: repository)

}



def "should build actor details from films the artist has acted in and has directed"() {

given: "Clint Eastwood has directed some films"

repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

and: "Clint Eastwood has starred in some films"

repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]

when:

def artistDetails = artistService.findArtistByName("Clint Eastwood")

then:

artistDetails.isPresent()

and:

artistDetails.get().name == "Clint Eastwood" &&

artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&

artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

}
Call the service
MovieRepository repository

def artistService



def setup() {

repository = Mock(MovieRepository)

artistService = new ArtistService(movieRepository: repository)

}



def "should build actor details from films the artist has acted in and has directed"() {

given: "Clint Eastwood has directed some films"

repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

and: "Clint Eastwood has starred in some films"

repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]

when:

def artistDetails = artistService.findArtistByName("Clint Eastwood")

then:

artistDetails.isPresent()

and:

artistDetails.get().name == "Clint Eastwood" &&

artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&

artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

}
Check the outcomes
MovieRepository repository

def artistService



def setup() {

repository = Mock(MovieRepository)

artistService = new ArtistService(movieRepository: repository)

}



def "should build actor details from films the artist has acted in and has directed"() {

given: "Clint Eastwood has directed some films"

repository.findByDirector("Clint Eastwood") >>
[LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

and: "Clint Eastwood has starred in some films"

repository.findByActors("Clint Eastwood") >>
[THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]

when:

def artistDetails = artistService.findArtistByName("Clint Eastwood")

then:

artistDetails.isPresent()

and:

artistDetails.get().name == "Clint Eastwood" &&

artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&

artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]

}
Living Documentation
Living Documentation
Living Functional Documentation
with Serenity and Cucumber
65
Scenario: Adding movies

Given the following movie has just come out

| title | director | actors |

| Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |

When I add this movie to the catalog

Then I should be able to find it in the catalog
Executable Specifications
Automated tests Living documentation
66
66
Context
66
Context
Narrative
67
67
Technical details
Living API Documentation 

with Swagger
Springfox
69
YAML Specifications
Documentation
website
Client libraries Test stubs
70
@RequestMapping(method = GET)

@ApiOperation("List all the movies in the catalog")

public List<Movie> findAll() {

return repository.findAll();

}



@RequestMapping(method = POST)

@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")

public Movie add(@RequestBody Movie newMovie) {

return repository.save(newMovie);

}



@RequestMapping(value = "/{id}", method = DELETE)

@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")

public void delete(@PathVariable String id) {

repository.delete(id);

}

Springfox
Some annotations…
Swagger and Spring Boot
70
@RequestMapping(method = GET)

@ApiOperation("List all the movies in the catalog")

public List<Movie> findAll() {

return repository.findAll();

}



@RequestMapping(method = POST)

@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")

public Movie add(@RequestBody Movie newMovie) {

return repository.save(newMovie);

}



@RequestMapping(value = "/{id}", method = DELETE)

@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")

public void delete(@PathVariable String id) {

repository.delete(id);

}

Springfox
Some annotations…
Swagger and Spring Boot
70
@RequestMapping(method = GET)

@ApiOperation("List all the movies in the catalog")

public List<Movie> findAll() {

return repository.findAll();

}



@RequestMapping(method = POST)

@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")

public Movie add(@RequestBody Movie newMovie) {

return repository.save(newMovie);

}



@RequestMapping(value = "/{id}", method = DELETE)

@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")

public void delete(@PathVariable String id) {

repository.delete(id);

}

Springfox
Some annotations…
Swagger and Spring Boot
70
@RequestMapping(method = GET)

@ApiOperation("List all the movies in the catalog")

public List<Movie> findAll() {

return repository.findAll();

}



@RequestMapping(method = POST)

@ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")

public Movie add(@RequestBody Movie newMovie) {

return repository.save(newMovie);

}



@RequestMapping(value = "/{id}", method = DELETE)

@ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")

public void delete(@PathVariable String id) {

repository.delete(id);

}

Springfox
Some annotations…
Swagger and Spring Boot
71
Springfox
@EnableAutoConfiguration

@EnableSwagger2

public class MovieServiceApplication {



public static void main(String[] args) {

SpringApplication.run(MovieServiceApplication.class, args);

}



@Bean

public Docket moviesApi() {

return new Docket(DocumentationType.SWAGGER_2)

.select()

.apis(RequestHandlerSelectors.any())

.paths(PathSelectors.any())

.build()

.pathMapping("/")

.directModelSubstitute(LocalDate.class, String.class)

.genericModelSubstitutes(ResponseEntity.class);

}

} Some configuration…
Swagger and Spring Boot
72
Springfox
Documentation

bundled with your
web services
Swagger and Spring Boot
Production monitoring
Automated MonitoringFast provisioningA fast deployment pipeline
So you want to micro-service?
Automated health checksReal operationsSmoke tests in production
Simple checks may not be enough
An example with Spring Actuator
@Component

public class CatalogHealth implements HealthIndicator {



@Autowired

MovieRepository movieRepository;



@Override

public Health health() {

return (isCatalogStocked()) ? 

Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() 

: Health.down().build();

}



private boolean isCatalogStocked() {

return (movieRepository.count() > 0);

}

}
An example with Spring Actuator
@Component

public class CatalogHealth implements HealthIndicator {



@Autowired

MovieRepository movieRepository;



@Override

public Health health() {

return (isCatalogStocked()) ? 

Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() 

: Health.down().build();

}



private boolean isCatalogStocked() {

return (movieRepository.count() > 0);

}

}
A Spring Actuator Health Check
An example with Spring Actuator
@Component

public class CatalogHealth implements HealthIndicator {



@Autowired

MovieRepository movieRepository;



@Override

public Health health() {

return (isCatalogStocked()) ? 

Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() 

: Health.down().build();

}



private boolean isCatalogStocked() {

return (movieRepository.count() > 0);

}

}
A Spring Actuator Health Check
Custom logic to decide if the app is working
An example with Spring Actuator
@Component

public class MovieTransactionHealth implements HealthIndicator {



@Autowired

MovieController movieController;



@Override

public Health health() {

return Health.status(transactionStatus()).build();

}



private Status transactionStatus() {

try {

Movie movie = new Movie("TEST title", "TEST description", "TEST director",
ImmutableList.of("TEST actor"));

Movie reloadedMovie = movieController.add(movie);

movieController.delete(reloadedMovie.getId());

return Status.UP;

} catch (Throwable e) {

return new Status("DOWN", e.toString());

}

}

}
An example with Spring Actuator
@Component

public class MovieTransactionHealth implements HealthIndicator {



@Autowired

MovieController movieController;



@Override

public Health health() {

return Health.status(transactionStatus()).build();

}



private Status transactionStatus() {

try {

Movie movie = new Movie("TEST title", "TEST description", "TEST director",
ImmutableList.of("TEST actor"));

Movie reloadedMovie = movieController.add(movie);

movieController.delete(reloadedMovie.getId());

return Status.UP;

} catch (Throwable e) {

return new Status("DOWN", e.toString());

}

}

}
More complex custom logic
An example with Spring Actuator
@Component

public class MovieTransactionHealth implements HealthIndicator {



@Autowired

MovieController movieController;



@Override

public Health health() {

return Health.status(transactionStatus()).build();

}



private Status transactionStatus() {…}

}
@Component

public class CatalogHealth implements HealthIndicator {



@Autowired

MovieRepository movieRepository;



@Override

public Health health() {

return (isCatalogStocked()) ? 

Health.status(new Status("UP", "Movie count: " + 

movieRepository.count())).build() 

: Health.down().build();

}



private boolean isCatalogStocked() {…}

}
Try all this out at home!
Install Gradle
Install MongoDB
Clone the repowakaleo/movie-service
Questions?
John Ferguson Smart
john.smart@wakaleo.com
wakaleo
http://www.wakaleo.com

More Related Content

What's hot

API Test Automation Using Karate (Anil Kumar Moka)
API Test Automation Using Karate (Anil Kumar Moka)API Test Automation Using Karate (Anil Kumar Moka)
API Test Automation Using Karate (Anil Kumar Moka)Peter Thomas
 
CI and CD with Jenkins
CI and CD with JenkinsCI and CD with Jenkins
CI and CD with JenkinsMartin Málek
 
Transforming Organizations with CI/CD
Transforming Organizations with CI/CDTransforming Organizations with CI/CD
Transforming Organizations with CI/CDCprime
 
Introduction to CICD
Introduction to CICDIntroduction to CICD
Introduction to CICDKnoldus Inc.
 
Modern CI/CD Pipeline Using Azure DevOps
Modern CI/CD Pipeline Using Azure DevOpsModern CI/CD Pipeline Using Azure DevOps
Modern CI/CD Pipeline Using Azure DevOpsGlobalLogic Ukraine
 
(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS
(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS
(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWSAmazon Web Services
 
What is Jenkins | Jenkins Tutorial for Beginners | Edureka
What is Jenkins | Jenkins Tutorial for Beginners | EdurekaWhat is Jenkins | Jenkins Tutorial for Beginners | Edureka
What is Jenkins | Jenkins Tutorial for Beginners | EdurekaEdureka!
 
CI-CD Jenkins, GitHub Actions, Tekton
CI-CD Jenkins, GitHub Actions, Tekton CI-CD Jenkins, GitHub Actions, Tekton
CI-CD Jenkins, GitHub Actions, Tekton Araf Karsh Hamid
 
Performance Engineering Masterclass: Efficient Automation with the Help of SR...
Performance Engineering Masterclass: Efficient Automation with the Help of SR...Performance Engineering Masterclass: Efficient Automation with the Help of SR...
Performance Engineering Masterclass: Efficient Automation with the Help of SR...ScyllaDB
 
The Quality Assurance Checklist for Progressive Testing
The Quality Assurance Checklist for Progressive TestingThe Quality Assurance Checklist for Progressive Testing
The Quality Assurance Checklist for Progressive TestingCygnet Infotech
 
Behavior Driven Development (BDD)
Behavior Driven Development (BDD)Behavior Driven Development (BDD)
Behavior Driven Development (BDD)Ajay Danait
 
Monitoring at the Speed of DevOps
Monitoring at the Speed of DevOpsMonitoring at the Speed of DevOps
Monitoring at the Speed of DevOpsDevOps.com
 
Consumer-Driven Contract Testing With Postman
Consumer-Driven Contract Testing With PostmanConsumer-Driven Contract Testing With Postman
Consumer-Driven Contract Testing With PostmanPostman
 
Test Data Management a Managed Service for Software Quality Assurance
Test Data Management a Managed Service for Software Quality AssuranceTest Data Management a Managed Service for Software Quality Assurance
Test Data Management a Managed Service for Software Quality AssuranceSoftware Testing Solution
 

What's hot (20)

API Test Automation Using Karate (Anil Kumar Moka)
API Test Automation Using Karate (Anil Kumar Moka)API Test Automation Using Karate (Anil Kumar Moka)
API Test Automation Using Karate (Anil Kumar Moka)
 
CI and CD with Jenkins
CI and CD with JenkinsCI and CD with Jenkins
CI and CD with Jenkins
 
Jenkins presentation
Jenkins presentationJenkins presentation
Jenkins presentation
 
Transforming Organizations with CI/CD
Transforming Organizations with CI/CDTransforming Organizations with CI/CD
Transforming Organizations with CI/CD
 
Introduction to CICD
Introduction to CICDIntroduction to CICD
Introduction to CICD
 
Modern CI/CD Pipeline Using Azure DevOps
Modern CI/CD Pipeline Using Azure DevOpsModern CI/CD Pipeline Using Azure DevOps
Modern CI/CD Pipeline Using Azure DevOps
 
(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS
(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS
(DEV310) CI/CD of Services with Mocking & Resiliency Testing Using AWS
 
What is Jenkins | Jenkins Tutorial for Beginners | Edureka
What is Jenkins | Jenkins Tutorial for Beginners | EdurekaWhat is Jenkins | Jenkins Tutorial for Beginners | Edureka
What is Jenkins | Jenkins Tutorial for Beginners | Edureka
 
CI-CD Jenkins, GitHub Actions, Tekton
CI-CD Jenkins, GitHub Actions, Tekton CI-CD Jenkins, GitHub Actions, Tekton
CI-CD Jenkins, GitHub Actions, Tekton
 
Track code quality with SonarQube
Track code quality with SonarQubeTrack code quality with SonarQube
Track code quality with SonarQube
 
Performance Engineering Masterclass: Efficient Automation with the Help of SR...
Performance Engineering Masterclass: Efficient Automation with the Help of SR...Performance Engineering Masterclass: Efficient Automation with the Help of SR...
Performance Engineering Masterclass: Efficient Automation with the Help of SR...
 
The Quality Assurance Checklist for Progressive Testing
The Quality Assurance Checklist for Progressive TestingThe Quality Assurance Checklist for Progressive Testing
The Quality Assurance Checklist for Progressive Testing
 
"DevOps > CI+CD "
"DevOps > CI+CD ""DevOps > CI+CD "
"DevOps > CI+CD "
 
Behavior Driven Development (BDD)
Behavior Driven Development (BDD)Behavior Driven Development (BDD)
Behavior Driven Development (BDD)
 
Monitoring at the Speed of DevOps
Monitoring at the Speed of DevOpsMonitoring at the Speed of DevOps
Monitoring at the Speed of DevOps
 
Consumer-Driven Contract Testing With Postman
Consumer-Driven Contract Testing With PostmanConsumer-Driven Contract Testing With Postman
Consumer-Driven Contract Testing With Postman
 
Test Data Management a Managed Service for Software Quality Assurance
Test Data Management a Managed Service for Software Quality AssuranceTest Data Management a Managed Service for Software Quality Assurance
Test Data Management a Managed Service for Software Quality Assurance
 
Postman
PostmanPostman
Postman
 
Karate DSL
Karate DSLKarate DSL
Karate DSL
 
Docker Kubernetes Istio
Docker Kubernetes IstioDocker Kubernetes Istio
Docker Kubernetes Istio
 

Viewers also liked

All the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesAll the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesJohn Ferguson Smart Limited
 
BDD in Action - Automated Web Testing with WebDriver and Serenity
BDD in Action - Automated Web Testing with WebDriver and SerenityBDD in Action - Automated Web Testing with WebDriver and Serenity
BDD in Action - Automated Web Testing with WebDriver and SerenityJohn Ferguson Smart Limited
 
Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Lars Thorup
 
Implementing Testing for Behavior-Driven Development Using Cucumber
Implementing Testing for Behavior-Driven Development Using CucumberImplementing Testing for Behavior-Driven Development Using Cucumber
Implementing Testing for Behavior-Driven Development Using CucumberTechWell
 
Microservices - Peixe Urbano Tech Talks
Microservices - Peixe Urbano Tech TalksMicroservices - Peixe Urbano Tech Talks
Microservices - Peixe Urbano Tech TalksPedro Mendes
 
Spring 4.0 - Evolution or Revolution
Spring 4.0 - Evolution or RevolutionSpring 4.0 - Evolution or Revolution
Spring 4.0 - Evolution or RevolutionRaffael Schmid
 
Webinar - What's new in Axon 3
Webinar - What's new in Axon 3 Webinar - What's new in Axon 3
Webinar - What's new in Axon 3 Allard Buijze
 
An introduction to Behavior-Driven Development (BDD)
An introduction to Behavior-Driven Development (BDD)An introduction to Behavior-Driven Development (BDD)
An introduction to Behavior-Driven Development (BDD)Suman Guha
 
Microservices architecture
Microservices architectureMicroservices architecture
Microservices architectureFaren faren
 
It's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersIt's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersJohn Ferguson Smart Limited
 
Bitácora Maestro Fabián Guerrero Obando
Bitácora Maestro Fabián Guerrero ObandoBitácora Maestro Fabián Guerrero Obando
Bitácora Maestro Fabián Guerrero ObandoCindy Altamirano
 

Viewers also liked (20)

BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
All the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesAll the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practices
 
BDD in Action - Automated Web Testing with WebDriver and Serenity
BDD in Action - Automated Web Testing with WebDriver and SerenityBDD in Action - Automated Web Testing with WebDriver and Serenity
BDD in Action - Automated Web Testing with WebDriver and Serenity
 
CukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning WorkshopCukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning Workshop
 
Serenity and the Journey Pattern
Serenity and the Journey PatternSerenity and the Journey Pattern
Serenity and the Journey Pattern
 
BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!
 
Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)Test and Behaviour Driven Development (TDD/BDD)
Test and Behaviour Driven Development (TDD/BDD)
 
Implementing Testing for Behavior-Driven Development Using Cucumber
Implementing Testing for Behavior-Driven Development Using CucumberImplementing Testing for Behavior-Driven Development Using Cucumber
Implementing Testing for Behavior-Driven Development Using Cucumber
 
Microservices - Peixe Urbano Tech Talks
Microservices - Peixe Urbano Tech TalksMicroservices - Peixe Urbano Tech Talks
Microservices - Peixe Urbano Tech Talks
 
Spring 4.0 - Evolution or Revolution
Spring 4.0 - Evolution or RevolutionSpring 4.0 - Evolution or Revolution
Spring 4.0 - Evolution or Revolution
 
Webinar - What's new in Axon 3
Webinar - What's new in Axon 3 Webinar - What's new in Axon 3
Webinar - What's new in Axon 3
 
An introduction to Behavior-Driven Development (BDD)
An introduction to Behavior-Driven Development (BDD)An introduction to Behavior-Driven Development (BDD)
An introduction to Behavior-Driven Development (BDD)
 
BDD: The unit test of the product owner
BDD: The unit test of the product ownerBDD: The unit test of the product owner
BDD: The unit test of the product owner
 
Bdd Introduction
Bdd IntroductionBdd Introduction
Bdd Introduction
 
Microservices architecture
Microservices architectureMicroservices architecture
Microservices architecture
 
It's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersIt's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for Testers
 
Bitácora Maestro Fabián Guerrero Obando
Bitácora Maestro Fabián Guerrero ObandoBitácora Maestro Fabián Guerrero Obando
Bitácora Maestro Fabián Guerrero Obando
 
Trinity at a Glance
Trinity at a GlanceTrinity at a Glance
Trinity at a Glance
 
CV of Mr Michael Mwatsika
CV of Mr Michael MwatsikaCV of Mr Michael Mwatsika
CV of Mr Michael Mwatsika
 

Similar to BDD Microservices Java Techniques Reflections

Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...Grid Dynamics
 
Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...Grid Dynamics
 
End-to-End Software testing services at Faststream technologies
End-to-End Software testing services at Faststream technologiesEnd-to-End Software testing services at Faststream technologies
End-to-End Software testing services at Faststream technologiesFaststream Technologies
 
Microservices
MicroservicesMicroservices
MicroservicesSmartBear
 
Continuous integration testing for automation needs and quality of the releases
Continuous integration testing for automation needs and quality of the releasesContinuous integration testing for automation needs and quality of the releases
Continuous integration testing for automation needs and quality of the releasesZado Technologies
 
Monktoberfest Fast Delivery
Monktoberfest Fast DeliveryMonktoberfest Fast Delivery
Monktoberfest Fast DeliveryAdrian Cockcroft
 
Microservices the Good Bad and the Ugly
Microservices the Good Bad and the UglyMicroservices the Good Bad and the Ugly
Microservices the Good Bad and the UglyAdrian Cockcroft
 
The Modern Tech Stack: Microservices - The Dark Side
The Modern Tech Stack: Microservices - The Dark SideThe Modern Tech Stack: Microservices - The Dark Side
The Modern Tech Stack: Microservices - The Dark SideAggregage
 
Uber's new mobile architecture
Uber's new mobile architectureUber's new mobile architecture
Uber's new mobile architectureDhaval Patel
 
Dockercon State of the Art in Microservices
Dockercon State of the Art in MicroservicesDockercon State of the Art in Microservices
Dockercon State of the Art in MicroservicesAdrian Cockcroft
 
Cloud Native Cost Optimization UCC
Cloud Native Cost Optimization UCCCloud Native Cost Optimization UCC
Cloud Native Cost Optimization UCCAdrian Cockcroft
 
Failure is an Option: Scaling Resilient Feature Delivery
Failure is an Option: Scaling Resilient Feature DeliveryFailure is an Option: Scaling Resilient Feature Delivery
Failure is an Option: Scaling Resilient Feature DeliveryOptimizely
 
Cigniti Independent Software Testing Services
Cigniti Independent Software Testing ServicesCigniti Independent Software Testing Services
Cigniti Independent Software Testing ServicesCigniti Technologies Ltd
 
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...Chris Richardson
 
Webinar: Automate Your Environment Provisioning for Mobile App Development
Webinar: Automate Your Environment Provisioning for Mobile App Development Webinar: Automate Your Environment Provisioning for Mobile App Development
Webinar: Automate Your Environment Provisioning for Mobile App Development Skytap Cloud
 
Software Testing Certification
Software Testing CertificationSoftware Testing Certification
Software Testing CertificationVskills
 
Creating Complete Test Environments in the Cloud: Skytap & Parasoft Webinar
Creating Complete Test Environments in the Cloud: Skytap & Parasoft WebinarCreating Complete Test Environments in the Cloud: Skytap & Parasoft Webinar
Creating Complete Test Environments in the Cloud: Skytap & Parasoft WebinarSkytap Cloud
 

Similar to BDD Microservices Java Techniques Reflections (20)

Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...
 
Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...Best practices for enterprise-grade microservices implementations with Google...
Best practices for enterprise-grade microservices implementations with Google...
 
Dragonfly Software Testing
Dragonfly Software TestingDragonfly Software Testing
Dragonfly Software Testing
 
End-to-End Software testing services at Faststream technologies
End-to-End Software testing services at Faststream technologiesEnd-to-End Software testing services at Faststream technologies
End-to-End Software testing services at Faststream technologies
 
Tec314
Tec314Tec314
Tec314
 
Microservices
MicroservicesMicroservices
Microservices
 
Continuous integration testing for automation needs and quality of the releases
Continuous integration testing for automation needs and quality of the releasesContinuous integration testing for automation needs and quality of the releases
Continuous integration testing for automation needs and quality of the releases
 
Monktoberfest Fast Delivery
Monktoberfest Fast DeliveryMonktoberfest Fast Delivery
Monktoberfest Fast Delivery
 
Microservices the Good Bad and the Ugly
Microservices the Good Bad and the UglyMicroservices the Good Bad and the Ugly
Microservices the Good Bad and the Ugly
 
The Modern Tech Stack: Microservices - The Dark Side
The Modern Tech Stack: Microservices - The Dark SideThe Modern Tech Stack: Microservices - The Dark Side
The Modern Tech Stack: Microservices - The Dark Side
 
Uber's new mobile architecture
Uber's new mobile architectureUber's new mobile architecture
Uber's new mobile architecture
 
Dockercon State of the Art in Microservices
Dockercon State of the Art in MicroservicesDockercon State of the Art in Microservices
Dockercon State of the Art in Microservices
 
Cloud Native Cost Optimization UCC
Cloud Native Cost Optimization UCCCloud Native Cost Optimization UCC
Cloud Native Cost Optimization UCC
 
vidhi talk.pdf
vidhi talk.pdfvidhi talk.pdf
vidhi talk.pdf
 
Failure is an Option: Scaling Resilient Feature Delivery
Failure is an Option: Scaling Resilient Feature DeliveryFailure is an Option: Scaling Resilient Feature Delivery
Failure is an Option: Scaling Resilient Feature Delivery
 
Cigniti Independent Software Testing Services
Cigniti Independent Software Testing ServicesCigniti Independent Software Testing Services
Cigniti Independent Software Testing Services
 
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...
 
Webinar: Automate Your Environment Provisioning for Mobile App Development
Webinar: Automate Your Environment Provisioning for Mobile App Development Webinar: Automate Your Environment Provisioning for Mobile App Development
Webinar: Automate Your Environment Provisioning for Mobile App Development
 
Software Testing Certification
Software Testing CertificationSoftware Testing Certification
Software Testing Certification
 
Creating Complete Test Environments in the Cloud: Skytap & Parasoft Webinar
Creating Complete Test Environments in the Cloud: Skytap & Parasoft WebinarCreating Complete Test Environments in the Cloud: Skytap & Parasoft Webinar
Creating Complete Test Environments in the Cloud: Skytap & Parasoft Webinar
 

More from John Ferguson Smart Limited

My Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosMy Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosJohn Ferguson Smart Limited
 
Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...John Ferguson Smart Limited
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceJohn Ferguson Smart Limited
 
Sustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplaySustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplayJohn Ferguson Smart Limited
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceJohn Ferguson Smart Limited
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...John Ferguson Smart Limited
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...John Ferguson Smart Limited
 
Screenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingScreenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingJohn Ferguson Smart Limited
 
BDD in Action: Building Software Right and Building the Right Software
BDD in Action: Building Software Right and Building the Right SoftwareBDD in Action: Building Software Right and Building the Right Software
BDD in Action: Building Software Right and Building the Right SoftwareJohn Ferguson Smart Limited
 
BDD in Action – principles, practices and real-world application
BDD in Action – principles, practices and real-world applicationBDD in Action – principles, practices and real-world application
BDD in Action – principles, practices and real-world applicationJohn Ferguson Smart Limited
 

More from John Ferguson Smart Limited (20)

My Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosMy Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin Scenarios
 
Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
 
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANTBE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
 
Sustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplaySustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and Screenplay
 
Feature Mapping Workshop
Feature Mapping WorkshopFeature Mapping Workshop
Feature Mapping Workshop
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
 
Shift left-devoxx-pl
Shift left-devoxx-plShift left-devoxx-pl
Shift left-devoxx-pl
 
Screenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingScreenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testing
 
Cucumber and Spock Primer
Cucumber and Spock PrimerCucumber and Spock Primer
Cucumber and Spock Primer
 
BDD in Action - Devoxx 2014
BDD in Action - Devoxx 2014BDD in Action - Devoxx 2014
BDD in Action - Devoxx 2014
 
BDD in Action: Building Software Right and Building the Right Software
BDD in Action: Building Software Right and Building the Right SoftwareBDD in Action: Building Software Right and Building the Right Software
BDD in Action: Building Software Right and Building the Right Software
 
Its testing-jim-but-not-as-we-know-it-devoxx
Its testing-jim-but-not-as-we-know-it-devoxxIts testing-jim-but-not-as-we-know-it-devoxx
Its testing-jim-but-not-as-we-know-it-devoxx
 
BDD in Action - building software that matters
BDD in Action - building software that mattersBDD in Action - building software that matters
BDD in Action - building software that matters
 
BDD in Action – principles, practices and real-world application
BDD in Action – principles, practices and real-world applicationBDD in Action – principles, practices and real-world application
BDD in Action – principles, practices and real-world application
 
TDD and BDD in Java 8 - what's in it for me?
TDD and BDD in Java 8 - what's in it for me?TDD and BDD in Java 8 - what's in it for me?
TDD and BDD in Java 8 - what's in it for me?
 
Continuous Integration 101
Continuous Integration 101Continuous Integration 101
Continuous Integration 101
 
BDD: There's more to it than you think
BDD: There's more to it than you thinkBDD: There's more to it than you think
BDD: There's more to it than you think
 

Recently uploaded

Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
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
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
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
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
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
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
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
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
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
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 

Recently uploaded (20)

Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
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
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
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...
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
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...
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
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...
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 

BDD Microservices Java Techniques Reflections

  • 1. Tools, techniques and reflections BDD-Driven Microservices in Java
  • 2. John Ferguson Smart Introductions “I help teams of smart people 
 learn to work together more efficiently, 
 to deliver better software faster”
  • 9. Microservices 101 Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service REST/HTTP
  • 10. Microservices 101 Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 13. Microservices 101 Movie Catalog Service Resource Service Layer Domain model Repositories
  • 14. Microservices 101 Movie Catalog Service Resource Persistance Layer Service Layer Domain model Repositories
  • 15. Microservices 101 Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories
  • 18. The testing pyramid Unit Tests Integration Tests
  • 19. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 20. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 21. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 22. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 23. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 24. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 25. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 26. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 27. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 28. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 29. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 30. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 31. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Unit Tests
  • 32. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Integration Tests
  • 33. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Integration Tests
  • 34. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Integration Tests
  • 35. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Integration Tests
  • 36. The testing pyramid Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Integration Tests
  • 37. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 38. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 39. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 40. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 41. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 42. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 43. The testing pyramid End-to-End Tests Movie Catalog Service Authentication Service Shopping Cart Service Delivery Service Payment Service Event Bus
  • 44. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 45. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 46. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 47. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 48. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 49. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 50. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 51. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 52. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 53. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 54. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 55. To document how to interact with the microservice To document what the microservice does To ensure the service work correctly To ensure we are delivering valuable functionality Why test our micro-services?
  • 56. To document how to interact with the microservice To document what the microservice does To ensure the service work correctly To ensure we are delivering valuable functionality Why test our micro-services?
  • 57. To document how to interact with the microservice To document what the microservice does To ensure the service work correctly To ensure we are delivering valuable functionality Why test our micro-services?
  • 58. To document how to interact with the microservice To document what the microservice does To ensure the service work correctly To ensure we are delivering valuable functionality Why test our micro-services?
  • 59. To document how to interact with the microservice To document what the microservice does To ensure the service work correctly To ensure we are delivering valuable functionality Why test our micro-services?
  • 60. To document how to interact with the microservice To document what the microservice does To ensure the service work correctly To ensure we are delivering valuable functionality Why test our micro-services?
  • 61. “We test our micro-services so we can deploy new features quickly and with confidence”
  • 62. And with aggressive production monitoring Writing executable specifications and living documentation To a sufficient level of confidence Outside-in testing Pragmatic web service testing
  • 63. And with aggressive production monitoring Writing executable specifications and living documentation To a sufficient level of confidence Outside-in testing Pragmatic web service testing
  • 64. And with aggressive production monitoring Writing executable specifications and living documentation To a sufficient level of confidence Outside-in testing Pragmatic web service testing
  • 65. And with aggressive production monitoring Writing executable specifications and living documentation To a sufficient level of confidence Outside-in testing Pragmatic web service testing
  • 66. And with aggressive production monitoring Writing executable specifications and living documentation To a sufficient level of confidence Outside-in testing Pragmatic web service testing
  • 67. And with aggressive production monitoring Writing executable specifications and living documentation To a sufficient level of confidence Outside-in testing Pragmatic web service testing
  • 69. To deliver software that matters And a common language to build a shared understanding Using examples at multiple levels Collaborate to discover requirements and identify uncertainty The essence of BDD
  • 70. To deliver software that matters And a common language to build a shared understanding Using examples at multiple levels Collaborate to discover requirements and identify uncertainty The essence of BDD
  • 71. To deliver software that matters And a common language to build a shared understanding Using examples at multiple levels Collaborate to discover requirements and identify uncertainty The essence of BDD
  • 72. To deliver software that matters And a common language to build a shared understanding Using examples at multiple levels Collaborate to discover requirements and identify uncertainty The essence of BDD
  • 73. To deliver software that matters And a common language to build a shared understanding Using examples at multiple levels Collaborate to discover requirements and identify uncertainty The essence of BDD
  • 74. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 75. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 76. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 77. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 78. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 79. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 80. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 81. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 82. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 83. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 84. The business owner tells the business analyst what he wants 1 2 The business analyst writes a requirements document 3 The developer translates the requirements into software 4 The tester translates the requirements into test cases 5 The technical writer translates the software into functional and technical documentation A traditional development process How does it work?
  • 85. How does it work? The business owner and the business analyst have a conversation about what he needs. 1 2 3 4 The tester uses these scenarios as the basis for her tests 5 The automated tests provide feedback on progress and help document the application The business analyst, the developer and the tester elaborate the requirements together. The scenarios guide the developer and act as automated tests They define requirements as structured, English- language format "scenarios" A BDD development process
  • 86. How does it work? The business owner and the business analyst have a conversation about what he needs. 1 2 3 4 The tester uses these scenarios as the basis for her tests 5 The automated tests provide feedback on progress and help document the application The business analyst, the developer and the tester elaborate the requirements together. The scenarios guide the developer and act as automated tests They define requirements as structured, English- language format "scenarios" A BDD development process
  • 87. How does it work? The business owner and the business analyst have a conversation about what he needs. 1 2 3 4 The tester uses these scenarios as the basis for her tests 5 The automated tests provide feedback on progress and help document the application The business analyst, the developer and the tester elaborate the requirements together. The scenarios guide the developer and act as automated tests They define requirements as structured, English- language format "scenarios" A BDD development process
  • 88. How does it work? The business owner and the business analyst have a conversation about what he needs. 1 2 3 4 The tester uses these scenarios as the basis for her tests 5 The automated tests provide feedback on progress and help document the application The business analyst, the developer and the tester elaborate the requirements together. The scenarios guide the developer and act as automated tests They define requirements as structured, English- language format "scenarios" A BDD development process
  • 89. How does it work? The business owner and the business analyst have a conversation about what he needs. 1 2 3 4 The tester uses these scenarios as the basis for her tests 5 The automated tests provide feedback on progress and help document the application The business analyst, the developer and the tester elaborate the requirements together. The scenarios guide the developer and act as automated tests They define requirements as structured, English- language format "scenarios" A BDD development process
  • 90. How does it work? The business owner and the business analyst have a conversation about what he needs. 1 2 3 4 The tester uses these scenarios as the basis for her tests 5 The automated tests provide feedback on progress and help document the application The business analyst, the developer and the tester elaborate the requirements together. The scenarios guide the developer and act as automated tests They define requirements as structured, English- language format "scenarios" A BDD development process
  • 91. But what about micro-services?
  • 92. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 93. The testing pyramid Unit Tests Integration Tests End-to-end Tests
  • 95. A different testing pyramid Executable Business Specifications
  • 96. A different testing pyramid Slow-running executable technical specifications Executable Business Specifications
  • 97. A different testing pyramid Fast-running executable technical specifications Slow-running executable technical specifications Executable Business Specifications
  • 98. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Executable Business specs
  • 99. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Executable Business specs Scenario: Search movies by director
 Given the catalog has the following movies:
 | title | director | actors |
 | Gladiator | Ridley Scott | Russel Crowe, Joaquin Phoenix |
 | Letters from Iwo Jima | Clint Eastwood | Ken Watanabe |
 | Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |
 When I search for movies directed by Clint Eastwood
 Then I should be presented with the following movies:
 | title | director | actors |
 | Letters from Iwo Jima | Clint Eastwood | Ken Watanabe |
 | Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |

  • 100. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Slow-running technical specs
  • 101. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Slow-running technical specs @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest("server.port:0")
 class WhenFindingMoviesViaTheRestAPI extends Specification {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Value('${local.server.port}')
 int port;
 
 def "should list movies by director"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
 when:
 List<Movie> movies = when().get("/movies/findByDirector/Clint Eastwood").as(List)
 then:
 movies.collect {movie -> movie.title} == ["Letters from Iwo Jima", "Gran Torino"]
 }
  • 102. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Fast- running technical specs
  • 103. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Fast- running technical specs def setup() {
 repository = Mock(MovieRepository)
 artistService = new ArtistService(movieRepository: repository)
 }
 
 def "should build actor details from films the artist has acted in and has directed"() {
 given: "Clint Eastwood has directed some films"
 repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 and: "Clint Eastwood has starred in some films"
 repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
 when:
 def artistDetails = artistService.findArtistByName("Clint Eastwood")
 then:
 artistDetails.isPresent()
 and:
 artistDetails.get().name == "Clint Eastwood" &&
 artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
 artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 } Spock
  • 104. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Fast- running technical specs
  • 105. Outside-in development Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Fast- running technical specs class MovieControllerSpecs extends Specification {
 
 MovieRepository movieRepository = Mock()
 
 def "should find by director regardless of case (#director -> #filteredDirector)"() {
 given:
 def controller = new MovieController(repository: movieRepository)
 when:
 controller.findByDirector(director)
 then:
 1*movieRepository.findByDirector(filteredDirector)
 where:
 director | filteredDirector
 "Clint Eastwood" | "Clint Eastwood"
 "Clint eastwood" | "Clint Eastwood" Spock
  • 107. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service Delivery Service REST/HTTP
  • 108. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service REST/HTTP Delivery Service
  • 109. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service REST/HTTP Consumer Delivery Service
  • 110. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service REST/HTTP Consumer Producer Delivery Service
  • 111. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service REST/HTTP Consumer Producer Contract Delivery Service
  • 112. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service REST/HTTP Contract Delivery Service
  • 113. Micro-service Contracts Movie Catalog Service Resource Persistance Layer Gateway Service Layer Domain model Repositories Shopping Cart Service Delivery Service REST/HTTP Contract Mock Shopping Cart Service
  • 115. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Producer
  • 116. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer
  • 117. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer Consumer
  • 118. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer Consumer Consumer
  • 119. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer Consumer Consumer Contract
  • 120. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer Consumer Consumer Contract
  • 121. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer Consumer Consumer Contract
  • 122. Micro-service Contracts REST/HTTP Movie Catalog Service Web app iPhone app Android app Consumer Producer Consumer Consumer Contract The Producer API is the sum of the Consumer Contrats
  • 123. Specialised ToolsPublished specificationsAutomated Acceptance Criteria Verifying the contracts
  • 124. Specialised ToolsPublished specificationsAutomated Acceptance Criteria Verifying the contracts
  • 125. Specialised ToolsPublished specificationsAutomated Acceptance Criteria Verifying the contracts
  • 126. Specialised ToolsPublished specificationsAutomated Acceptance Criteria Verifying the contracts
  • 127. Specialised ToolsPublished specificationsAutomated Acceptance Criteria Verifying the contracts
  • 135. Pact and Pacto
 Consumer Driven Contract Testing 42 Consumer Movie Catalog Service
  • 136. Pact and Pacto
 Consumer Driven Contract Testing 42 Consumer Movie Catalog Service Mock Service Pact help us create and configure a mock service
  • 137. Pact and Pacto
 Consumer Driven Contract Testing 43 Consumer Movie Catalog Service Mock Service
  • 138. Pact and Pacto
 Consumer Driven Contract Testing 43 Consumer Movie Catalog Service Mock Service We write specifications to describe the expected behaviour of the service
  • 139. Pact and Pacto
 Consumer Driven Contract Testing 44 Consumer Movie Catalog Service Mock Service
  • 140. Pact and Pacto
 Consumer Driven Contract Testing 44 Consumer Movie Catalog Service Mock Service When we run these specifications, the expected behaviour is recorded in a ‘pact’ file asdasdasda asdasdasdas asdasdasd asdasdasda asdasdasdasd asdasdasdasd asdasdasdas
  • 141. Pact and Pacto
 Consumer Driven Contract Testing 45 Consumer Movie Catalog Service Mock Service asdasdasda asdasdasdas asdasdasd asdasdasda asdasdasdasd asdasdasdasd asdasdasdas
  • 142. Pact and Pacto
 Consumer Driven Contract Testing 45 Consumer Movie Catalog Service Mock Service We can now use this ‘pact’ to test(drive) the service implementation asdasdasda asdasdasdas asdasdasd asdasdasda asdasdasdasd asdasdasdasd asdasdasdas
  • 144. From BDD to TDD “How much automated testing?
 As much as you need, but no more.”
  • 148. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog
  • 149. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog
  • 150. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog @When("I add this movie to the catalog")
 public void addMovieToCatalog() {
 movieId = rest().given().contentType("application/json")
 .content(newMovie)
 .post("/movies")
 .then().statusCode(200)
 .and().extract().jsonPath().getString("id");
 }
  • 151. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog
  • 152. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog
  • 153. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog @Then("I should be able to find it in the catalog")
 public void shouldBeAbleToFindMovieInCatalog() {
 rest().given().contentType("application/json")
 .get("/movies/{movieId}", movieId)
 .then().statusCode(200)
 .and().body("title", equalTo(newMovie.getTitle()))
 .and().body("director", equalTo(newMovie.getDirector()));
 }
  • 154. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog @Then("I should be able to find it in the catalog")
 public void shouldBeAbleToFindMovieInCatalog() {
 rest().given().contentType("application/json")
 .get("/movies/{movieId}", movieId)
 .then().statusCode(200)
 .and().body("title", equalTo(newMovie.getTitle()))
 .and().body("director", equalTo(newMovie.getDirector()));
 } Rest Assured + Serenity
  • 155. Feature: Adding new movies
 In order to sell more movies
 As an online movie seller
 I want to be able to add movies to the catalog
 
 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog @Then("I should be able to find it in the catalog")
 public void shouldBeAbleToFindMovieInCatalog() {
 rest().given().contentType("application/json")
 .get("/movies/{movieId}", movieId)
 .then().statusCode(200)
 .and().body("title", equalTo(newMovie.getTitle()))
 .and().body("director", equalTo(newMovie.getDirector()));
 }
  • 156. Testing REST services with Rest-Assured
  • 157. Testing REST services with Rest-Assured get(“/movies/findByTitle/Gladiator") .then().body("title", equalTo("Gladiator"));
  • 158. Testing REST services with Rest-Assured get(“/movies/findByTitle/Gladiator") .then().body("title", equalTo("Gladiator"));
  • 159. Testing REST services with Rest-Assured when().get(“/movies/findByTitle/Gladiator”) .then().body("nominations.category", hasItems("Best Actor", "Special Effects"));
  • 160. Testing REST services with Rest-Assured when().get(“/movies/findByTitle/Gladiator”) .then().body("nominations.category", hasItems("Best Actor", "Special Effects"));
  • 161. Testing REST services with Rest-Assured given().contentType("application/json")
 .content(newMovie)
 .post("/movies")
 .then().statusCode(200)
 .and().extract().jsonPath().getString("id");
  • 162. Testing REST services with Rest-Assured given().contentType("application/json")
 .content(newMovie)
 .post("/movies")
 .then().statusCode(200)
 .and().extract().jsonPath().getString("id"); Posting data
  • 163. Testing REST services with Rest-Assured Movie matchingMovie = get("/movies/findByTitle/Gladiator").as(Movie.class);
  • 164. Testing REST services with Rest-Assured Movie matchingMovie = get("/movies/findByTitle/Gladiator").as(Movie.class); Convert responses to Java objects
  • 165. Testing REST services with Rest-Assured given().param("title","Unknown").
 when().get("/movies/search").
 then().statusCode(404);
  • 166. Testing REST services with Rest-Assured given().param("title","Unknown").
 when().get("/movies/search").
 then().statusCode(404); Check for errors
  • 171. 57 @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest("server.port:0")
 class WhenFindingMovies extends Specification {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Value('${local.server.port}')
 int port;
 
 def setup() {
 movieRepository.deleteAll();
 RestAssured.port = port;
 }
 
 def "should list all movies"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
 when:
 def movies = when().get("/movies").as(List)
 then:
 movies.collect {movie -> movie.title} == ["Gladiator", 
 "Letters from Iwo Jima", 
 "Gran Torino"]
 }
  • 172. 57 @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest("server.port:0")
 class WhenFindingMovies extends Specification {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Value('${local.server.port}')
 int port;
 
 def setup() {
 movieRepository.deleteAll();
 RestAssured.port = port;
 }
 
 def "should list all movies"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
 when:
 def movies = when().get("/movies").as(List)
 then:
 movies.collect {movie -> movie.title} == ["Gladiator", 
 "Letters from Iwo Jima", 
 "Gran Torino"]
 } Spring Context
  • 173. 57 @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest("server.port:0")
 class WhenFindingMovies extends Specification {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Value('${local.server.port}')
 int port;
 
 def setup() {
 movieRepository.deleteAll();
 RestAssured.port = port;
 }
 
 def "should list all movies"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
 when:
 def movies = when().get("/movies").as(List)
 then:
 movies.collect {movie -> movie.title} == ["Gladiator", 
 "Letters from Iwo Jima", 
 "Gran Torino"]
 } Spring Integration Tests
  • 174. 57 @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest("server.port:0")
 class WhenFindingMovies extends Specification {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Value('${local.server.port}')
 int port;
 
 def setup() {
 movieRepository.deleteAll();
 RestAssured.port = port;
 }
 
 def "should list all movies"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
 when:
 def movies = when().get("/movies").as(List)
 then:
 movies.collect {movie -> movie.title} == ["Gladiator", 
 "Letters from Iwo Jima", 
 "Gran Torino"]
 } Rest Assured
  • 175. 57 @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest("server.port:0")
 class WhenFindingMovies extends Specification {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Value('${local.server.port}')
 int port;
 
 def setup() {
 movieRepository.deleteAll();
 RestAssured.port = port;
 }
 
 def "should list all movies"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO])
 when:
 def movies = when().get("/movies").as(List)
 then:
 movies.collect {movie -> movie.title} == ["Gladiator", 
 "Letters from Iwo Jima", 
 "Gran Torino"]
 }
  • 179. @ContextConfiguration(loader = SpringApplicationContextLoader.class,
 classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest
 class WhenViewingActorDetailsViaTheController extends Specification {
 
 @Autowired
 ArtistController artistController;
 
 def "should retrieve actor details for an artist"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,
 THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])
 when:
 Artist artist = artistController.findArtistDetails("Clint Eastwood")
 then:
 artist.name == "Clint Eastwood"
 and:
 artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO)
 and:
 artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)
 }
  • 180. @ContextConfiguration(loader = SpringApplicationContextLoader.class,
 classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest
 class WhenViewingActorDetailsViaTheController extends Specification {
 
 @Autowired
 ArtistController artistController;
 
 def "should retrieve actor details for an artist"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,
 THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])
 when:
 Artist artist = artistController.findArtistDetails("Clint Eastwood")
 then:
 artist.name == "Clint Eastwood"
 and:
 artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO)
 and:
 artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)
 } Use a fully wired controller
  • 181. @ContextConfiguration(loader = SpringApplicationContextLoader.class,
 classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest
 class WhenViewingActorDetailsViaTheController extends Specification {
 
 @Autowired
 ArtistController artistController;
 
 def "should retrieve actor details for an artist"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,
 THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])
 when:
 Artist artist = artistController.findArtistDetails("Clint Eastwood")
 then:
 artist.name == "Clint Eastwood"
 and:
 artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO)
 and:
 artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)
 } Use domain objects rather than REST calls
  • 182. @ContextConfiguration(loader = SpringApplicationContextLoader.class,
 classes = MovieServiceApplication.class)
 @WebAppConfiguration
 @IntegrationTest
 class WhenViewingActorDetailsViaTheController extends Specification {
 
 @Autowired
 ArtistController artistController;
 
 def "should retrieve actor details for an artist"() {
 given:
 movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA,
 THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO])
 when:
 Artist artist = artistController.findArtistDetails("Clint Eastwood")
 then:
 artist.name == "Clint Eastwood"
 and:
 artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO)
 and:
 artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO)
 }
  • 184. Service or domain-level testing Spock
  • 185. MovieRepository repository
 def artistService
 
 def setup() {
 repository = Mock(MovieRepository)
 artistService = new ArtistService(movieRepository: repository)
 }
 
 def "should build actor details from films the artist has acted in and has directed"() {
 given: "Clint Eastwood has directed some films"
 repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 and: "Clint Eastwood has starred in some films"
 repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
 when:
 def artistDetails = artistService.findArtistByName("Clint Eastwood")
 then:
 artistDetails.isPresent()
 and:
 artistDetails.get().name == "Clint Eastwood" &&
 artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
 artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 }
  • 186. MovieRepository repository
 def artistService
 
 def setup() {
 repository = Mock(MovieRepository)
 artistService = new ArtistService(movieRepository: repository)
 }
 
 def "should build actor details from films the artist has acted in and has directed"() {
 given: "Clint Eastwood has directed some films"
 repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 and: "Clint Eastwood has starred in some films"
 repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
 when:
 def artistDetails = artistService.findArtistByName("Clint Eastwood")
 then:
 artistDetails.isPresent()
 and:
 artistDetails.get().name == "Clint Eastwood" &&
 artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
 artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 } Mocked repositories
  • 187. MovieRepository repository
 def artistService
 
 def setup() {
 repository = Mock(MovieRepository)
 artistService = new ArtistService(movieRepository: repository)
 }
 
 def "should build actor details from films the artist has acted in and has directed"() {
 given: "Clint Eastwood has directed some films"
 repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 and: "Clint Eastwood has starred in some films"
 repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
 when:
 def artistDetails = artistService.findArtistByName("Clint Eastwood")
 then:
 artistDetails.isPresent()
 and:
 artistDetails.get().name == "Clint Eastwood" &&
 artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
 artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 } Call the service
  • 188. MovieRepository repository
 def artistService
 
 def setup() {
 repository = Mock(MovieRepository)
 artistService = new ArtistService(movieRepository: repository)
 }
 
 def "should build actor details from films the artist has acted in and has directed"() {
 given: "Clint Eastwood has directed some films"
 repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 and: "Clint Eastwood has starred in some films"
 repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
 when:
 def artistDetails = artistService.findArtistByName("Clint Eastwood")
 then:
 artistDetails.isPresent()
 and:
 artistDetails.get().name == "Clint Eastwood" &&
 artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
 artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 } Check the outcomes
  • 189. MovieRepository repository
 def artistService
 
 def setup() {
 repository = Mock(MovieRepository)
 artistService = new ArtistService(movieRepository: repository)
 }
 
 def "should build actor details from films the artist has acted in and has directed"() {
 given: "Clint Eastwood has directed some films"
 repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 and: "Clint Eastwood has starred in some films"
 repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]
 when:
 def artistDetails = artistService.findArtistByName("Clint Eastwood")
 then:
 artistDetails.isPresent()
 and:
 artistDetails.get().name == "Clint Eastwood" &&
 artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] &&
 artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO]
 }
  • 192. Living Functional Documentation with Serenity and Cucumber
  • 193. 65 Scenario: Adding movies
 Given the following movie has just come out
 | title | director | actors |
 | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard |
 When I add this movie to the catalog
 Then I should be able to find it in the catalog Executable Specifications Automated tests Living documentation
  • 194. 66
  • 197. 67
  • 199. Living API Documentation 
 with Swagger Springfox
  • 201. 70 @RequestMapping(method = GET)
 @ApiOperation("List all the movies in the catalog")
 public List<Movie> findAll() {
 return repository.findAll();
 }
 
 @RequestMapping(method = POST)
 @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
 public Movie add(@RequestBody Movie newMovie) {
 return repository.save(newMovie);
 }
 
 @RequestMapping(value = "/{id}", method = DELETE)
 @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
 public void delete(@PathVariable String id) {
 repository.delete(id);
 }
 Springfox Some annotations… Swagger and Spring Boot
  • 202. 70 @RequestMapping(method = GET)
 @ApiOperation("List all the movies in the catalog")
 public List<Movie> findAll() {
 return repository.findAll();
 }
 
 @RequestMapping(method = POST)
 @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
 public Movie add(@RequestBody Movie newMovie) {
 return repository.save(newMovie);
 }
 
 @RequestMapping(value = "/{id}", method = DELETE)
 @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
 public void delete(@PathVariable String id) {
 repository.delete(id);
 }
 Springfox Some annotations… Swagger and Spring Boot
  • 203. 70 @RequestMapping(method = GET)
 @ApiOperation("List all the movies in the catalog")
 public List<Movie> findAll() {
 return repository.findAll();
 }
 
 @RequestMapping(method = POST)
 @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
 public Movie add(@RequestBody Movie newMovie) {
 return repository.save(newMovie);
 }
 
 @RequestMapping(value = "/{id}", method = DELETE)
 @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
 public void delete(@PathVariable String id) {
 repository.delete(id);
 }
 Springfox Some annotations… Swagger and Spring Boot
  • 204. 70 @RequestMapping(method = GET)
 @ApiOperation("List all the movies in the catalog")
 public List<Movie> findAll() {
 return repository.findAll();
 }
 
 @RequestMapping(method = POST)
 @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST")
 public Movie add(@RequestBody Movie newMovie) {
 return repository.save(newMovie);
 }
 
 @RequestMapping(value = "/{id}", method = DELETE)
 @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE")
 public void delete(@PathVariable String id) {
 repository.delete(id);
 }
 Springfox Some annotations… Swagger and Spring Boot
  • 205. 71 Springfox @EnableAutoConfiguration
 @EnableSwagger2
 public class MovieServiceApplication {
 
 public static void main(String[] args) {
 SpringApplication.run(MovieServiceApplication.class, args);
 }
 
 @Bean
 public Docket moviesApi() {
 return new Docket(DocumentationType.SWAGGER_2)
 .select()
 .apis(RequestHandlerSelectors.any())
 .paths(PathSelectors.any())
 .build()
 .pathMapping("/")
 .directModelSubstitute(LocalDate.class, String.class)
 .genericModelSubstitutes(ResponseEntity.class);
 }
 } Some configuration… Swagger and Spring Boot
  • 206. 72 Springfox Documentation
 bundled with your web services Swagger and Spring Boot
  • 208. Automated MonitoringFast provisioningA fast deployment pipeline So you want to micro-service?
  • 209. Automated health checksReal operationsSmoke tests in production Simple checks may not be enough
  • 210. An example with Spring Actuator @Component
 public class CatalogHealth implements HealthIndicator {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Override
 public Health health() {
 return (isCatalogStocked()) ? 
 Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() 
 : Health.down().build();
 }
 
 private boolean isCatalogStocked() {
 return (movieRepository.count() > 0);
 }
 }
  • 211. An example with Spring Actuator @Component
 public class CatalogHealth implements HealthIndicator {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Override
 public Health health() {
 return (isCatalogStocked()) ? 
 Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() 
 : Health.down().build();
 }
 
 private boolean isCatalogStocked() {
 return (movieRepository.count() > 0);
 }
 } A Spring Actuator Health Check
  • 212. An example with Spring Actuator @Component
 public class CatalogHealth implements HealthIndicator {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Override
 public Health health() {
 return (isCatalogStocked()) ? 
 Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() 
 : Health.down().build();
 }
 
 private boolean isCatalogStocked() {
 return (movieRepository.count() > 0);
 }
 } A Spring Actuator Health Check Custom logic to decide if the app is working
  • 213. An example with Spring Actuator @Component
 public class MovieTransactionHealth implements HealthIndicator {
 
 @Autowired
 MovieController movieController;
 
 @Override
 public Health health() {
 return Health.status(transactionStatus()).build();
 }
 
 private Status transactionStatus() {
 try {
 Movie movie = new Movie("TEST title", "TEST description", "TEST director", ImmutableList.of("TEST actor"));
 Movie reloadedMovie = movieController.add(movie);
 movieController.delete(reloadedMovie.getId());
 return Status.UP;
 } catch (Throwable e) {
 return new Status("DOWN", e.toString());
 }
 }
 }
  • 214. An example with Spring Actuator @Component
 public class MovieTransactionHealth implements HealthIndicator {
 
 @Autowired
 MovieController movieController;
 
 @Override
 public Health health() {
 return Health.status(transactionStatus()).build();
 }
 
 private Status transactionStatus() {
 try {
 Movie movie = new Movie("TEST title", "TEST description", "TEST director", ImmutableList.of("TEST actor"));
 Movie reloadedMovie = movieController.add(movie);
 movieController.delete(reloadedMovie.getId());
 return Status.UP;
 } catch (Throwable e) {
 return new Status("DOWN", e.toString());
 }
 }
 } More complex custom logic
  • 215. An example with Spring Actuator @Component
 public class MovieTransactionHealth implements HealthIndicator {
 
 @Autowired
 MovieController movieController;
 
 @Override
 public Health health() {
 return Health.status(transactionStatus()).build();
 }
 
 private Status transactionStatus() {…}
 } @Component
 public class CatalogHealth implements HealthIndicator {
 
 @Autowired
 MovieRepository movieRepository;
 
 @Override
 public Health health() {
 return (isCatalogStocked()) ? 
 Health.status(new Status("UP", "Movie count: " + 
 movieRepository.count())).build() 
 : Health.down().build();
 }
 
 private boolean isCatalogStocked() {…}
 }
  • 216. Try all this out at home! Install Gradle Install MongoDB Clone the repowakaleo/movie-service