Top Banner
SPRINGONE2GX WASHINGTON, DC © 2013-2015 Sam Brannen & Nicolas Fränkel and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Get the Most out of Testing with Spring 4.2 Sam Brannen @sam_brannen Nicolas Fränkel @nicolas_frankel
64

Get the Most out of Testing with Spring 4.2

Apr 12, 2017

Download

Software

Sam Brannen
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Get the Most out of Testing with Spring 4.2

SPRINGONE2GXWASHINGTON, DC

© 2013-2015 Sam Brannen & Nicolas Fränkel and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/l icenses/by-nc/3.0/

Get the Most out of Testingwith Spring 4.2

Sam Brannen@sam_brannen

Nicolas Fränkel@nicolas_frankel

Page 2: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 2

Sam Brannen• Spring and Enterprise Java Consultant @ Swiftmind

• Java Developer for over 17 years

• Spring Framework Core Committer since 2007• Component lead for spring-test• Creator of @AliasFor

• Spring Trainer

• Speaker on Spring, Java, and testing

• Swiss Spring User Group Lead

Page 3: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 3

Your experts for Spring and Enterprise Java

Areas of expertise• Spring *• Java EE• Software Architecture• Software Engineering

Best Practices

Where you find us• Zurich, Switzerland• @swiftmind• http://

www.swiftmind.com

Page 4: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 4

Nicolas Fränkel• Developer & Architect

• Consultant

• Teacher & Trainer

• Blogger

• Book Author

Page 5: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 5

Learning Vaadin 7

Integration Testing from the Trenches

Nicolas’ Books

Page 6: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 6

Agenda• Spring Events App

• New in Spring 4.2

• JUnit vs. TestNG

• Spring Boot Tests

• Spring Security Tests

• Tips & Tricks

Page 7: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 7

Show of hands…

Page 8: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 8

Spring Events App

Page 9: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 9

The Spring Events Example Application• Spring Boot powered web app

• Simple POJO domain model: Event

• Transactional service layer

• Spring Data JPA repository layer

• Spring @MVC +Thymeleaf & REST presentation layer

• Spring Security

• https://github.com/sbrannen/spring-events

Page 10: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 10

New in Spring Framework 4.2

Page 11: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 11

@AliasFor• New in Spring Framework 4.2, refined in 4.2.1

• Used to declare aliases between attributes within an annotation• e.g., locations and value in @ContextConfiguration, or

path and value in @RequestMapping

• Used in composed annotations to declare explicit overrides of attributes in meta-annotations• e.g., @Get, @Post, @GetJson, @TransactionalService• See Spring Composed project for examples• https://github.com/sbrannen/spring-composed

Page 12: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 12

Composable Annotations w/ Overrides: pre 4.2• Composable annotations can override attributes of meta-annotations

• Purely convention-based• Matched by attribute name and type• Can lead to potential naming conflicts

• Cannot override the value attribute

Page 13: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 13

Convention-based Attribute Override@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration@Transactionalpublic @interface TransactionalTest { String[] locations() default {};}

@TransactionalTest(locations = "/order-test-config.xml")public class OrderRepositoryTests { }

seen as locations in @ContextConfiguration

redeclares locations attribute

declares locations attribute

Page 14: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 14

Conflict w/ Convention-based Attribute Override@Target(TYPE)@Retention(RUNTIME)@ContextConfiguration@TestPropertySource@Transactionalpublic @interface TransactionalTest { String[] locations() default {};}

@TransactionalTest(locations = "/order-test-config.xml")public class OrderRepositoryTests { }

both declare locations attribute

ambiguous

which one?!

Page 15: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 15

Composable Annotations w/ Overrides: post 4.2• Composable annotations can explicitly override attributes of meta-

annotations, even transitively

• Attributes within an annotation that effectively override the same attribute are treated as implicit aliases for each other

• Explicitly declared via @AliasFor• Can avoid potential naming conflicts

• Can even override the value attribute

Page 16: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 16

Avoid Attribute Override Conflict w/ @AliasFor (1)@ContextConfiguration@TestPropertySource@Transactionalpublic @interface TransactionalTest {

@AliasFor(annotation = ContextConfiguration.class, attribute = "locations") String[] xmlFiles() default {};

@AliasFor(annotation = TestPropertySource.class, attribute = "locations") String[] propFiles() default {};}

both declare locations attribute

explicit

explicit

Page 17: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 17

Avoid Attribute Override Conflict w/ @AliasFor (2)

@TransactionalTest( xmlFiles = "/order-test-config.xml", propFiles = "/order-test.properties")public class OrderRepositoryTests {}

seen as locations in @ContextConfiguration

seen as locations in @TestPropertySource

Page 18: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 18

Embedded Databases – What’s in a Name?Q: Why should I care what my embedded database is named?A: Because you’ll run into problems if your DataSource config is imported from multiple places within your test suite.

Q: Why? Doesn’t it just create a new instance of the database?A: Recreating an embedded database within the same JVM doesn’t actually create anything: a second attempt simply connects to the existing one.

Q: Ummmm… What?!A: When you connect to an embedded database, it gets created if it doesn’t already exist; otherwise, you just connect to the existing instance. Assigning each one a unique name results in different JDBC connection URLs and thus different instances.

Page 19: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 19

Unique Names for Embedded Databases• EmbeddedDatabaseBuilder

• setName() – since 3.0• generateUniqueName() – since 4.2

• <jdbc:embedded-database>• id – used as name since 3.0

o but bad since the id is usually “dataSource”... i.e., not unique• database-name – since 4.2• generate-name – since 4.2

Page 20: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 20

Ex: Embedded Database in Java Config

@Beanpublic DataSource dataSource() { return new EmbeddedDatabaseBuilder() .generateUniqueName(true) .addScript("schema.sql") .addScript("user_data.sql") .build();}

New in Spring 4.2

Page 21: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 21

Ex: Embedded Database XML Config

<jdbc:embedded-database id="dataSource" generate-name="true"> <jdbc:script location="classpath:/schema.sql" /> <jdbc:script location="classpath:/user_data.sql" /></jdbc:embedded-database>

New in Spring 4.2

Page 22: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 22

Spring Cleaning• @TransactionConfiguration

• Deprecated in 4.2• @Rollback (and @Commit) now supported at the class level• Use @Transactional qualifiers

• AssertThrows• Deprecated in 3.x; gone in 4.2• JUnit: use @Test(expected = ...) or @Rule ExpectedException• TestNG: use @Test(expectedExceptions = ...)

Page 23: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 23

Extension Points• ContextCache

• Now a public API with DefaultContextCache implementation

• DefaultTestContext, DefaultBootstrapContext, and DefaultCacheAwareContextLoaderDelegate• Now public classes, allowing for custom extensions

• TestContextBootstrapper• Now responsible for building the TestContext

Page 24: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 24

Spring + JUnit … @Rules!• SpringJUnit4ClassRunner

• Serving the community since Spring 2.5 (2007)• But… can’t be used with other runners

o JUnit's Parameterized, MockitoJUnitRunner, etc.

• SpringClassRule & SpringMethodRule• Since Spring 4.2• Can be used with any JUnit runner!• Have to be used together• Provide full power of the Spring TestContext Framework

Page 25: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 25

Ex: SpringClassRule & SpringMethodRule

@RunWith(Parameterized.class)@ContextConfigurationpublic class ParameterizedSpringRuleTests {

@ClassRule public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

@Rule public final SpringMethodRule springMethodRule = new SpringMethodRule();

Page 26: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 26

HtmlUnit, Selenium, & Geb• First-class support for HtmlUnit and Selenium in Spring MVC Test

• Initially a stand-alone project

• Incorporated into spring-test in Spring 4.2

• Page-based web app testing w/o a Servlet container

• The Selenium support can also be used with Geb

Page 27: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 27

MockMvc & HtmlUnit WebClient Setup• spring-test (4.2+) & htmlunit (2.18+)

• MockMvcWebClientBuilder: several options, simplest case below

@Autowired WebApplicationContext wac;

WebClient webClient;

@Beforepublic void setup() { webClient = MockMvcWebClientBuilder .webAppContextSetup(wac).build();}

Page 28: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 28

MockMvc & Selenium WebDriver Setup• spring-test (4.2+) & selenium-htmlunit-driver (2.47+)

• MockMvcHtmlUnitDriverBuilder: several options, simplest case below@Autowired WebApplicationContext wac;

WebDriver webDriver;

@Beforepublic void setup() { webDriver = MockMvcHtmlUnitDriverBuilder .webAppContextSetup(wac).build();}

Page 29: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 29

Odds & Ends (1)• ReflectionTestUtils

• Now you can get or set static fields, including constants

• AopTestUtils• Obtain reference to target object hidden behind one or more Spring

proxies• Useful if your mock gets proxied (e.g., if your interface is @Transactional)

• @DirtiesContext• New BEFORE_METHOD, BEFORE_CLASS, & BEFORE_EACH_TEST_METHOD

modes• Requires DirtiesContextBeforeModesTestExecutionListener, enabled by

default

Page 30: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 30

ReflectionTestUtils vs. Proper Design• Proper design mandates that we use the most narrow visibility

possible.• But it’s sometimes meaningful to test private methods, or change

values of final fields, etc.

• As a work-around, set the visibility to package (no keyword) and put the test class in the same package.• Guava provides the @VisibleForTesting annotation to document

this hack.

• ReflectionTestUtils is an alternative to such work-arounds that promotes proper design.

Page 31: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 31

Odds & Ends (2)• @Commit

• Syntactical sugar for @Rollback(false)

• Inlined statements with @Sql• When a dedicated SQL script is overkill• Configured via the new statements attribute• Executed after SQL scripts in same @Sql annotation• Great for one-liners

• Spring MVC Test - MvcResult logging• New log(), print(OutputStream), and print(Writer) methods in

MockMvcResultHandlers complement existing print() method

Page 32: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 32

@Test@Sql(statements = "DROP TABLE user IF EXISTS")@Sql( scripts = "/test-schema.sql", statements = "INSERT INTO user VALUES ('Dilbert')")public void userTest() { // code that uses the test schema and test user}

Ex: Inlined @Sql Statements

Page 33: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 33

@Beforepublic void setUpMockMvc() { mockMvc = MockMvcBuilders .webAppContextSetup(wac) .alwaysDo(print(System.err)) .build();}

Ex: Logging MvcResult to STDERR

Page 34: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 34

JUnit vs TestNG

Page 35: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 35

JUnit• De facto testing framework for

Java

• Most popular library in the entire Java ecosystem• http://bit.ly/1iwwboO

Page 36: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 36

JUnit• Unit for… unit testing!

• Test methods are independent and isolated• Simplicity can be both a pro and a con• Can be used for integration testing, too

• Test methods are unordered• Unless you use @FixMethodOrder

• Single Runner• Spring OR Mockito OR Parameterized• Rules to the rescue

Page 37: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 37

TestNG• Implemented test annotations before JUnit

• Richer lifecycle than JUnit

• Ordering and grouping of test methods

• Concurrent test execution

Page 38: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 38

Spring Boot Tests

Page 39: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 39

Integration Tests with Spring Boot• @SpringApplicationConfiguration

• Like @ContextConfiguration but with SpringApplicationContextLoader

• Fully Loaded• @IntegrationTest

o IntegrationTestPropertiesListener vs. @TestPropertySource• @WebIntegrationTest

• Limit scope of auto-configuration• @TestRepositoryConfig as example

Page 40: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 40

Spring Security Tests

Page 41: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 41

Spring Security Test Annotations• WithSecurityContextTestExecutionListener

• auto-detected

• @WithMockUser• See RestEventsControllerIT in spring-events

• @WithUserDetails

• @WithSecurityContext

Page 42: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 42

Spring Security & MockMvc• apply(springSecurity())

• with(...)• user(...)• authentication(...)• securityContext(...)• httpBasic(...)

• perform(...)• formLogin()

• logout()

Page 43: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 43

Testing Tips & Tricks

Page 44: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 44

Eclipse• Define key bindings for executing tests quickly

• Alt + Shift + X… T too awkward to type frequently!• Sam’s personal settings:

o Run JUnit Test Ctrl + Jo Rerun JUnit Test Ctrl + Shift + J

• Set up content assist favorites for common static imports• org.junit.Assert OR org.assertj.core.api.Assertions• org.mockito.Mockito• org.springframework.test.web.servlet.request.MockMvcRequestBuilders• org.springframework.test.web.servlet.result.MockMvcResultMatchers

Page 45: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 45

Context Caching• Granularity of context configuration files

• Goal: one entry point for production and one for testing• But… not very practical: you’ll need to support different scenarios• Too many constellations too many contexts • Too few constellations all tests use the same config

• Optimum use of the context cache• Avoid frequent use of @DirtiesContext• Cache statistics are logged at DEBUG level for category

org.springframework.test.context.cache

Page 46: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 46

Integration Tests: Spring Boot vs. Spring Core• The key differences are speed and scope

• @SpringApplicationConfiguration vs. @ContextConfiguration

• @EnableAutoConfiguration vs. hand-crafted test @Configuration• See @TestRepositoryConfig in spring-events app

Page 47: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 47

Scope• Think about the scope of your

test• SUT: Subject Under Test

• The larger the SUT, the smaller the number of tests

• Mock or fake the dependencies of your SUT

Page 48: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 48

End-to-end Testing• A few nominal scenarios

• Very brittle• Use the Page pattern• Decouples the page structure from the test itself

Page 49: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 49

Integration Testing Challenges• Speed

• Diagnosing the problem

• Brittleness

Page 50: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 50

Speed• Integration tests are often slow

• Execute unit tests before integration tests• No need to run integration tests if unit tests fail

• Separate unit and integration tests in the build• Maven: use the maven-failsafe-plugin• Gradle: configure dependent Test tasks

o See spring-events for an example

Page 51: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 51

Diagnosing the Problem• Consider an e-commerce checkout process

• Multi-step use case• Many places where things can go wrong

• Use small, focused, and aptly named methods

• Order and group methods• According to the steps in the process• Easy with TestNG; possible with JUnit

Page 52: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 52

Brittleness• All applications have infrastructure dependencies

• Database, web services, file system, time, etc.

• External dependencies might be unavailable during testing• Sends a bad signal to developers• Causes builds to fail intermittently

• Solution: approximate the production environment• Mock or fake external dependencies

Page 53: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 53

Developer & Test Databases• Embedded databases

• HSQL, H2, Derby• in-memory or persistent mode• H2 supports compatibility modes for Oracle, MySQL, etc.

• Developer databases• Use a single schema per developer if possible

• Be aware of the mismatch if you’re not using the same RDBMS in tests as in production

Page 54: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 54

Fake Remote Web Services with SoapUI & Spark• SOAP

• SoapUI has an API• REST

• Spark

setPort(5678);get("/hello", (request, response) -> {

return "Hello World!";});

Page 55: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 55

Mock Remote Web Services with Spring• In-memory mocks for remote Web Service endpoints

• Don’t actually connect to a server over the network

• SOAP – Spring Web Services• spring-ws-test module• MockWebServiceServer

• REST – Spring MVC REST• spring-test module• MockRestServiceServer

Page 56: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 56

DataSource pool exhaustion check• Set the maximum number of connections in the pool to 1

• Tests blow up fast if connections are not returned to pool

Page 57: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 57

Checking the database when a test failsIf a database related test is failing…

• Commit your transactions in your tests• Via @Commit or the TestTransaction API

• Use a clean setup strategy• Instead of a clean tear down strategy

• Use a file based database• Use persistent storage mode for embedded DBs• Inspect database state after failed test

Page 58: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 58

Testing is about Saving Money• Not about having more test coverage than your neighbor

• Think about ROI

Page 59: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 59

JUnit Lambda

Page 60: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 60

Give back to the project that’s given us so much!• JUnit is the de facto standard testing

framework in the Java ecosystem• Last major release 10 years ago• Times have changed: Java 8, etc.

• Introducing … JUnit Lambda … the crowdfunding campaign to help make the next major release of JUnit a reality

• Pitch in if you can, & help spread the word!• @JUnitLambda• https://www.indiegogo.com/projects/junit-lambda

Page 61: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 61

In closing…

Page 62: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 62

Spring ResourcesSpring Frameworkhttp://projects.spring.io/spring-framework

Spring Guideshttp://spring.io/guides

Spring JIRAhttps://jira.spring.io

Spring on GitHubhttps://github.com/spring-projects/spring-framework

Stack Overflowspring, spring-test, spring-mvc, spring-boot, spring-security, …

Page 63: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 63

Blogs

Spring Blog http://spring.io/blog

Swiftmind Blog http://www.swiftmind.com/blog

Nicolas Fränkel’s Blog https://blog.frankel.ch

Page 64: Get the Most out of Testing with Spring 4.2

© 2013-2015 Sam Brannen & Nicolas Fränkel and l icensed under a Creative CommonsAttr ibution-NonCommercial l icense: http:/ /creativecommons.org/ l icenses/by-nc/3.0/ 64

Sam Brannen

@sam_brannen www.slideshare.net/sbrannen www.swiftmind.com

Learn More. Stay Connected.

@springcentral Spring.io/video Nicolas Fränkel

@nicolas_frankel