SlideShare ist ein Scribd-Unternehmen logo
1 von 78
Downloaden Sie, um offline zu lesen
10 Testing libraries
any Java developer should know
Alex Soto‹
Red Hat Engineer‹
@alexsotob
@alexsotob2
Alex Soto
Red Hat Engineer
www.lordofthejars.com
@alexsotob
Who Am I?
@alexsotob3
https://www.manning.com/books/testing-java-microservices
@alexsotob4
Questions
@alexsotob5
ASSERTIONS
@alexsotob
JUnit Test
@Test
public void should_find_composer_by_name() {
// Given:
Composers composers = new Composers();
// When:
final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart");
// Then:
assertEquals("Wolfgang Amadeus Mozart", mozart.getName());
assertEquals(Era.CLASSICAL, mozart.getEra());
assertEquals(LocalDate.of(1756, 1, 27), mozart.getBirthdate());
assertEquals(LocalDate.of(1791, 12, 5), mozart.getDied());
}
6
Readable name
BDD style
AssertEquals Order
Depends On Equals
@alexsotob7
AssertJ
@alexsotob
AssertJ Test
import static org.assertj.core.api.Assertions.assertThat;
@Test
public void should_find_composer_by_name() {
// Given:
Composers composers = new Composers();
// When:
final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart”);
// Then:
assertThat(mozart.getName()).isEqualTo("Wolfgang Amadeus Mozart”);
assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName);
assertThat(mozart.getBirthdate()).isEqualTo(LocalDate.of(1756, 1, 27));
assertThat(mozart).isEqualToComparingFieldByField(expectedMozart);
assertThat(mozart).isEqualToIgnoringNullFields(expectedMozart);
}
8
Static Import
Readable Assertions
Not Depending on
Equals
@alexsotob
AssertJ Test Collections
@Test
public void should_find_operas_by_composer_name() {
// Given:
Composers composers = new Composers();
// When:
final List<Opera> operas = composers.findOperasByComposerName("Wolfgang Amadeus Mozart");
// Then:
assertThat(operas)
.hasSize(2)
.extracting(Opera::getName)
.containsExactlyInAnyOrder("Die Zauberflöte", "Don Giovanni”);
}
9
Train Call (IDE
support) Create List with
getName Result
Methods for String
@alexsotob
AssertJ Soft Assertions
@Test
public void should_find_composer_by_name_soft_assertions() {
// Given:
Composers composers = new Composers();
// When:
final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart");
// Then:
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(mozart.getName()).isEqualTo("Wolfgang Amadeus Mozart");
softly.assertThat(mozart.getEra()).isEqualTo(Era.CLASSICAL);
softly.assertThat(mozart.getBirthdate()).isEqualTo(LocalDate.of(1756, 1, 27));
softly.assertThat(mozart.getDied()).isEqualTo(LocalDate.of(1791, 12, 5));
});
}
10
Java 8 Lambda
All assertions in Block
@alexsotob11
Things go
Wrong
@alexsotob
Try/Catch
@Test
public void should_throw_exception_if_composer_not_found() {
// Given:
Composers composers = new Composers();
// When:
try {
final Composer salieri = composers.findComposerByName("Antonio Salieri");
fail();
} catch (IllegalArgumentException e) {
// Then:
assertEquals("Composer Antonio Salieri is not found", e.getMessage());
}
}
12
Fails if Success
@alexsotob
JUnit
@Test(expected = IllegalArgumentException.class)
public void should_throw_exception_if_composer_not_found_version_2() {
// Given:
Composers composers = new Composers();
// When:
final Composer salieri = composers.findComposerByName("Antonio Salieri");
}
13
Special Attribute
@alexsotob
AssertJ Exceptions
@Test
public void should_throw_exception_if_composer_not_found_version_3() {
// Given:
Composers composers = new Composers();
// When:
Throwable thrown = catchThrowable(() -> composers.findComposerByName("Antonio Salieri"));
// Then:
assertThat(thrown).isInstanceOf(IllegalArgumentException.class)
.withFailMessage("Composer Antonio Salieri is not found”);
}
14
Catch Exception of Lambda
Assertion Methods for
Exceptions
@alexsotob15
DEMO
@alexsotob16
Benefits of AssertJ
> IDE Friendly
Ctrl + Space works
> Assertions Generation
ComposerAssert.assertThat(mozart).hasName(“Mozart”).hasBirthdate(LocalDate.of(..);
> Out-of-the-Box Assertions
Guava, Joda, DB, Neo4j and Swing
@alexsotob17
Don’t Sleep, Just Wait
@alexsotob
Asynchronous Call
@Test
public void should_play_operas() throws InterruptedException {
// Given:
final Opera nozzeDiFigaro = ...;
Gramophone gramophone = new Gramophone();
// When:
gramophone.play(nozzeDiFigaro);
// Then:
TimeUnit.SECONDS.sleep(3);
assertThat(gramophone.getCurrentOpera()).isEqualTo(nozzeDiFigaro);
}
18
Asynchronous Call
Slowest Machine Time
@alexsotob19
@alexsotob
Awaitility Example
@Test
public void should_play_operas_version_2() {
// Given:
final Opera nozzeDiFigaro = Composers.OperaFactory
.createOpera("Le Nozze di Figaro")
.language(Language.ITALIAN).librettist("Lorenzo Da Ponte")
.roles("Count Almaviva", "Countess Rosina", "Susanna", "Figaro")
.build();
Gramophone gramophone = new Gramophone();
// When:
gramophone.play(nozzeDiFigaro);
// Then:
await().atMost(5, TimeUnit.SECONDS).until(gramophone::isPlaying);
assertThat(gramophone.getCurrentOpera()).isEqualTo(nozzeDiFigaro);
}
20
Asynchronous Call
Polls until True or Timeout
@alexsotob21
DEMO
@alexsotob22
Benefits of Awaitility
> Deadlock Detection
> Different Pollings
Fixed, Fibonacci, Iterative, Custom
> Simple Library
No dependencies, No magic
@alexsotob23
REST API
@alexsotob
GET /Ludwig+van+Beethoven
{
"name": "Ludwig van Beethoven",
"era": "ROMANTIC",
"birthdate": {},
"died": {},
"operas": [
{
"name": "Fidelio",
"librettist": "Georg Friedrich Treitschke",
"language": "GERMAN",
"roles": ["Rocco", "Leonore", "Florestan"]
}
]
}
24
Simple Objects
Array of Objects
@alexsotob
HttpClient Example
@Test
public void should_find_composer() throws IOException, URISyntaxException {
// Given:
URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/");
uriBuilder.setPath("Ludwig van Beethoven");
// When:
final Content bodyContent = Request.Get(uriBuilder.build())
.execute().returnContent();
String body = bodyContent.asString();
// Then:
assertThat(body).contains(""name":"Ludwig van Beethoven"")
.contains(""librettist":"Georg Friedrich Treitschke"");
}
25
Prepare Connection
Do connection
Get content
Manipulate String
@alexsotob
WebDriver Example
// Given:
WebDriver browser = new FirefoxDriver();
URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/");
uriBuilder.setPath("Ludwig van Beethoven");
// When:
browser.navigate().to(uriBuilder.build());
// Then:
assertThat(browser.getPageSource()).contains(""name":"Ludwig van Beethoven"");
26
@alexsotob27
@alexsotob
REST-assured Example
@Test
public void should_find_composer() {
given()
.when()
.get("{composer}", "Ludwig van Beethoven")
.then()
.assertThat()
.body("name", is("Ludwig van Beethoven"))
.body("operas.size()", is(1))
.body("operas.name", hasItems("Fidelio"));
}
28
GET Http Method with
Placeholders
GPath Expression
@alexsotob
REST-assured Example
@Test
public void should_insert_composer() {
Composer composer = ....;
given()
.param("parameter1", "parameterValue")
.body(composer)
.when()
.post()
.then()
.assertThat()
.statusCode(201);
}
29
Create POJO object
Set Params
Set POJO as Body
POST Http Method
Assertion on Status Code
@alexsotob
REST-assured Request Logging
given().log().all(). .. // Log all request specification details
given().log().params(). .. // Log only the parameters of the request
given().log().body(). .. // Log only the request body
given().log().headers(). .. // Log only the request headers
given().log().cookies(). .. // Log only the request cookies
given().log().method(). .. // Log only the request method
given().log().path(). .. // Log only the request path
30
@alexsotob
REST-assured Response Logging
get("/x").then().log().ifError()
get("/x").then().log().all()
given().log().ifValidationFails()
get("/x").then().log().ifStatusCodeIsEqualTo(302)
given().config(RestAssured.config()
.logConfig(logConfig().enableLoggingOfRequestAndResponseIfValidationFails())
)
31
@alexsotob
REST-assured Request SpeciïŹcation
.get("http://example.com/{composer}", "Ludwig van Beethoven")
RequestSpecBuilder builder = new RequestSpecBuilder();
builder.setBaseUri("http://example.com");
given().spec(builder.build())...
32
Use domain directly
Use Spec Builder
Reuse Everywhere
@alexsotob
REST-assured Auth
given().auth().oauth2(accessToken).when()...
given().auth().form("John", "Doe", springSecurity().withCsrfFieldName("_csrf")).when()...
given().auth().basic("username", "password").when()...
33
@alexsotob34
DEMO
@alexsotob35
More Features of Rest-Assured
> Custom Parsers
Not just JSON and XML
> SSL Support
.relaxedHTTPSValidation()
> Filters
Input/Output modiïŹcation
> JSON Schema Validation
Content not Important
@alexsotob36
Service Virtualization
@alexsotob
Service Virtualization Capture Mode
37
Service A External Network Service B
Scripts
Proxy
@alexsotob
Service Virtualization Simulate Mode
38
Service A External Network Service B
Scripts
Proxy
@alexsotob39
@alexsotob
HoverïŹ‚y Example
@ClassRule
public static HoverflyRule hoverflyRule =
HoverflyRule.inCaptureOrSimulationMode("getcomposers.json");
@Test
public void should_get_composers_from_composers_microservice() {
// Given:
ComposersGateway composersGateway = new ComposersGateway("operas.com", 8081);
// When:
Composer composer = composersGateway.getComposer("Ludwig van Beethoven");
// Then:
assertThat(composer.getName()).isEqualTo("Ludwig van Beethoven");
}
40
Start HoverïŹ‚y
Use Real Host
Get Data from Real
{
"data" : {
"pairs" : [{
"request" : {
"path" : "/Ludwig van Beethoven",
"method" : "GET",
"destination" : “operas.com:8081",
...
}
"response" : {
"status" : 200,
"body" : "{"name":"Ludwig van Beethoven",}",
"encodedBody" : false,
"headers" : {
"Connection" : [ "keep-alive" ],
...
}
}
}
}
Get Data from Proxy
@alexsotob
HoverïŹ‚y Example Simulate
private static String RESPONSE = "[n"
+ " {n"
+ " "name": "Moon",n"
+ " "villain": "Gru",n"
+ " "wiki": "https://en.wikipedia.org/wiki/Moon"n"
+ " }
+ "]";
@ClassRule
public static HoverflyRule hoverflyRule =
HoverflyRule.inSimulationMode(dsl(
service("crimesdb:8080")
.get("/crimes/Gru")
.willReturn(success(RESPONSE, "application/json"))
41
Hardcoded response
Starts in simulate
Host
Program interactions
@alexsotob42
Benefits of Service Virtualization and Hoverfly
> Do not relay on network
Yet testing all stack trace
> HoverïŹ‚y multilanguage
Can be used as standalone proxy
> HoverïŹ‚y JVM
Integration with JVM proxy settings
@alexsotob43
Contract Tests
@alexsotob44
Consumer
request
response Stub Server
expectations
Provider
request
response
Result
DeïŹne Consumer Expectations Verify Expectations On Provider
@alexsotob45
@RunWith(Arquillian.class)
public class CrimesConsumerContractTest {
@StubServer URL pactServer;
@Pact(provider = "crimes", consumer = "villains")
public RequestResponsePact returnListOfCrimes(PactDslWithProvider builder) {
return builder
.uponReceiving("Gru villain to get all Crimes")
.path("/crimes/Gru")
.method("GET")
.willRespondWith()
.status(200)
.body(RESPONSE)
.toPact();
}
@Test
@PactVerification("crimes")
public void should_get_list_of_crimes_by_villain() {
CrimesGateway crimesGateway = new CrimesGateway(webClient, pactServer);
final Single<JsonArray> gruCrimes = crimesGateway.getCrimesByVillainName("Gru");
}
Stub/proxy Server URL
DeïŹnes service interaction
Provides predeïŹned Req/Res
Executes real requests
Consumer side
@alexsotob46
@RunWith(Arquillian.class)
@Provider("crimes")
@ContractsFolder("~/crimescontract")
public class CrimesContractTest {
@ArquillianResource
Target target;
@Test
public void should_validate_contract() {
assertThat(target).withUrl(getCrimesServer()).satisfiesContract();
}
}
Provider under validation
Location of contracts
Http Client
Asserts All Interactions are correct
Provider side
@alexsotob47
DEMO
@alexsotob48
Benefits of CDC and Pact
> Pact Foundation
Pact speciïŹcation v3
> Integration with several languages
JVM, Ruby, Python, Go, .Net, Swift, JS
> Pact Broker
Sharing contracts, API documentation, Overview of services
> Arquillian Algeron
Arquillian ecosystem + Pact, Publishers/Retrievers, JBoss Forge
> Consumer Driven Contracts
Fail fast
Independent deployments
Improve communication
@alexsotob49
Containers Are Burning
@alexsotob
Testing Containers
docker build -t myorg/myservice:1.0.0 .
docker run --rm -ti -p 8080:8080 myorg/myservice:1.0.0
docker-compose up
mvn clean test
docker-compose stop
50
Docker Run
Docker Compose Run
Run tests
Stop Docker Containers
@alexsotob51
@alexsotob
Arquillian Cube Example
@RunWith(Arquillian.class)
public class HelloWorldTest {
@ArquillianResource
@DockerUrl(containerName = "helloworld", exposedPort = 8080)
RequestSpecBuilder requestSpecBuilder;
@Test
public void should_receive_ok_message() {
RestAssured
.given()
.spec(requestSpecBuilder.build())
.when()
.get()
.then()
.assertThat().body("status", equalTo("OK"));
}
}
52
Arquillian Runner
REST-Assured Integration
Environment Resolver
Normal REST-Assured Call
helloworld:
image: jonmorehouse/ping-pong
ports:
- "8080:8080"
src/test/docker/docker-compose.yml
@alexsotob
Arquillian Cube DSL
@RunWith(SpringRunner.class)
@SpringBootTest(classes = PingPongController.class, webEnvironment = RANDOM_PORT)
@ContextConfiguration(initializers = PingPongSpringBootTest.Initializer.class)
public class PingPongSpringBootTest {
@ClassRule
public static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6")
.withPortBinding(6379);
@Autowired
TestRestTemplate restTemplate;
@Test
public void should_get_data_from_redis() {
}
53
Spring Boot Test
Custom Initializer
Container DeïŹnition
public static class Initializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
EnvironmentTestUtils.addEnvironment("testcontainers",
configurableApplicationContext.getEnvironment(),
"spring.redis.host=" + redis.getIpAddress(),
"spring.redis.port=" + redis.getBindPort(6379)
);
Sets Container Environment
@alexsotob54
DEMO
@alexsotob
Arquillian Kube
@RunWith(Arquillian.class)
public class HelloWorldTest {
@ArquillianResource
KubernetesClient client;
@Named(“hello-world-service")
@PortForward
@ArquillianResource
URL url;
@Test
public void testRunningPodStaysUp() throws Exception {
assertThat(client).deployments().pods().isPodReadyForPeriod();
}
}
55
Kubernetes Client
URL to Access Service
AssertJ Custom Assertions
@alexsotob56
Persistence Tests
@alexsotob
First attempt
@Test
public void should_find_composer_by_name() {
// Given:
clearDatabase(jdbcUri);
insertComposersData(jdbcUri);
ComposersRepository composersRepository = new ComposersRepository();
// When:
Composer mozart = composersRepository.findComposerByName("Wolfgang Amadeus Mozart");
// Then:
assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName);
}
57
Prepare Database
Execute Query
@alexsotob58
APE
@alexsotob
APE SQL example
@Rule
public ArquillianPersistenceRule arquillianPersistenceRule =
new ArquillianPersistenceRule();
@DbUnit
@ArquillianResource
RdbmsPopulator rdbmsPopulator;
@Before
public void populateData() {
// Given:
rdbmsPopulator.forUri(jdbcUri).withDriver(Driver.class).withUsername("sa")
.withPassword("").usingDataSet("composers.yml")
.execute();
}
59
APE JUnit Rule
(not necessary with
Arquillian Runner)
Set DBUnit usage
ConïŹgure Connection and Dataset
Populate
composers:
- id: 1
name: Wolfgang Amadeus Mozart
birthdate: 27/1/1756
died: 5/12/1791
@alexsotob
APE SQL example
@After
public void clean_database() {
// Given:
rdbmsPopulator.forUri(jdbcUri).withDriver(Driver.class).withUsername("sa")
.withPassword("").usingDataSet("composers.yml")
.clean();
}
60
Clean After Test
Clean Database
@alexsotob61
DEMO
@alexsotob62
Benefits of Arquillian APE
> Boilerplate Code
> Programmatic/Declarative
@UsingDataSet/@ShouldMatchDataSet
> SQL Support
DBUnit and Flyway
> RESTAPI Support
Postman Collections
> NoSQL Support
MongoDB, Couchbase, CouchDB, Vault, Redis, InïŹnispan
@alexsotob63
Visual Testing
@alexsotob
Selenium
64
@alexsotob
Arquillian Drone
65
@alexsotob
Arquillian Drone example
@RunWith(Arquillian.class)
public class LoginScreenTest {
@Drone
private WebDriver browser;
@Test
public void should_login_user() {
driver.get("www.mypage.com/login");
driver.findElement(By.id("loginForm:login")).click();
}
}
66
Arquillian Runner
Injection of WebDriver instance
@alexsotob
Arquillian Graphene
67
@alexsotob
Arquillian Graphene Page Object example
@Location("login.xhtml")
public class HomePage {
@Page
private UserPage userPage;
@FindBy(id = "submit")
private WebElement submitButton;
@FindBy(id = "form")
private LoginPopup loginPopup;
// methods
}
68
Location of the page
Another Page Object
Find web element by id
Page fragment
@alexsotob
Arquillian Graphene example
@RunWith(Arquillian.class)
public class LoginTest {
@Drone
WebDriver webDriver;
@Test
public void should_create_a_new_speaker(@InitialPage HomePage homePage) {
homePage.login("username", "pasword");
}
}
69
Open given page
Use Page Object method
@alexsotob70
Docker and Selenium
@alexsotob71
DEMO
@alexsotob72
Benefits of Graphene
> Reduces ConïŹguration Code
> Page Object pattern
With extra features like AJAX-enabled, fragments, JQuery expressions
> Docker integration
Multiple versions, multiple browsers, recording
@alexsotob73
Speeding Test Execution
@alexsotob74
Production Sources Tests
https://martinfowler.com/articles/rise-test-impact-analysis.html
@alexsotob
Smart Testing Maven Extension
curl -sSL https://git.io/v5jy6 | bash
75
Installs extension
mvn clean test -Dsmart.testing="new, changed, affected"
Runs only new, changed and prod related tests
mvn clean test -Dsmart.testing.mode=ordering -Dsmart.testing="new, changed, affected”
Prioritize new, changed and prod related tests
@alexsotob76
DEMO
@alexsotob77
More about Smart Testing
> Heuristics
new, changed, affected, failed and categorized
> Range of Commits
DeïŹne where you want to look at
> ConïŹguration
System Properties or YAML ïŹle (global or per module)
> Jenkins Pipeline Shared Library
Integrate with your CI/CD pipeline
> Detection of none class changes
@WatchFile("src/main/resources/META-INF/
> SureïŹre based
Works with any kind of test that can be run in SureïŹre
https://developers.redhat.com/
@alexsotob
asotobue@redhat.com

Weitere Àhnliche Inhalte

Was ist angesagt?

201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programingwahyuseptiansyah
 
TDOH x 揰科 pwnèȘČ繋
TDOH x 揰科 pwnèȘČ繋TDOH x 揰科 pwnèȘČ繋
TDOH x 揰科 pwnèȘČ繋Weber Tsai
 
ES6 in Production [JSConfUY2015]
ES6 in Production [JSConfUY2015]ES6 in Production [JSConfUY2015]
ES6 in Production [JSConfUY2015]Guillermo Paz
 
Celluloid - Beyond Sidekiq
Celluloid - Beyond SidekiqCelluloid - Beyond Sidekiq
Celluloid - Beyond SidekiqMarcelo Pinheiro
 
20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš
20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš
20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒšHiroki Mizuno
 
Live Updating Swift Code
Live Updating Swift CodeLive Updating Swift Code
Live Updating Swift CodeBartosz Polaczyk
 
festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...
festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...
festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...festival ICT 2016
 
Unit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon GaliciaUnit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon GaliciaRobot Media
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Anton Arhipov
 
Javascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyJavascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyThorsten Suckow-Homberg
 
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionDEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionFelipe Prado
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival GuideGiordano Scalzo
 
ć°ç§‘é€†ć‘ç°Ąć ±
ć°ç§‘é€†ć‘ç°Ąć ±ć°ç§‘é€†ć‘ç°Ąć ±
ć°ç§‘é€†ć‘ç°Ąć ±è€€ćŸ· è”Ą
 
G*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIII
G*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIIIG*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIII
G*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIIITakuma Watabiki
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
Stop Monkeys Fall
Stop Monkeys FallStop Monkeys Fall
Stop Monkeys FallHajime Morrita
 

Was ist angesagt? (20)

201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing
 
TDOH x 揰科 pwnèȘČ繋
TDOH x 揰科 pwnèȘČ繋TDOH x 揰科 pwnèȘČ繋
TDOH x 揰科 pwnèȘČ繋
 
ES6 in Production [JSConfUY2015]
ES6 in Production [JSConfUY2015]ES6 in Production [JSConfUY2015]
ES6 in Production [JSConfUY2015]
 
Celluloid - Beyond Sidekiq
Celluloid - Beyond SidekiqCelluloid - Beyond Sidekiq
Celluloid - Beyond Sidekiq
 
20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš
20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš
20110424 action scriptă‚’äœżă‚ăȘいflashć‹‰ćŒ·äŒš
 
NAGARAVEEKSHANAM
NAGARAVEEKSHANAMNAGARAVEEKSHANAM
NAGARAVEEKSHANAM
 
Live Updating Swift Code
Live Updating Swift CodeLive Updating Swift Code
Live Updating Swift Code
 
festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...
festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...
festival ICT 2013: Solid as diamond: use ruby in an web application penetrati...
 
Pdr ppt
Pdr pptPdr ppt
Pdr ppt
 
Botsing demo
Botsing demoBotsing demo
Botsing demo
 
Unit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon GaliciaUnit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon Galicia
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
Javascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyJavascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the Ugly
 
Ecma script 5
Ecma script 5Ecma script 5
Ecma script 5
 
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destructionDEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
DEF CON 27 - PATRICK WARDLE - harnessing weapons of Mac destruction
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival Guide
 
ć°ç§‘é€†ć‘ç°Ąć ±
ć°ç§‘é€†ć‘ç°Ąć ±ć°ç§‘é€†ć‘ç°Ąć ±
ć°ç§‘é€†ć‘ç°Ąć ±
 
G*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIII
G*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIIIG*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIII
G*ă«ăŠă‘ă‚‹ă‚œăƒ•ăƒˆă‚Šă‚§ă‚ąăƒ†ă‚čăƒˆăƒ»ă‚·ăƒŒă‚șンIII
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
Stop Monkeys Fall
Stop Monkeys FallStop Monkeys Fall
Stop Monkeys Fall
 

Ähnlich wie 10 Testing libraries any Java developer should know

Testing For Unicorns [IMWorld]
Testing For Unicorns [IMWorld] Testing For Unicorns [IMWorld]
Testing For Unicorns [IMWorld] Alex Soto
 
Testing Java Microservices Devoxx be 2017
Testing Java Microservices Devoxx be 2017Testing Java Microservices Devoxx be 2017
Testing Java Microservices Devoxx be 2017Alex Soto
 
wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?Scott Leberknight
 
AST Transformations
AST TransformationsAST Transformations
AST TransformationsHamletDRC
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Expression trees in c#
Expression trees in c#Expression trees in c#
Expression trees in c#Oleksii Holub
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!Aaron Patterson
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6Solution4Future
 
Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)
Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)
Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)Alina Vilk
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptCaridy Patino
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian ConstellationAlex Soto
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macrosunivalence
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokusHamletDRC
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowViliam Elischer
 

Ähnlich wie 10 Testing libraries any Java developer should know (20)

Testing For Unicorns [IMWorld]
Testing For Unicorns [IMWorld] Testing For Unicorns [IMWorld]
Testing For Unicorns [IMWorld]
 
Testing Java Microservices Devoxx be 2017
Testing Java Microservices Devoxx be 2017Testing Java Microservices Devoxx be 2017
Testing Java Microservices Devoxx be 2017
 
wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Unfiltered Unveiled
Unfiltered UnveiledUnfiltered Unveiled
Unfiltered Unveiled
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Expression trees in c#
Expression trees in c#Expression trees in c#
Expression trees in c#
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)
Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)
Expression trees in c#, АлДĐșсДĐč Đ“ĐŸĐ»ŃƒĐ±ŃŒ (Svitla Systems)
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScript
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian Constellation
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macros
 
Jasmine BDD for Javascript
Jasmine BDD for JavascriptJasmine BDD for Javascript
Jasmine BDD for Javascript
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrow
 

Mehr von Alex Soto

Kubernetes Native Java
Kubernetes Native JavaKubernetes Native Java
Kubernetes Native JavaAlex Soto
 
Reactive Programming for Real Use Cases
Reactive Programming for Real Use CasesReactive Programming for Real Use Cases
Reactive Programming for Real Use CasesAlex Soto
 
Chaos Engineering Kubernetes
Chaos Engineering KubernetesChaos Engineering Kubernetes
Chaos Engineering KubernetesAlex Soto
 
Chaos Engineering Kubernetes
Chaos Engineering KubernetesChaos Engineering Kubernetes
Chaos Engineering KubernetesAlex Soto
 
Microservices testing and automation
Microservices testing and automationMicroservices testing and automation
Microservices testing and automationAlex Soto
 
Testing in Production: From DevTestOops to DevTestOps
Testing in Production: From DevTestOops to DevTestOpsTesting in Production: From DevTestOops to DevTestOps
Testing in Production: From DevTestOops to DevTestOpsAlex Soto
 
Supersonic Subatomic Java
Supersonic Subatomic JavaSupersonic Subatomic Java
Supersonic Subatomic JavaAlex Soto
 
From DevTestOops to DevTestOps
From DevTestOops to DevTestOpsFrom DevTestOops to DevTestOps
From DevTestOops to DevTestOpsAlex Soto
 
Istio service mesh & pragmatic microservices architecture
Istio service mesh & pragmatic microservices architectureIstio service mesh & pragmatic microservices architecture
Istio service mesh & pragmatic microservices architectureAlex Soto
 
Zero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices eraZero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices eraAlex Soto
 
Service Mesh Patterns
Service Mesh PatternsService Mesh Patterns
Service Mesh PatternsAlex Soto
 
Supersonic, Subatomic Java
Supersonic, Subatomic JavaSupersonic, Subatomic Java
Supersonic, Subatomic JavaAlex Soto
 
Zero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices eraZero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices eraAlex Soto
 
Long Live and Prosper To Monolith
Long Live and Prosper To MonolithLong Live and Prosper To Monolith
Long Live and Prosper To MonolithAlex Soto
 
Sail in the cloud - An intro to Istio commit
Sail in the cloud - An intro to Istio commitSail in the cloud - An intro to Istio commit
Sail in the cloud - An intro to Istio commitAlex Soto
 
KubeBoot - Spring Boot deployment on Kubernetes
KubeBoot - Spring Boot deployment on KubernetesKubeBoot - Spring Boot deployment on Kubernetes
KubeBoot - Spring Boot deployment on KubernetesAlex Soto
 
Sail in the Cloud - An intro to Istio
Sail in the Cloud  - An intro to IstioSail in the Cloud  - An intro to Istio
Sail in the Cloud - An intro to IstioAlex Soto
 
Testing XXIst Century
Testing XXIst CenturyTesting XXIst Century
Testing XXIst CenturyAlex Soto
 
Live Long and Prosper to Monolith
Live Long and Prosper to MonolithLive Long and Prosper to Monolith
Live Long and Prosper to MonolithAlex Soto
 
Testing in the 21st Century (ExpoQA)
Testing in the 21st Century (ExpoQA)Testing in the 21st Century (ExpoQA)
Testing in the 21st Century (ExpoQA)Alex Soto
 

Mehr von Alex Soto (20)

Kubernetes Native Java
Kubernetes Native JavaKubernetes Native Java
Kubernetes Native Java
 
Reactive Programming for Real Use Cases
Reactive Programming for Real Use CasesReactive Programming for Real Use Cases
Reactive Programming for Real Use Cases
 
Chaos Engineering Kubernetes
Chaos Engineering KubernetesChaos Engineering Kubernetes
Chaos Engineering Kubernetes
 
Chaos Engineering Kubernetes
Chaos Engineering KubernetesChaos Engineering Kubernetes
Chaos Engineering Kubernetes
 
Microservices testing and automation
Microservices testing and automationMicroservices testing and automation
Microservices testing and automation
 
Testing in Production: From DevTestOops to DevTestOps
Testing in Production: From DevTestOops to DevTestOpsTesting in Production: From DevTestOops to DevTestOps
Testing in Production: From DevTestOops to DevTestOps
 
Supersonic Subatomic Java
Supersonic Subatomic JavaSupersonic Subatomic Java
Supersonic Subatomic Java
 
From DevTestOops to DevTestOps
From DevTestOops to DevTestOpsFrom DevTestOops to DevTestOps
From DevTestOops to DevTestOps
 
Istio service mesh & pragmatic microservices architecture
Istio service mesh & pragmatic microservices architectureIstio service mesh & pragmatic microservices architecture
Istio service mesh & pragmatic microservices architecture
 
Zero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices eraZero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices era
 
Service Mesh Patterns
Service Mesh PatternsService Mesh Patterns
Service Mesh Patterns
 
Supersonic, Subatomic Java
Supersonic, Subatomic JavaSupersonic, Subatomic Java
Supersonic, Subatomic Java
 
Zero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices eraZero Downtime Deployment in Microservices era
Zero Downtime Deployment in Microservices era
 
Long Live and Prosper To Monolith
Long Live and Prosper To MonolithLong Live and Prosper To Monolith
Long Live and Prosper To Monolith
 
Sail in the cloud - An intro to Istio commit
Sail in the cloud - An intro to Istio commitSail in the cloud - An intro to Istio commit
Sail in the cloud - An intro to Istio commit
 
KubeBoot - Spring Boot deployment on Kubernetes
KubeBoot - Spring Boot deployment on KubernetesKubeBoot - Spring Boot deployment on Kubernetes
KubeBoot - Spring Boot deployment on Kubernetes
 
Sail in the Cloud - An intro to Istio
Sail in the Cloud  - An intro to IstioSail in the Cloud  - An intro to Istio
Sail in the Cloud - An intro to Istio
 
Testing XXIst Century
Testing XXIst CenturyTesting XXIst Century
Testing XXIst Century
 
Live Long and Prosper to Monolith
Live Long and Prosper to MonolithLive Long and Prosper to Monolith
Live Long and Prosper to Monolith
 
Testing in the 21st Century (ExpoQA)
Testing in the 21st Century (ExpoQA)Testing in the 21st Century (ExpoQA)
Testing in the 21st Century (ExpoQA)
 

KĂŒrzlich hochgeladen

Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

KĂŒrzlich hochgeladen (20)

Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Call Girls In Mukherjee Nagar đŸ“± 9999965857 đŸ€© Delhi đŸ«Š HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar đŸ“±  9999965857  đŸ€© Delhi đŸ«Š HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar đŸ“±  9999965857  đŸ€© Delhi đŸ«Š HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar đŸ“± 9999965857 đŸ€© Delhi đŸ«Š HOT AND SEXY VVIP 🍎 SE...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Vip Call Girls Noida âžĄïž Delhi âžĄïž 9999965857 No Advance 24HRS Live
Vip Call Girls Noida âžĄïž Delhi âžĄïž 9999965857 No Advance 24HRS LiveVip Call Girls Noida âžĄïž Delhi âžĄïž 9999965857 No Advance 24HRS Live
Vip Call Girls Noida âžĄïž Delhi âžĄïž 9999965857 No Advance 24HRS Live
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

10 Testing libraries any Java developer should know

  • 1. 10 Testing libraries any Java developer should know Alex Soto‹ Red Hat Engineer‹ @alexsotob
  • 2. @alexsotob2 Alex Soto Red Hat Engineer www.lordofthejars.com @alexsotob Who Am I?
  • 6. @alexsotob JUnit Test @Test public void should_find_composer_by_name() { // Given: Composers composers = new Composers(); // When: final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart"); // Then: assertEquals("Wolfgang Amadeus Mozart", mozart.getName()); assertEquals(Era.CLASSICAL, mozart.getEra()); assertEquals(LocalDate.of(1756, 1, 27), mozart.getBirthdate()); assertEquals(LocalDate.of(1791, 12, 5), mozart.getDied()); } 6 Readable name BDD style AssertEquals Order Depends On Equals
  • 8. @alexsotob AssertJ Test import static org.assertj.core.api.Assertions.assertThat; @Test public void should_find_composer_by_name() { // Given: Composers composers = new Composers(); // When: final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart”); // Then: assertThat(mozart.getName()).isEqualTo("Wolfgang Amadeus Mozart”); assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName); assertThat(mozart.getBirthdate()).isEqualTo(LocalDate.of(1756, 1, 27)); assertThat(mozart).isEqualToComparingFieldByField(expectedMozart); assertThat(mozart).isEqualToIgnoringNullFields(expectedMozart); } 8 Static Import Readable Assertions Not Depending on Equals
  • 9. @alexsotob AssertJ Test Collections @Test public void should_find_operas_by_composer_name() { // Given: Composers composers = new Composers(); // When: final List<Opera> operas = composers.findOperasByComposerName("Wolfgang Amadeus Mozart"); // Then: assertThat(operas) .hasSize(2) .extracting(Opera::getName) .containsExactlyInAnyOrder("Die Zauberflöte", "Don Giovanni”); } 9 Train Call (IDE support) Create List with getName Result Methods for String
  • 10. @alexsotob AssertJ Soft Assertions @Test public void should_find_composer_by_name_soft_assertions() { // Given: Composers composers = new Composers(); // When: final Composer mozart = composers.findComposerByName("Wolfgang Amadeus Mozart"); // Then: SoftAssertions.assertSoftly(softly -> { softly.assertThat(mozart.getName()).isEqualTo("Wolfgang Amadeus Mozart"); softly.assertThat(mozart.getEra()).isEqualTo(Era.CLASSICAL); softly.assertThat(mozart.getBirthdate()).isEqualTo(LocalDate.of(1756, 1, 27)); softly.assertThat(mozart.getDied()).isEqualTo(LocalDate.of(1791, 12, 5)); }); } 10 Java 8 Lambda All assertions in Block
  • 12. @alexsotob Try/Catch @Test public void should_throw_exception_if_composer_not_found() { // Given: Composers composers = new Composers(); // When: try { final Composer salieri = composers.findComposerByName("Antonio Salieri"); fail(); } catch (IllegalArgumentException e) { // Then: assertEquals("Composer Antonio Salieri is not found", e.getMessage()); } } 12 Fails if Success
  • 13. @alexsotob JUnit @Test(expected = IllegalArgumentException.class) public void should_throw_exception_if_composer_not_found_version_2() { // Given: Composers composers = new Composers(); // When: final Composer salieri = composers.findComposerByName("Antonio Salieri"); } 13 Special Attribute
  • 14. @alexsotob AssertJ Exceptions @Test public void should_throw_exception_if_composer_not_found_version_3() { // Given: Composers composers = new Composers(); // When: Throwable thrown = catchThrowable(() -> composers.findComposerByName("Antonio Salieri")); // Then: assertThat(thrown).isInstanceOf(IllegalArgumentException.class) .withFailMessage("Composer Antonio Salieri is not found”); } 14 Catch Exception of Lambda Assertion Methods for Exceptions
  • 16. @alexsotob16 Benefits of AssertJ > IDE Friendly Ctrl + Space works > Assertions Generation ComposerAssert.assertThat(mozart).hasName(“Mozart”).hasBirthdate(LocalDate.of(..); > Out-of-the-Box Assertions Guava, Joda, DB, Neo4j and Swing
  • 18. @alexsotob Asynchronous Call @Test public void should_play_operas() throws InterruptedException { // Given: final Opera nozzeDiFigaro = ...; Gramophone gramophone = new Gramophone(); // When: gramophone.play(nozzeDiFigaro); // Then: TimeUnit.SECONDS.sleep(3); assertThat(gramophone.getCurrentOpera()).isEqualTo(nozzeDiFigaro); } 18 Asynchronous Call Slowest Machine Time
  • 20. @alexsotob Awaitility Example @Test public void should_play_operas_version_2() { // Given: final Opera nozzeDiFigaro = Composers.OperaFactory .createOpera("Le Nozze di Figaro") .language(Language.ITALIAN).librettist("Lorenzo Da Ponte") .roles("Count Almaviva", "Countess Rosina", "Susanna", "Figaro") .build(); Gramophone gramophone = new Gramophone(); // When: gramophone.play(nozzeDiFigaro); // Then: await().atMost(5, TimeUnit.SECONDS).until(gramophone::isPlaying); assertThat(gramophone.getCurrentOpera()).isEqualTo(nozzeDiFigaro); } 20 Asynchronous Call Polls until True or Timeout
  • 22. @alexsotob22 Benefits of Awaitility > Deadlock Detection > Different Pollings Fixed, Fibonacci, Iterative, Custom > Simple Library No dependencies, No magic
  • 24. @alexsotob GET /Ludwig+van+Beethoven { "name": "Ludwig van Beethoven", "era": "ROMANTIC", "birthdate": {}, "died": {}, "operas": [ { "name": "Fidelio", "librettist": "Georg Friedrich Treitschke", "language": "GERMAN", "roles": ["Rocco", "Leonore", "Florestan"] } ] } 24 Simple Objects Array of Objects
  • 25. @alexsotob HttpClient Example @Test public void should_find_composer() throws IOException, URISyntaxException { // Given: URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/"); uriBuilder.setPath("Ludwig van Beethoven"); // When: final Content bodyContent = Request.Get(uriBuilder.build()) .execute().returnContent(); String body = bodyContent.asString(); // Then: assertThat(body).contains(""name":"Ludwig van Beethoven"") .contains(""librettist":"Georg Friedrich Treitschke""); } 25 Prepare Connection Do connection Get content Manipulate String
  • 26. @alexsotob WebDriver Example // Given: WebDriver browser = new FirefoxDriver(); URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/"); uriBuilder.setPath("Ludwig van Beethoven"); // When: browser.navigate().to(uriBuilder.build()); // Then: assertThat(browser.getPageSource()).contains(""name":"Ludwig van Beethoven""); 26
  • 28. @alexsotob REST-assured Example @Test public void should_find_composer() { given() .when() .get("{composer}", "Ludwig van Beethoven") .then() .assertThat() .body("name", is("Ludwig van Beethoven")) .body("operas.size()", is(1)) .body("operas.name", hasItems("Fidelio")); } 28 GET Http Method with Placeholders GPath Expression
  • 29. @alexsotob REST-assured Example @Test public void should_insert_composer() { Composer composer = ....; given() .param("parameter1", "parameterValue") .body(composer) .when() .post() .then() .assertThat() .statusCode(201); } 29 Create POJO object Set Params Set POJO as Body POST Http Method Assertion on Status Code
  • 30. @alexsotob REST-assured Request Logging given().log().all(). .. // Log all request specification details given().log().params(). .. // Log only the parameters of the request given().log().body(). .. // Log only the request body given().log().headers(). .. // Log only the request headers given().log().cookies(). .. // Log only the request cookies given().log().method(). .. // Log only the request method given().log().path(). .. // Log only the request path 30
  • 32. @alexsotob REST-assured Request SpeciïŹcation .get("http://example.com/{composer}", "Ludwig van Beethoven") RequestSpecBuilder builder = new RequestSpecBuilder(); builder.setBaseUri("http://example.com"); given().spec(builder.build())... 32 Use domain directly Use Spec Builder Reuse Everywhere
  • 33. @alexsotob REST-assured Auth given().auth().oauth2(accessToken).when()... given().auth().form("John", "Doe", springSecurity().withCsrfFieldName("_csrf")).when()... given().auth().basic("username", "password").when()... 33
  • 35. @alexsotob35 More Features of Rest-Assured > Custom Parsers Not just JSON and XML > SSL Support .relaxedHTTPSValidation() > Filters Input/Output modiïŹcation > JSON Schema Validation Content not Important
  • 37. @alexsotob Service Virtualization Capture Mode 37 Service A External Network Service B Scripts Proxy
  • 38. @alexsotob Service Virtualization Simulate Mode 38 Service A External Network Service B Scripts Proxy
  • 40. @alexsotob HoverïŹ‚y Example @ClassRule public static HoverflyRule hoverflyRule = HoverflyRule.inCaptureOrSimulationMode("getcomposers.json"); @Test public void should_get_composers_from_composers_microservice() { // Given: ComposersGateway composersGateway = new ComposersGateway("operas.com", 8081); // When: Composer composer = composersGateway.getComposer("Ludwig van Beethoven"); // Then: assertThat(composer.getName()).isEqualTo("Ludwig van Beethoven"); } 40 Start HoverïŹ‚y Use Real Host Get Data from Real { "data" : { "pairs" : [{ "request" : { "path" : "/Ludwig van Beethoven", "method" : "GET", "destination" : “operas.com:8081", ... } "response" : { "status" : 200, "body" : "{"name":"Ludwig van Beethoven",}", "encodedBody" : false, "headers" : { "Connection" : [ "keep-alive" ], ... } } } } Get Data from Proxy
  • 41. @alexsotob HoverïŹ‚y Example Simulate private static String RESPONSE = "[n" + " {n" + " "name": "Moon",n" + " "villain": "Gru",n" + " "wiki": "https://en.wikipedia.org/wiki/Moon"n" + " } + "]"; @ClassRule public static HoverflyRule hoverflyRule = HoverflyRule.inSimulationMode(dsl( service("crimesdb:8080") .get("/crimes/Gru") .willReturn(success(RESPONSE, "application/json")) 41 Hardcoded response Starts in simulate Host Program interactions
  • 42. @alexsotob42 Benefits of Service Virtualization and Hoverfly > Do not relay on network Yet testing all stack trace > HoverïŹ‚y multilanguage Can be used as standalone proxy > HoverïŹ‚y JVM Integration with JVM proxy settings
  • 45. @alexsotob45 @RunWith(Arquillian.class) public class CrimesConsumerContractTest { @StubServer URL pactServer; @Pact(provider = "crimes", consumer = "villains") public RequestResponsePact returnListOfCrimes(PactDslWithProvider builder) { return builder .uponReceiving("Gru villain to get all Crimes") .path("/crimes/Gru") .method("GET") .willRespondWith() .status(200) .body(RESPONSE) .toPact(); } @Test @PactVerification("crimes") public void should_get_list_of_crimes_by_villain() { CrimesGateway crimesGateway = new CrimesGateway(webClient, pactServer); final Single<JsonArray> gruCrimes = crimesGateway.getCrimesByVillainName("Gru"); } Stub/proxy Server URL DeïŹnes service interaction Provides predeïŹned Req/Res Executes real requests Consumer side
  • 46. @alexsotob46 @RunWith(Arquillian.class) @Provider("crimes") @ContractsFolder("~/crimescontract") public class CrimesContractTest { @ArquillianResource Target target; @Test public void should_validate_contract() { assertThat(target).withUrl(getCrimesServer()).satisfiesContract(); } } Provider under validation Location of contracts Http Client Asserts All Interactions are correct Provider side
  • 48. @alexsotob48 Benefits of CDC and Pact > Pact Foundation Pact speciïŹcation v3 > Integration with several languages JVM, Ruby, Python, Go, .Net, Swift, JS > Pact Broker Sharing contracts, API documentation, Overview of services > Arquillian Algeron Arquillian ecosystem + Pact, Publishers/Retrievers, JBoss Forge > Consumer Driven Contracts Fail fast Independent deployments Improve communication
  • 50. @alexsotob Testing Containers docker build -t myorg/myservice:1.0.0 . docker run --rm -ti -p 8080:8080 myorg/myservice:1.0.0 docker-compose up mvn clean test docker-compose stop 50 Docker Run Docker Compose Run Run tests Stop Docker Containers
  • 52. @alexsotob Arquillian Cube Example @RunWith(Arquillian.class) public class HelloWorldTest { @ArquillianResource @DockerUrl(containerName = "helloworld", exposedPort = 8080) RequestSpecBuilder requestSpecBuilder; @Test public void should_receive_ok_message() { RestAssured .given() .spec(requestSpecBuilder.build()) .when() .get() .then() .assertThat().body("status", equalTo("OK")); } } 52 Arquillian Runner REST-Assured Integration Environment Resolver Normal REST-Assured Call helloworld: image: jonmorehouse/ping-pong ports: - "8080:8080" src/test/docker/docker-compose.yml
  • 53. @alexsotob Arquillian Cube DSL @RunWith(SpringRunner.class) @SpringBootTest(classes = PingPongController.class, webEnvironment = RANDOM_PORT) @ContextConfiguration(initializers = PingPongSpringBootTest.Initializer.class) public class PingPongSpringBootTest { @ClassRule public static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6") .withPortBinding(6379); @Autowired TestRestTemplate restTemplate; @Test public void should_get_data_from_redis() { } 53 Spring Boot Test Custom Initializer Container DeïŹnition public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { EnvironmentTestUtils.addEnvironment("testcontainers", configurableApplicationContext.getEnvironment(), "spring.redis.host=" + redis.getIpAddress(), "spring.redis.port=" + redis.getBindPort(6379) ); Sets Container Environment
  • 55. @alexsotob Arquillian Kube @RunWith(Arquillian.class) public class HelloWorldTest { @ArquillianResource KubernetesClient client; @Named(“hello-world-service") @PortForward @ArquillianResource URL url; @Test public void testRunningPodStaysUp() throws Exception { assertThat(client).deployments().pods().isPodReadyForPeriod(); } } 55 Kubernetes Client URL to Access Service AssertJ Custom Assertions
  • 57. @alexsotob First attempt @Test public void should_find_composer_by_name() { // Given: clearDatabase(jdbcUri); insertComposersData(jdbcUri); ComposersRepository composersRepository = new ComposersRepository(); // When: Composer mozart = composersRepository.findComposerByName("Wolfgang Amadeus Mozart"); // Then: assertThat(mozart).returns("Wolfgang Amadeus Mozart", Composer::getName); } 57 Prepare Database Execute Query
  • 59. @alexsotob APE SQL example @Rule public ArquillianPersistenceRule arquillianPersistenceRule = new ArquillianPersistenceRule(); @DbUnit @ArquillianResource RdbmsPopulator rdbmsPopulator; @Before public void populateData() { // Given: rdbmsPopulator.forUri(jdbcUri).withDriver(Driver.class).withUsername("sa") .withPassword("").usingDataSet("composers.yml") .execute(); } 59 APE JUnit Rule (not necessary with Arquillian Runner) Set DBUnit usage ConïŹgure Connection and Dataset Populate composers: - id: 1 name: Wolfgang Amadeus Mozart birthdate: 27/1/1756 died: 5/12/1791
  • 60. @alexsotob APE SQL example @After public void clean_database() { // Given: rdbmsPopulator.forUri(jdbcUri).withDriver(Driver.class).withUsername("sa") .withPassword("").usingDataSet("composers.yml") .clean(); } 60 Clean After Test Clean Database
  • 62. @alexsotob62 Benefits of Arquillian APE > Boilerplate Code > Programmatic/Declarative @UsingDataSet/@ShouldMatchDataSet > SQL Support DBUnit and Flyway > RESTAPI Support Postman Collections > NoSQL Support MongoDB, Couchbase, CouchDB, Vault, Redis, InïŹnispan
  • 66. @alexsotob Arquillian Drone example @RunWith(Arquillian.class) public class LoginScreenTest { @Drone private WebDriver browser; @Test public void should_login_user() { driver.get("www.mypage.com/login"); driver.findElement(By.id("loginForm:login")).click(); } } 66 Arquillian Runner Injection of WebDriver instance
  • 68. @alexsotob Arquillian Graphene Page Object example @Location("login.xhtml") public class HomePage { @Page private UserPage userPage; @FindBy(id = "submit") private WebElement submitButton; @FindBy(id = "form") private LoginPopup loginPopup; // methods } 68 Location of the page Another Page Object Find web element by id Page fragment
  • 69. @alexsotob Arquillian Graphene example @RunWith(Arquillian.class) public class LoginTest { @Drone WebDriver webDriver; @Test public void should_create_a_new_speaker(@InitialPage HomePage homePage) { homePage.login("username", "pasword"); } } 69 Open given page Use Page Object method
  • 72. @alexsotob72 Benefits of Graphene > Reduces ConïŹguration Code > Page Object pattern With extra features like AJAX-enabled, fragments, JQuery expressions > Docker integration Multiple versions, multiple browsers, recording
  • 75. @alexsotob Smart Testing Maven Extension curl -sSL https://git.io/v5jy6 | bash 75 Installs extension mvn clean test -Dsmart.testing="new, changed, affected" Runs only new, changed and prod related tests mvn clean test -Dsmart.testing.mode=ordering -Dsmart.testing="new, changed, affected” Prioritize new, changed and prod related tests
  • 77. @alexsotob77 More about Smart Testing > Heuristics new, changed, affected, failed and categorized > Range of Commits DeïŹne where you want to look at > ConïŹguration System Properties or YAML ïŹle (global or per module) > Jenkins Pipeline Shared Library Integrate with your CI/CD pipeline > Detection of none class changes @WatchFile("src/main/resources/META-INF/ > SureïŹre based Works with any kind of test that can be run in SureïŹre