SlideShare a Scribd company logo
1 of 124
TDD mit Java EE
100% Code Coverage
Schreibst du Unit-Tests?
85% 97%ZeroTurnaround, 2014
2164 Teilnehmer
Hubstaff, 2014
mehrere 100 Teilnehmer
Na klar!
Schreibst du Browser-Tests?
33% 30%ZeroTurnaround, 2014
2164 Teilnehmer
Hubstaff, 2014
mehrere 100 Teilnehmer
Ja!?
ZeroTurnaround, 2014
2164 Teilnehmer
29.0%
41.5%
82.5%
Selenium
Mockito
JUnit
Welche Tools setzt du ein?
Schreibst du gerne Tests?
66% 35%Hubstaff, 2014
mehrere 100 Teilnehmer
Ja Immer
Stefan Macke
Stefan Macke
http://soa.rocks
Stefan Macke
http://soa.rocks
@StefanMacke
Stefan Macke
http://soa.rocks
anwendungsentwickler
podcast.de
@StefanMacke
JSF
JPA
Bean
Validation
JAX-RS
REST
Allgemeines
https://github.com/StefanMacke/javaeetests
System
Integration
Unit
100%
62%
71%
72%
Geschäftslogik
http://junit.org/
sut = new UserName("validusername");
„system under test“
http://joel-costigliola.github.io/assertj/
AssertJ
assertThat(
new Password("AsdfFdsa").getValue())
.startsWith("Asdf")
.endsWith("Fdsa")
.isEqualTo("AsdfFdsa");
https://github.com/orien/bean-matchers
BeanMatchers
assertThat(Article.class, allOf(
hasValidBeanConstructor(),
hasValidGettersAndSetters(),
hasValidBeanHashCode(),
hasValidBeanEquals(),
hasValidBeanToString()));
public class User {
@NotNull(message="User name may not be null")
private UserName userName;
@Size(min=1, message="Password too short")
private Password password;
Validator validator =
Validation.buildDefaultValidatorFactory()
.getValidator();
Set<ConstraintViolation<User>> constraintViolations =
validator.validate(sut);
assertThat(constraintViolations.size(), is(3));
http://hibernate.org/validator/
sut = new UserService();
userRepository = mock(UserRepository.class);
sut.userRepository = userRepository;
when(userRepository.findByUserName(USER_NAME))
.thenReturn(Optional.empty());
assertThat(sut.isValidUser(USER_NAME, PASSWORD),
is(false));
http://mockito.org/
public class UserService {
@Inject
UserRepository userRepository;
mockStatic(Salt.class);
when(Salt.generate()).thenReturn(
new Salt("asdfasdf"));
User user = sut.createUser(...);
assertThat(user.getSalt().getValue(),
is("asdfasdf"));
https://github.com/powermock/powermock
public void notifyAdminWhenUserIsCreated() {
sut.createUser(USER_NAME, PASSWORD);
verify(mailService)
.notifyAdmin("New user created.");
http://mockito.org/
logger = mock(Logger.class);
sut.logger = logger;
Persistenz
%
em = mock(EntityManager.class);
query = mock(TypedQuery.class);
sut = new JpaUserRepository(em);
private void givenTheUserDoesNotExist() {
when(query.getSingleResult())
.thenThrow(NoResultException.class);
when(em.createQuery(
any(String.class), eq(User.class)))
.thenReturn(query);
givenTheUserDoesNotExist();
Optional<User> result =
sut.findByUserName("nonexistinguser");
assertThat(result.isPresent(), is(false));
@Entity(name = "Users")
public class User {
@Id
@GeneratedValue
private long id;
private UserName userName;
Datenbank JPA
http://www.eclipse.org/eclipselink/https://db.apache.org/derby/
<persistence-unit name="IntegrationTest">
<properties>
<property name="target-database" value="Derby" />
<property name="url"
value="jdbc:derby:./Test.db;create=true" />
<property name="ddl-generation"
value="drop-and-create-tables" />
src/integrationTest/resources/META-INF/persistence.xml
@BeforeAll
public static void setupClass() {
EntityManager em = getEntityManager();
EntityTransaction t = em.getTransaction();
t.begin();
new TestDataCreator().createTestData(em);
t.commit();
public void createTestData(EntityManager em) {
User user = TestData.validUser();
em.persist(user);
}
sut = new JpaUserRepository(getEntityManager());
User expectedUser = TestData.validUser();
User actualUser = sut.findByUserName(...);
assertThat(actualUser, is(expectedUser)),
Controller
public String logout() {
facesContext.addMessage(null,
new FacesMessage(
FacesMessage.SEVERITY_INFO,
"Goodbye!", null));
return INDEX_PAGE;
facesContext = mock(FacesContext.class);
sut.facesContext = facesContext;
final String targetPage = sut.logout();
assertThat(targetPage, is(LoginController.INDEX_PAGE));
verify(facesContext).addMessage(isNull(), message.capture());
assertThat(message.getValue().getDetail(), is("Goodbye!"));
REST-API
sut = new SessionResource();
sut.userService = mock(UserService.class);
givenCredentialsAreInvalid();
assertThat(sut.authenticateUser(credentials),
is(Response.Status.UNAUTHORIZED));
@Path(SessionResource.PATH)
public class SessionResource {
public static String PATH = "/sessions";
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(
@BeforeAll
public static void setupClass() {
JETTY_SERVER = new Server(JETTY_PORT);
JETTY_SERVER.start();
}
@AfterAll
public static void teardownClass() {
JETTY_SERVER.stop();
}
http://www.eclipse.org/jetty/
Response response = ClientBuilder.newClient()
.target(DemoApplication.getRestUrl())
.path("/sessions")
.request(MediaType.APPLICATION_JSON)
.post(Entity.json(validCredentials));
assertThat(response.getStatus(), is(200));
assertThat(response.readEntity(Boolean.class),
is(true));
https://jersey.github.io/
given()
.contentType(ContentType.JSON)
.accept(ContentType.JSON)
.body("{ "userName": "validusername",
"password": "ValidPassword" }")
.when()
.post(DemoApplication.getRestUrl() + "/sessions")
.then()
.statusCode(200)
.body(is("true"));
https://github.com/rest-assured/rest-assured
EE-Container
http://arquillian.org/
arquillian.xml
Chameleon
repo1.maven.org
wildfly:10.0.0:remote
a4d2-f27-91af.war
persistence.xml
TestDataCreator
@Observes
java:/ExampleDS
create-drop
war
H2
IntegrationTest
WebTarget
.../a4d2-f27-91af/
@Test
Frontend
Webdriver
http://www.seleniumhq.org/
Drone und Graphene
http://arquillian.org/modules/drone-extension/ http://arquillian.org/modules/graphene-extension/
public class LoginPage {
static final By LOGIN_BUTTON =
By.id("loginForm:login");
static final By LOGGED_IN =
By.xpath("//h1[contains(text(),'Welcome')]");
public void login(String name, String password) {
driver.get(contextPath + "index.xhtml");
driver.findElement(USERNAME_FIELD).sendKeys(name);
driver.findElement(LOGIN_BUTTON).click();
Externe Services
String json =
"[ {"
+ " "title": "The first title""
+ "} ]";
List<Article> articles = sut.createArticles(json);
assertThat(articles.get(0).getTitle(),
is("The first title"));
public class ArticleService {
static String TARGET_SERVER =
"http://serviceorientedarchitect.com";
static String TARGET_PATH =
"/wp-json/wp/v2/posts";
stubFor(get(urlPathEqualTo("articles"))
.withQueryParam("per_page", equalTo("2"))
.willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("The first title")));
assertThat(first.getTitle(), is("The first title"));
http://wiremock.org/
http://www.citrusframework.org/
Fazit
http://soa.rocks
anwendungsentwickler
podcast.de
@StefanMacke
TDD mit Java EE
100% Code Coverage
StefanMacke/javaeetests

More Related Content

What's hot

PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to heroJeremy Cook
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptRyan Anklam
 
Introduction To Testing With Perl
Introduction To Testing With PerlIntroduction To Testing With Perl
Introduction To Testing With Perljoshua.mcadams
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnitMindfire Solutions
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnitferca_sl
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentationnicobn
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmanndpc
 
for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...hwbloom59
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Java 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR BeneluxJava 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR Beneluxyohanbeschi
 
Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...
Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...
Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...Samuel Nitsche
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski
 
Mutation Testing: Testing your tests
Mutation Testing: Testing your testsMutation Testing: Testing your tests
Mutation Testing: Testing your testsStephen Leigh
 
for this particular program how do i create the input innotepad 1st ?#include...
for this particular program how do i create the input innotepad 1st ?#include...for this particular program how do i create the input innotepad 1st ?#include...
for this particular program how do i create the input innotepad 1st ?#include...hwbloom14
 
The three layers of testing
The three layers of testingThe three layers of testing
The three layers of testingBart Waardenburg
 

What's hot (20)

PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to hero
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Introduction To Testing With Perl
Introduction To Testing With PerlIntroduction To Testing With Perl
Introduction To Testing With Perl
 
Qunit Java script Un
Qunit Java script UnQunit Java script Un
Qunit Java script Un
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnit
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 
for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good Tests
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
 
Java 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR BeneluxJava 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR Benelux
 
Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...
Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...
Oracle Apex Meetup Frankfurt - 03/2020 - Wir haben doch keine Zeit - Pragmati...
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
 
Mutation Testing: Testing your tests
Mutation Testing: Testing your testsMutation Testing: Testing your tests
Mutation Testing: Testing your tests
 
for this particular program how do i create the input innotepad 1st ?#include...
for this particular program how do i create the input innotepad 1st ?#include...for this particular program how do i create the input innotepad 1st ?#include...
for this particular program how do i create the input innotepad 1st ?#include...
 
Java Quiz - Meetup
Java Quiz - MeetupJava Quiz - Meetup
Java Quiz - Meetup
 
The three layers of testing
The three layers of testingThe three layers of testing
The three layers of testing
 

Similar to 100% Code Coverage - TDD mit Java EE

Spring mvc my Faviourite Slide
Spring mvc my Faviourite SlideSpring mvc my Faviourite Slide
Spring mvc my Faviourite SlideDaniel Adenew
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEnterprise PHP Center
 
The secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutThe secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutDror Helper
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean testsDanylenko Max
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
Automated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platformsAutomated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platformsjobandesther
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And DrupalPeter Arato
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testingjeresig
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4jeresig
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonbeITconference
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014Guillaume POTIER
 
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageabilityDaniel Fisher
 
Auto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendAuto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendSven Efftinge
 

Similar to 100% Code Coverage - TDD mit Java EE (20)

Spring mvc my Faviourite Slide
Spring mvc my Faviourite SlideSpring mvc my Faviourite Slide
Spring mvc my Faviourite Slide
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
The secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutThe secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you about
 
Unit testing
Unit testingUnit testing
Unit testing
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Automated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platformsAutomated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platforms
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And Drupal
 
Presentation Unit Testing process
Presentation Unit Testing processPresentation Unit Testing process
Presentation Unit Testing process
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
 
Agile mobile
Agile mobileAgile mobile
Agile mobile
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
 
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
 
Auto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendAuto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with Xtend
 

More from Stefan Macke

Railway Oriented Programming - Funktionaler programmieren ohne Exceptions
Railway Oriented Programming - Funktionaler programmieren ohne ExceptionsRailway Oriented Programming - Funktionaler programmieren ohne Exceptions
Railway Oriented Programming - Funktionaler programmieren ohne ExceptionsStefan Macke
 
Moderne IT-Infrastrukturen (Cloud Computing, Serverless)
Moderne IT-Infrastrukturen (Cloud Computing, Serverless)Moderne IT-Infrastrukturen (Cloud Computing, Serverless)
Moderne IT-Infrastrukturen (Cloud Computing, Serverless)Stefan Macke
 
Property-based Testing mit JUnit-Quickcheck
Property-based Testing mit JUnit-QuickcheckProperty-based Testing mit JUnit-Quickcheck
Property-based Testing mit JUnit-QuickcheckStefan Macke
 
Railway Oriented Programming - Java funktional und ohne Exceptions
Railway Oriented Programming - Java funktional und ohne ExceptionsRailway Oriented Programming - Java funktional und ohne Exceptions
Railway Oriented Programming - Java funktional und ohne ExceptionsStefan Macke
 
Steuerung für automatische Verbuchungsprozesse im SAP ERP
Steuerung für automatische Verbuchungsprozesse im SAP ERPSteuerung für automatische Verbuchungsprozesse im SAP ERP
Steuerung für automatische Verbuchungsprozesse im SAP ERPStefan Macke
 
Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...
Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...
Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...Stefan Macke
 
Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7
Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7
Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7Stefan Macke
 

More from Stefan Macke (8)

Railway Oriented Programming - Funktionaler programmieren ohne Exceptions
Railway Oriented Programming - Funktionaler programmieren ohne ExceptionsRailway Oriented Programming - Funktionaler programmieren ohne Exceptions
Railway Oriented Programming - Funktionaler programmieren ohne Exceptions
 
Moderne IT-Infrastrukturen (Cloud Computing, Serverless)
Moderne IT-Infrastrukturen (Cloud Computing, Serverless)Moderne IT-Infrastrukturen (Cloud Computing, Serverless)
Moderne IT-Infrastrukturen (Cloud Computing, Serverless)
 
Property-based Testing mit JUnit-Quickcheck
Property-based Testing mit JUnit-QuickcheckProperty-based Testing mit JUnit-Quickcheck
Property-based Testing mit JUnit-Quickcheck
 
Railway Oriented Programming - Java funktional und ohne Exceptions
Railway Oriented Programming - Java funktional und ohne ExceptionsRailway Oriented Programming - Java funktional und ohne Exceptions
Railway Oriented Programming - Java funktional und ohne Exceptions
 
Sketch Notes
Sketch NotesSketch Notes
Sketch Notes
 
Steuerung für automatische Verbuchungsprozesse im SAP ERP
Steuerung für automatische Verbuchungsprozesse im SAP ERPSteuerung für automatische Verbuchungsprozesse im SAP ERP
Steuerung für automatische Verbuchungsprozesse im SAP ERP
 
Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...
Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...
Wer braucht eigentlich Microservices - Aktuelle Trends der Softwareentwicklun...
 
Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7
Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7
Von wegen schwergewichtig - Moderne Webentwicklung mit Java EE 7
 

Recently uploaded

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
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
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
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
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
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
 
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
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
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
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
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
 

Recently uploaded (20)

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
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
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
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
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
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
 
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...
 
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
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
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 Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
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
 

100% Code Coverage - TDD mit Java EE

Editor's Notes

  1. Das ist Stefan.
  2. Stefan ist Softwareentwickler und arbeitet mit Java.
  3. Ganz besonders mag Stefan bei der Programmierung die Automatisierung von Tests.
  4. In seinen aktuellen Projekten setzt er Java EE ein und tut sich etwas schwer mit den Tests.
  5. Wie soll er die vielen Komponenten und insb. die „Magic“ von EE in Tests abdecken? Und ist das überhaupt sinnvoll?
  6. Wie gut, dass es zu diesem Thema einen Vortrag auf der JavaLand gibt! Also lasst uns loslegen!
  7. Ich würde gerne einen kleinen Überblick bekommen, wie weit ihr im Bezug auf automatisierte Tests seid.
  8. Wer schreibt Unit-Tests?
  9. Wer (davon) schreibt Integration-Tests?
  10. Wer (davon) schreibt automatische Browser-/UI-Tests?
  11. Vergleichen wir unser Ergebnis doch einmal mit einigen Umfragen. Unit-Tests scheinen gängige Praxis zu sein. Java Tools and Technologies Landscape 2014 (RebelLabs/ZeroTurnaround), 2164 Teilnehmer, http://pages.zeroturnaround.com/Java-Tools-Technologies.html Survey Results: How Many Developers Write Unit Tests? (Hubstaff, 2014), mehrere hundert Teilnehmer, http://blog.hubstaff.com/survey-many-developers-write-unit-tests/
  12. Und nun gehen wir einen Schritt weiter und fragen nach Browser-Tests. Dort sieht die Situation schon etwas anders aus. Java Tools and Technologies Landscape 2014 (RebelLabs/ZeroTurnaround), 2164 Teilnehmer, http://pages.zeroturnaround.com/Java-Tools-Technologies.html Survey Results: How Many Developers Write Unit Tests? (Hubstaff, 2014), mehrere hundert Teilnehmer, http://blog.hubstaff.com/survey-many-developers-write-unit-tests/
  13. Die verwendeten Tools laut einer Umfrage von 2014. Java Tools and Technologies Landscape 2014 (RebelLabs/ZeroTurnaround), 2164 Teilnehmer, http://pages.zeroturnaround.com/Java-Tools-Technologies.html
  14. Die Frage danach, ob die Entwickler gerne Tests schreiben, wurde größtenteils positiv beantwortet. Aber da geht noch mehr! Survey Results: How Many Developers Write Unit Tests? (Hubstaff, 2014), mehrere hundert Teilnehmer, http://blog.hubstaff.com/survey-many-developers-write-unit-tests/
  15. Was macht Unit-Tests schwierig? Laut einer Studie wird auf der Liste häufiger Probleme beim Unit-Testing auf Platz 2 von 5 die Isolation der Unit genannt. A Survey on Unit Testing Practices and Problems (Daka/Fraser, 2014), 225 Teilnehmer, http://ieeexplore.ieee.org/document/6982627/
  16. Und genau darum soll es heute gehen: Wie können wir die einzelnen Komponenten einer Java-EE-Anwendung möglichst isoliert testen?
  17. Also werden wir uns an den üblichen Komponenten einer Java-EE-Anwendung orientieren und sie Schritt für Schritt unter Test bringen.
  18. Also lasst uns loslegen und schauen, wie wir eine Java-EE-7-Applikation komplett mit Tests abdecken können.
  19. Aber bevor wir tiefer ins Thema einsteigen stelle ich mich noch kurz vor.
  20. Ich habe einige Blogs, aber unter soa.rocks gibt es auch ab und an etwas über Java zu lesen. Keine Angst: Ich blogge (noch) nicht über Microservices! ;-)
  21. Ihr könnt mir gerne auf Twitter folgen.
  22. Und wenn ihr Lust habt, hört doch mal in meinen Podcast rein.
  23. Dort gibt es über 100 Episoden.
  24. Es gibt auch schon einige spannende Interviews. Zwei davon sogar mit Referenten der JavaLand vom letzten Jahr.
  25. Ich komme aus Vechta, einer kleinen Stadt im Nordwesten Deutschlands mit ca. 30.000 Einwohnern.
  26. Ich arbeite dort bei der ALTE OLDENBURGER Krankenversicherung AG als Softwareentwickler und -architekt.
  27. Nebenberuflich bin ich noch Dozent für Programmierung und Software-Engineering an der PHWT.
  28. Doch nun zurück zum Thema!
  29. Kenntnisse von Java EE und den üblichen Pattern/Komponenten/Frameworks setze ich im Weiteren voraus.
  30. Dies ist die Beispielapplikation, die uns durch alle Testphasen begleiten wird. Sie ist sehr simpel aufgebaut, umfasst aber alle häufig verwendeten Technologien und Abstraktionen von Java EE. Die Oberfläche ist mit Standardmitteln von JSF gebaut.
  31. Der Datenbankzugriff läuft über JPA.
  32. Für die Validierung wird Bean Validation genutzt.
  33. Natürlich bietet die Anwendung eine REST-API für den Zugriff von außen an.
  34. Und zuletzt werden noch per REST-Client externe Inhalte eingebunden.
  35. Die Architektur ist in folgende Komponenten aufgeteilt.
  36. Die Domain enthält die POJOs und die Geschäftslogik ohne Abhängigkeiten nach außen.
  37. Das Repository ist für den Zugriff auf die Datenhaltung verantwortlich und wird mittels JPA realisiert. Die Abhängigkeit geht in Richtung des Models. Die Entitys in der Domain verwenden allerdings @Entity-Annotationen, um den Code nicht unnötig zu verkomplizieren.
  38. Die Services stellen die fachlichen Schnittstellen nach außen dar. Sie verwenden ViewModels für den Datenaustausch mit den anderen Komponenten.
  39. In der View werden JSF für die Oberflächen und JAX-RS für das Anbieten einer REST-API verwendet. Dabei wird Model View Controller als internes Modell verwendet.
  40. Zuletzt soll die Anwendung noch mit externen Systemen kommunizieren und verwendet dafür einen REST-Aufruf bzw. das Versenden von Mails.
  41. Bevor wir loslegen noch ein paar allgemeine Hinweise.
  42. Die gesamte Anwendung inkl. Testcode ist bei GitHub verfügbar. Daher reduziere ich die Code-Beispiele stark auf die Kernaussagen. Die vollständige Implementierung könnt ihr euch online anschauen. Auch enthalten sind Dinge, die ich heute nicht zeigen kann, wie Mutation Testing und Property-based Testing.
  43. Die Test-Pyramide ist sinnvoll: viele schnelle Unit-Tests (mit Mocking) und wenige langsame Integrationstests (mit Deployment) schreiben. Der Fokus dieses Vortrags liegt darauf, wie wir statt Integrationstests Unit-Tests schreiben können, indem die zu testenden Komponenten voneinander isoliert werden.
  44. Das Ziel ist daher, möglichst viele Tests im Java-SE-Kontext laufen zu lassen und nicht einen kompletten EE-Container dafür hochzufahren.
  45. Dabei sollte jeweils nur das getestet werden, was die jeweilige Schicht selbst tut (z.B. bei REST-APIs HTTP-Codes erzeugen), und nicht z.B. Business-Logik durch die Oberfläche getestet werden.
  46. Das Ziel ist dabei nicht (wie der Titel des Vortrags vermuten lässt), 100% Codeabdeckung zu erreichen. Aufwand und Nutzen stehen dabei nämlich häufig in keinem sinnvollen Verhältnis.
  47. Aus drei echten Projekten habe ich als Beispiel mal die letztendliche Codeabdeckung mitgebracht.
  48. Beim ersten Projekt sieht die Coverage im Model z.B. recht gering aus. Aber bei genauem Hinsehen fällt auf, dass dies eigentlich ausschließlich durch die fehlende Abdeckung der generierten (!) equals()-Methoden usw. zustandekommt. Wie man damit umgeht, zeige ich später.
  49. Beim letzten Projekt fällt die Testabdeckung der Kernkomponente – der Services – sehr hoch aus. Damit könnte ich gut leben, denn hier spielt die eigentliche Musik – die Geschäftslogik!
  50. Zunächst wollen wir uns nun also anschauen, wie wir die Geschäftslogik unserer Anwendung testen können.
  51. In der Architektur befinden wir uns nun im Bereich Model -> Domain und ViewModel.
  52. So könnte eine Klasse aussehen, die wir testen wollen: Getter und Setter und fachliche Methoden.
  53. Hierfür eignen sich „klassische“ Unit-Tests, die mittels Assertions die Rückgabewerte von Methodenaufrufen prüfen. Wir verwenden dafür die neuste Version von JUnit, die einige hilfreiche Neuerungen mitbringt.
  54. Zu Beginn zwei kurze Hinweise zur Benennung meiner Tests. Die Klassennamen enden meist auf „Should“, sodass sich sprechende Zusammenhänge aus Klassen- und Methodennamen ergeben: „User should -> be valid“.
  55. Und die zu testende Klasse heißt in meinen Tests immer „sut“, um sie von evtl. notwendigen anderen Instanzvariablen abzugrenzen und eine einheitliche Benennung in allen Tests zu haben.
  56. Je nach Laune verwende ich für die Assertions AssertJ, um etwas sprechendere Tests zu erzeugen. Beispiel: PasswordShould
  57. Dumme POJOs und Beans (wie z.B. die ViewModels) lassen sich automatisiert mittels Reflection testen, auch wenn der Mehrwert fragwürdig ist. Beispiel: UserShould
  58. Mit den Bean Matchers bekommt man dann auch tatsächlich 100% Code Coverage hin!
  59. BeanValidation lässt sich recht einfach testen.
  60. Es ist lediglich eine Implementierung des Standards (z.B. Hibernate Validator) nötig und der Validator liefert alle Validierungsergebnisse für einfache Assertions. Beispiel: UserShould
  61. Damit befinden wir uns nun schon im nächsten Bereich der Architektur: Service und ViewModel. Und wir gehen nun in Richtung Test von Abhängigkeiten und schauen uns dafür einen Service an.
  62. So könnte eine Klasse aussehen, die externen Input benötigt bzw. externe Aufrufe tätigt. Beide Varianten werden unterschiedlich getestet, also sollten wir sie trennen. Beginnen wir mit den externen Inputs.
  63. Wir testen sie mit Stub-Objekten, die das Verhalten der Abhängigkeiten simulieren und harte Werte zurückliefern. Dafür hat sich das Framework Mockito etabliert. Beispiel: UserServiceShould Am Test ändert sich nichts: Inputs werden gestubbt, Tests verwenden weiterhin normale Assertions.
  64. Dabei ist irrelevant, wie diese Abhängigkeit erzeugt wird, also z.B. als Konstruktorparameter oder per Dependency Injection. Attribute, die über das häufig genutzte @Inject gefüllt werden, können z.B. durch setzen des entsprechenden Attributs auf package-private direkt im Test zugewiesen werden.
  65. Das bricht die Kapselung zwar ein wenig auf, erleichtert den Test aber deutlich. Und es ist kein DI-Framework nötig.
  66. Es ist sogar möglich, statische Methoden zu stubben. Das Framework PowerMock macht es möglich. Beispiel: UserServiceAlsoShould
  67. Nun schauen wir uns an, wie wir Seiteneffekte testen, die von der zu testenden Klasse ausgelöst werden.
  68. Dafür verwenden wir Mocks, die sich „merken“ können, wie mit ihnen interagiert wurde. Die Tests verändern sich: Statt Assertions gegen Rückgabewerte werden nun Vergleiche mit dem gewünschten Kommunikationsverhalten durchgeführt (verify). Beispiel: UserServiceShould Da Services häufig „nur“ Repositorys und andere Services orchestrieren, kann ihr Verhalten gut mittels Mocks getestet werden.
  69. Viele Klassen nutzen Logger (z.B. von SLF4J), die auch im Test vorhanden sein müssen und gestubbt werden können. Falls es zum Use-Case dazugehört, könnte sogar geprüft werden, ob Logaufrufe stattgefunden haben. Beispiel: SessionResourceShould
  70. Als nächstes schauen wir uns die Tests für die Persistenzschicht an.
  71. Wir befinden uns nun im Bereich der Persistence, für die JPA als Technologie eingesetzt wird.
  72. So könnte ein typisches Repository aussehen, das letztlich nur einen Wrapper um den Entity Manager darstellt.
  73. Für den Großteil der Funktionalität muss lediglich der EntityManager gemockt werden. Das kann durch Setzen der Instanzvariable auf package-private analog zum Service einfach erreicht werden. Beispiel: JpaUserRepositoryShould
  74. Das Setup wird nun etwas komplexer, da teilweise auch die Returnwerte des Entity Managers erneut gemockt werden müssen. Aber mit sprechenden Hilfsmethoden im Testcase kann man trotzdem gut lesbare Tests schreiben.
  75. Das hier ist ein komplettes Beispiel für einen AAA-Test mit gemocktem Entity Manager.
  76. Durch das Mocken des Entity Managers können wir leider nicht die korrekte Konfiguration (Annotationen für Ids, Beziehungen, Serializable, Custom Converter usw.) der Entity-Klassen testen.
  77. Für den Test der „JPA-Magic“ nutzen wir daher eine echte (aber leichtgewichtige) Datenbank, die einen Zugriff auf Testdaten ermöglicht. Dafür wird Derby als Datenbank und EclipseLink als JPA-Referenzimplementierung verwendet.
  78. Man kann dafür entweder eine eigene Persistence Unit in der persistence.xml in main anlegen oder eine zweite persistence.xml in test hinzufügen. Ich tendiere zu Letzterem, damit kein Test-Artefakt im Produktionscode liegt. Die persistence.xml reicht aus, um zur Testlaufzeit eine funktionsfähige Datenbank vorzufinden, die direkt ohne weiteres Setup genutzt werden kann.
  79. Lediglich der Inhalt der Testdatenbank ist noch anzulegen. Dafür ist ein manueller Aufruf des Entity-Managers mit eigener Transaktionssteuerung zu Beginn des Tests nötig, da wir uns noch nicht im EE-Container befinden.
  80. Die Testdaten können nun ganz normal mit dem Entity Manager erzeugt werden. Ein Aufräumen/Teardown ist nicht nötig, da die Datenbank mittels der entsprechenden EclipseLink-Option automatisch beim Starten gelöscht und neu angelegt wird.
  81. Nun kann ganz „normal“ getestet werden. Das Repository muss lediglich den Entity Manager gesetzt bekommen, da es ihn nicht automatisch injiziert bekommt. Beispiel: JpaUserRepositoryIntegrationTest
  82. Die Controller der View-Komponente lassen sich recht gut isoliert testen. Dazu ist weder JSF noch ein EE-Container notwendig.
  83. Wir befinden uns in der Architektur nun im Frontend und schauen uns im Detail die Controller an.
  84. Ein Controller kommuniziert laut Architektur mit dem Service im Model, um die gewünschten Use-Cases umzusetzen. Dabei verwenden beide die ViewModels als Parameter. Außerdem wird häufig der FacesContext genutzt, um z.B. Meldungen anzuzeigen.
  85. Hier ist das Anzeigen einer solchen Meldung zu sehen. Man könnte nun also auf die Idee kommen, den FacesContext wie gewohnt als package-private Instanzvariable anzulegen und zu mocken.
  86. Der Test ist nun nur noch ein simpler String-Vergleich für die Zielseiten und ein verify() für die Messages. Beispiel: LoginControllerShould
  87. Die angebotene REST-Schnittstelle wird als nächstes getestet.
  88. Die REST-API zählt auch zum Frontend der Anwendung. Wie man sie testen kann, wird als nächstes behandelt.
  89. Der Aufbau ist analog zum Controller: Eine Ressource nutzt den Service im Model zur Umsetzung der Use-Cases.
  90. Der Service kann wieder gemockt werden und die Tests (z.B. der korrekten Return-Codes) verlaufen analog zum Controller. Beispiel: SessionResourceShould
  91. Um allerdings den korrekten Aufbau der URLs und die Annahme/Rückgabe der richtigen Content-Types zu testen, müssen wir die REST-API in einen Servlet-Container deployen.
  92. Dazu verwenden wir den leichtgewichtigen Container Jetty, der mit wenigen Zeilen Code eingerichtet und gestartet werden kann.
  93. Für den Test kann nun einfach mit Jersey ein REST-Client entwickelt werden, mit dem dann normale Assertions durchgeführt werden können.
  94. Für ein wenig mehr Komfort beim Testen der REST-Services kann RESTassured eingesetzt werden, das eine Fluent-API anbietet. Dann muss nicht manuell mit Jersey ein eigener REST-Client erstellt werden. Beispiel: SessionResourceIntegrationTest
  95. Die gesamte Anwendung als Ganzes kann inkl. eines Deployments in einen Container automatisiert getestet werden.
  96. Um das Zusammenspiel der gesamten Anwendung zu testen, wird diese in einen EE-Container deployt. Hier kann sie unter realistischen Bedingungen mit allen nötigen EE-Frameworks getestet werden.
  97. Alle Komponenten sollen nun im Zusammenspiel getestet werden. Insbesondere die Dependency Injection und die Verbindung zur Datenbank stehen hierbei im Fokus.
  98. Arquillian ist ein Integration-Test-Framework für Java-EE-Anwendungen, das die gesamte Applikation in einen echten Application Server deployt.
  99. Arquillian unterstützt eine Vielzahl an Zielcontainern.
  100. arquillian.xml -> Target für Deployment definieren Chameleon lädt Dependencies automatisch beim Ausführen des Tests herunter
  101. Artefakt der Anwendung wird erstellt Zeigt auf In-Memory-DB des Zielsystems mit create-drop Mittels Observer werden automatisch die Testdaten in die Datenbank geschrieben
  102. Anwendung wird deployt -> generierte URL als WebTarget injiziert Arquillian führt die Tests direkt im Container aus bzw. ermöglicht Zugriff von außen über WebTarget z.B. für RESTassured
  103. Da wir nun die Anwendung zur Testzeit automatisiert deployen können, kann auch die Weboberfläche mit Tests versehen werden.
  104. Der letzte noch zu testende Teil der Frontend-Architektur sind die JSF-Seiten. Da hierfür ein Deployment in einen EE-Container notwendig ist, bauen die Tests immer auf diesem auf.
  105. Hier geht es nun nicht mehr um automatische Tests der Komponenten, sondern um echte End-to-End-Tests der Oberfläche, also die Simulation der Benutzereingaben.
  106. Der de facto Standard für Weboberflächentests ist das Framework Selenium. Es kann verschiedene Browser simulieren bzw. fernsteuern. Und einer dieser Browser ist PhantomJS, ein „headless“ JavaScript-Browser.
  107. Das Framework Drone verbindet Selenium mit Arquillian und Graphene bietet einige nette Features, die das Schreiben von Tests einfacher macht. Drone: Wrapper um WebDriver, Lifecycle-Management für Browser, mehrere Browser pro Test Graphene: Page-Abstraktion, AJAX-Unterstützung, Waiting-API
  108. Die zu testenden Webseiten können in einzelnen Klassen abgebildet werden, die mittels CSS-Selektoren, XPath oder anderen Zugriffsmethoden automatisiert gesteuert werden können. Beispiel: LoginPage
  109. Unsere eigene Anwendung steht nun komplett unter Tests. Aber die Abhängigkeiten von fremden Services gilt es noch mit Tests abzudecken.
  110. Der letzte Teil unserer Architektur sind die externen Services, die von unserer Anwendung über Standardprotokolle wie HTTP oder SMTP aufgerufen werden.
  111. So könnte ein interner REST-Client aussehen, der eine externe Ressource abfragt. Die Anfrage an den Service sollte von der Verarbeitung der Ergebnisse getrennt werden. Dann kann ersterer gemockt werden, während die Verarbeitung normal mit Unit-Tests abgedeckt wird. Beispiel: ArticleService
  112. Die Verarbeitung des JSON-Strings, der vom Fremdsystem geliefert wird, kann ganz einfach getestet werden. Beispiel: ArticleServiceShould
  113. Der Hostname des Zielsystems muss konfigurierbar sein, sodass im Test localhost verwendet werden kann. Das geht der Einfachheit halber wieder gut mit package-private Attributen.
  114. Für den Test gegen einen „echten“ REST-Endpunkt kann nun Wiremock verwendet werden. Es wird zur Laufzeit ein Webserver gestartet, der REST-Anfragen entgegennimmt. Beispiel: ArticleServiceIntegrationTest
  115. Für Tests, die mehr als eine REST-Schnittstelle ansprechen, gibt es noch Citrus. Das Framework kann alle erdenklichen Schnittstellen mocken, z.B. SOAP, REST, JMS, FTP, SSH.
  116. Damit komme ich zum Ende meines Vortrags.
  117. Java bietet eine Vielzahl an ausgereiften Frameworks rund ums Testen bis hin zum automatischen Deployment in einen Application Server. Stefan ist durch die ganzen Möglichkeiten jetzt allerdings mehr verwirrt als vorher.
  118. Er wollte doch nur ein paar Unit Tests schreiben…
  119. …und nicht gleich ein ganzes Sammelsurium an Frameworks lernen und kombinieren.
  120. Aber man muss ja nicht gleich mit allen Teilen starten, sondern kann langsam anfangen. Macht euch Gedanken über die Isolation eurer Units und legt mit dem gewohnten JUnit und Mockito los.
  121. Und Schritt für Schritt fügt ihr für alle Komponenten die passenden Frameworks hinzu.
  122. Der Aufwand für automatische Tests lohnt sich immer! Also fangt am besten gleich morgen damit an!
  123. Vielen Dank! Wie gesagt: Das komplette Projekt findet ihr auf GitHub.