2014 joker - integration testing from the trenches
TRANSCRIPT
![Page 1: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/1.jpg)
Integration Testing from the Trenches
Nicolas Fränkel October 2014
![Page 2: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/2.jpg)
2https://leanpub.com/integrationtest
Me, myself and I
Developer & Architect as consultant
Wide range of businesses & customers
Teacher & Trainer
Speaker
Blogger
http://blog.frankel.ch/
(http://morevaadin.com/)
![Page 3: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/3.jpg)
3https://leanpub.com/integrationtest
Also an author
![Page 4: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/4.jpg)
4https://leanpub.com/integrationtest
Plan
Integration Testing
What is that?
Challenges
Solution hints
Testing with resource dependencies
Database
Web Services
Testing In-container
Spring & Spring MVC
JavaEE
![Page 5: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/5.jpg)
Basics
![Page 6: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/6.jpg)
6https://leanpub.com/integrationtest
There are many different kinds of testing
Unit Testing
Mutation Testing
Integration Testing
GUI Testing
Performance Testing
Load Testing
Stress Testing
Endurance Testing
Security Testing
etc.
![Page 7: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/7.jpg)
7https://leanpub.com/integrationtest
Unit Testing vs. Integration Testing
Unit Testing
Testing a unit (i.e. a class) in isolation
Integration Testing
Testing the collaboration of multiple units
"Sa
vate
fo
uet
té f
igur
e 1
" b
y D
an
iel -
Pho
to D
an
iel.
![Page 8: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/8.jpg)
8https://leanpub.com/integrationtest
A concrete example
Let’s take an example
A prototype car
"20
11 N
issa
n L
eaf
WA
S 2
011
104
0"
by
Ma
rio
rdo
Ma
rio
Ro
be
rto
Du
ran
Ort
iz -
Ow
n w
ork
![Page 9: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/9.jpg)
9https://leanpub.com/integrationtest
Unit Testing
Akin to testing each nut and bolt separately
![Page 10: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/10.jpg)
10https://leanpub.com/integrationtest
Integration Testing
Akin to going on a test drive
"UR
E0
5e
" b
y M
arv
in R
aaijm
ake
rs -
Ow
n w
ork
.
![Page 11: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/11.jpg)
11https://leanpub.com/integrationtest
Unit Testing + Integration Testing
Approaches are not exclusive but complementary
Would you take a prototype car on test drive without having tested only nuts and bolts?
Would you manufacture a car from a prototype having only tested nuts and bolts but without having tested it on numerous test drives?
![Page 12: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/12.jpg)
12https://leanpub.com/integrationtest
System Under Test
The SUT is what get tested
Techniques from Unit Testing can be re-used
Dependency Injection
Test doubles
![Page 13: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/13.jpg)
13https://leanpub.com/integrationtest
Testing is about ROI
The larger the SUT
The more fragile the test
The less maintainable the test
The less the ROI
Thus, tests have to be organized in a pyramidal way
The bigger the SUT
The less the number of tests
Integration Testing
Test standard cases
Generally not error cases htt
p://
mar
tinfo
wle
r.co
m/b
liki/T
est
Pyr
am
id.h
tml
![Page 14: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/14.jpg)
14https://leanpub.com/integrationtest
Integration Testing Challenges
Brittle
Dependent on external resources Database(s) etc.
Slow
Dependent on external resources
Hard to diagnose
![Page 15: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/15.jpg)
15https://leanpub.com/integrationtest
How to cope
Separate Integration Tests from Unit Tests
Fake required infrastructure resources
Test in-container
![Page 16: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/16.jpg)
16https://leanpub.com/integrationtest
But IT are still slow?!
Separating UT & IT doesn’t make IT run faster
But you can uncover errors from UT faster
Fail Fast
It will speed testing
"Ge
pard
jagt
2 (
Aci
no
nyx
jub
atu
s)"
by
Ma
len
e T
hys
sen
- O
wn
wo
rk.
![Page 17: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/17.jpg)
17https://leanpub.com/integrationtest
Integration Testing and build
Available tools
Ant
Maven
Gradle
etc.
New
Dev
elo
pm
en
t Re
cen
tly F
inis
he
d o
n B
rist
ol's
City
Ce
ntr
e b
y B
rizz
leb
oy
![Page 18: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/18.jpg)
18https://leanpub.com/integrationtest
Maven lifecycle
…
compile
…
test
…
pre-integration-test
integration-test
post-integration-test
verify
…
![Page 19: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/19.jpg)
19https://leanpub.com/integrationtest
Reminder on Surefire
Bound to the test phase
Runs by default
*Test
Test*
*TestCase
![Page 20: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/20.jpg)
20https://leanpub.com/integrationtest
Failsafe
“Copy” of Surefire
Different defaults
*IT
IT*
*ITCase
One goal per lifecycle phase
pre-integration-test
integration-test
post-integration-test
verify
Must be bound explicitly
![Page 21: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/21.jpg)
21https://leanpub.com/integrationtest
Binding Failsafe - sample
<plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>2.17</version> <executions> <execution> <id>integration-test</id> <goals> <goal>integration-test</goal> </goals> <phase>integration-test</phase> </execution> <execution> <id>verify</id> <goals> <goal>verify</goal> </goals> <phase>verify</phase> </execution> </executions></plugin>
![Page 22: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/22.jpg)
22https://leanpub.com/integrationtest
Continuous Integration
Needs a build configured
Suggestions
Unit Tests run at each commit
Integration Tests run “regularly” Daily Hourly Depending on the context
![Page 23: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/23.jpg)
Infrastructure dependencies
![Page 24: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/24.jpg)
24https://leanpub.com/integrationtest
Infrastructure dependencies
Database
Filesystem
Time
Message Oriented Middleware
Mail server
FTP server
etc.
![Page 25: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/25.jpg)
25https://leanpub.com/integrationtest
Mocks and infrastructure dependencies
To test your Service
Mock your DAO/repository Mockito
To test your DAO/repository
Mock your database???
![Page 26: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/26.jpg)
26https://leanpub.com/integrationtest
Simple database use-case
Oracle database
Use an in-memory datasource and hope for the best
Use Oracle Express and hope for the best
Use a dedicated remote schema for each developer And your DBAs will hate you
![Page 27: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/27.jpg)
27https://leanpub.com/integrationtest
Reducing database gap risk
In-memory databases are easy to setup
h2 is such a database
(successor of HSQL)
Compatibility modes for most widespread DB jdbc:h2:mem:test;MODE=Oracle
![Page 28: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/28.jpg)
28https://leanpub.com/integrationtest
Parameterizing properties
Use properties for tests only
db.url=
db.driver=
db.username=
db.password=
And use your favorite build tool
Maven Resource filtering
Ant
Gradle
![Page 29: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/29.jpg)
29https://leanpub.com/integrationtest
Integration Testing with Web Services
Web Services also are an infrastructure resource
Hosted on-site
Or outside
Different Web Services types have different solutions
RESTful
SOAP
![Page 30: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/30.jpg)
30https://leanpub.com/integrationtest
Faking RESTful WS
Require an HTTP server
Requirements
Easy setup
Standalone
Embeddable in tests
Spring MVC?
Requires a servlet container (Not with Spring Boot)
Some code to write
Aut
ho
r: D
wig
ht S
iple
r fr
om
Sto
w,
MA
, U
SA
![Page 31: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/31.jpg)
31https://leanpub.com/integrationtest
Spark to the rescue
Micro web framework
A la Sinatra
http://www.sparkjava.com/
Very few lines of code
Just wire to serve JSON files
![Page 32: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/32.jpg)
32https://leanpub.com/integrationtest
Spark sample
import static spark.Spark.*;import spark.*;
public class SparkSample{ public static void main(String[] args) { setPort(5678); get("/hello", (request, response) -> { return "Hello World!"; }); get("/users/:name", (request, response) -> { return "User: " + request.params(":name"); }); get("/private", (request, response) -> { response.status(401); return "Go Away!!!"; }); }}
![Page 33: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/33.jpg)
33https://leanpub.com/integrationtest
Faking SOAP web service
Possible to use Spark for SOAP
But unwieldy
![Page 34: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/34.jpg)
34https://leanpub.com/integrationtest
SOAPUI
SOAPUI is the framework to test SOAP WS
Has a GUI
Good documentation
Understands Authentication Headers Etc.
Can be used to Fake SOAP WS
![Page 35: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/35.jpg)
35https://leanpub.com/integrationtest
SOAPUI usage
Get WSDL
Either online
Or from a file
Create MockService
Craft the adequate response
Run the service
Point the dependency to localhost
![Page 36: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/36.jpg)
37https://leanpub.com/integrationtest
Challenges to the previous scenario
Craft the adequate response?
More likely get one from the real WS
And tweak it
Running in an automated way
Save the project
Get the SOAPUI jar
Read the project and launch
![Page 37: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/37.jpg)
38https://leanpub.com/integrationtest
SOAPUI automation
WsdlProject project = new WsdlProject();String wsdlFile = "file:src/test/resources/ip2geo.wsdl";WsdlInterface wsdlInterface = importWsdl(project, wsdlFile, true)[0];WsdlMockService fakeService = project.addNewMockService("fakeService");WsdlOperation wsdlOp = wsdlInterface.getOperationByName("ResolveIP");MockOperation fakeOp = fakeService.addNewMockOperation(wsdlOp);MockResponse fakeResponse = fakeOp.addNewMockResponse("fakeResponse");fakeResponse.setResponseContent( "<soapenv:Envelope ...</soapenv:Envelope>");runner = fakeService.start();
![Page 38: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/38.jpg)
39https://leanpub.com/integrationtest
Faking Web Service in real-life
Use the same rules as for UT
Keep validation simple
Test one thing One Assert Or a set of related ones
Keep setup simple
Don’t put complex logic Don’t put too much logic Don’t put logic at all
Duplicate setup in each test Up to a point
Aut
ho
r: I
, ro
lf B
![Page 39: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/39.jpg)
In-container Testing
![Page 40: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/40.jpg)
41https://leanpub.com/integrationtest
Upping the ante
Testing collaboration is nice
Faking infrastructure dependencies is nice
But didn’t we forget the most important dependency?
![Page 41: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/41.jpg)
42https://leanpub.com/integrationtest
The container!
“Proprietary” container
Spring
Application Server
Tomcat
JBoss
<Place your favorite one here>
![Page 42: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/42.jpg)
43https://leanpub.com/integrationtest
Spring
So far, we can test:
Beans which dependencies can be mocked (or not) Service
Beans that depend on fake resources Datasource
What about the configuration?
In Unit Tests, we set dependencies The real configuration is not used Ergo, not tested!
![Page 43: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/43.jpg)
44https://leanpub.com/integrationtest
Testing configuration
Configuration cannot be monolithic
Break down into fragments
Each fragment contains a set of either Real beans Fake beans
Rud
sto
n M
on
olith
Ma
y 2
013
by
An
ge
la F
ind
lay
![Page 44: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/44.jpg)
45https://leanpub.com/integrationtest
Data source configuration fragment management example
Different configuration fragments
Production JNDI fragment
Test in-memory fragment
![Page 45: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/45.jpg)
46https://leanpub.com/integrationtest
Data source configuration sample
<beans ...> <jee:jndi-lookup id="ds" jndi-name="jdbc/MyDS" /></beans>
<beans ...> <bean id="ds" class="o.a.t.jdbc.pool.DataSource"> <property name="driverClassName” value="org.h2.Driver" /> <property name="url" value="jdbc:h2:~/test" /> <property name="username" value="sa" /> <property name="maxActive" value="1" /> </bean></beans>
![Page 46: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/46.jpg)
47https://leanpub.com/integrationtest
Fragment structure
1. Main fragment
Repository
Service
etc.
2. Prod DB fragment
3. Test DB fragment
![Page 47: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/47.jpg)
48https://leanpub.com/integrationtest
Tips
Prevent coupling
No fragments reference in fragments
Use top-level assembly instead Tests Application Context Webapps
Pool exhaustion check
Set the maximum number of connections in the pool to 1
Compile-time safety
Use JavaConfig
Not related to testing
![Page 48: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/48.jpg)
49https://leanpub.com/integrationtest
And now, how to test?
Get access to both
The entry point
And the “end” point
Spring Test to the rescue
Integration with common Testing frameworks JUnit TestNG
St L
ou
is G
ate
wa
y A
rch
19
16"
by
Dirk
Be
yer
- O
wn
wo
rk.
![Page 49: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/49.jpg)
50https://leanpub.com/integrationtest
Favor TestNG
Extra grouping
Per layer
Per use-case
Name your own
Extra lifecycle hooks
Better parameterization
Data Provider
Ordering of test methods
![Page 50: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/50.jpg)
51https://leanpub.com/integrationtest
Spring TestNG integration
AbstractTestNGSpringContextTests
AbstractTransactionalTestNGSpringContextTests
Configurable context fragments
@ContextConfiguration
Inject any bean in the test class
If necessary, applicatonContext member from superclass
![Page 51: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/51.jpg)
52https://leanpub.com/integrationtest
Sample TestNG test with Spring
@ContextConfiguration( classes = { MainCfg.class, AnotherCfg.class })public class OrderIT extends AbstractTestNGSpringContextTests {
@Autowired private OrderService orderService;
@Test public void should_do_this_and_that() { orderService.order(); Assert.assertThat(...) }}
![Page 52: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/52.jpg)
53https://leanpub.com/integrationtest
Testing with the DB (or other transactional resources)
Transactions
Bound to business functionality
Implemented on Service layer
With DAO
Use explicit transaction management
@Transactional
![Page 53: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/53.jpg)
54https://leanpub.com/integrationtest
Transaction management tip
Tests fail… sometimes
How to audit state?
By default, Spring rollbacks transactions
General configuration
@TransactionConfiguration( defaultRollback = false)
Can be overridden on a per-method basis @Rollback(true)
![Page 54: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/54.jpg)
55https://leanpub.com/integrationtest
Sample Transaction management
@ContextConfiguration@TransactionConfiguration(defaultRollback = false)public class OverrideDefaultRollbackSpringTest extends AbstractTransactionalTestNGSpringContextTests {
@Test @Rollback(true) public void transaction_will_be_rollbacked() { ... }
@Test public void transaction_wont_be_rollbacked() { ... }}
![Page 55: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/55.jpg)
56https://leanpub.com/integrationtest
Spring MVC webapps Testing
Require a context hierachy
Parent as main context
Child as webapp context
@ContextHierarchy
Require a webapp configuration
@WebAppConfiguration
![Page 56: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/56.jpg)
57https://leanpub.com/integrationtest
Spring MVC test sample
@WebAppConfiguration@ContextHierarchy({ @ContextConfiguration(classes = MainConfig.class), @ContextConfiguration(classes = WebConfig.class)})public class SpringWebApplicationTest extends AbstractTestNGSpringContextTests { ...}
![Page 57: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/57.jpg)
58https://leanpub.com/integrationtest
Entry points for testing Spring webapps
At the HTML level
At the HTTP level
At the Controller level
Like standard Java testing
"La
hn
tun
ne
l Wei
lbu
rg"
by
rup
p.d
e -
Ow
n w
ork
.
![Page 58: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/58.jpg)
59https://leanpub.com/integrationtest
Tools for testing webapps
HTML testing tools
Interact with HTML/CSS Fill this field Click on that button
HTTP testing tools Send HTTP requests Get HTTP responses
![Page 59: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/59.jpg)
60https://leanpub.com/integrationtest
Drawback of previous approaches
Very low-level
Fragile!
Remember that testing is about ROI Breaking tests with every
HTML/CSS change is the worst way to have positive ROI
(There are mitigation techniques out of scope)
Attr
ibu
tion:
© M
ilan
Nyk
od
ym,
Cze
ch R
ep
ubl
ic
![Page 60: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/60.jpg)
61https://leanpub.com/integrationtest
Drawback of Testing with controllers as entry point
Bypass many URL-related features
Interceptors
Spring Security
etc.
Con
tro
ller
SC
SI.
JPG
by
Ro
sco
![Page 61: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/61.jpg)
62https://leanpub.com/integrationtest
Spring Test to the rescue
Spring Test has a large chunk dedicated to MVC
Since 3.2
Can test with URL as entry-points
Fluent API with static imports
Coa
stg
uar
d H
elic
op
ter
(80
160
50
677
)" b
y P
au
l Luc
as
fro
m L
eic
est
ersh
ire
, UK
- C
oas
tgu
ard
He
lico
pte
r
![Page 62: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/62.jpg)
63https://leanpub.com/integrationtest
Spring MVC Test overview
![Page 63: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/63.jpg)
64https://leanpub.com/integrationtest
MockMvc class responsibilities
Request builder
Configures the Fake request
Request matcher
Misc. assertions
Request handler
Do something OOB logger
![Page 64: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/64.jpg)
65https://leanpub.com/integrationtest
Available configuration on Request Builder
HTTP method
GET
POST
etc.
HTTP related stuff
Headers
Parameters
Content
JavaEE related stuff
Request attributes
Session
etc.
![Page 65: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/65.jpg)
66https://leanpub.com/integrationtest
Request Builder sample
MockHttpServletRequestBuilder builder =get("/customer/{id}", 1234L).accept("text/html").param("lang", "en").secure(true);
GET /customer/1234?lang=en HTTP/1.1 Accept: text/html
![Page 66: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/66.jpg)
67https://leanpub.com/integrationtest
You can use constants in your @RequestMapping
@Controllerpublic class MyController {
public static final String PATH = "/customer/{id}";
@RequestMapping(PATH)public String showCustomer() { ... }
}
MockHttpServletRequestBuilder builder = get(PATH, 1L);
![Page 67: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/67.jpg)
68https://leanpub.com/integrationtest
Some matchers
Checks result is a
Forward Either exact Or regexp
Redirect Either exact Or regexp
JSON payload
a s
afe
ty w
ax
ma
tch
bo
x a
nd
ma
tch
es
by
Aa
thav
an
jaffn
a
![Page 68: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/68.jpg)
69https://leanpub.com/integrationtest
Some other matchers
Request class
Handler class
Controller
Content class
Cookie class
Status class
HTTP code
Flash class
(Attributes, not the techno)
View class
Model class "Ove
jas
en
Pa
tag
onia
- A
rge
ntin
a"
by
wri
tte
carl
osa
nto
nio
![Page 69: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/69.jpg)
70https://leanpub.com/integrationtest
Spring Pet Clinic
![Page 70: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/70.jpg)
71https://leanpub.com/integrationtest
Integration Testing on Spring Pet Clinic
@WebAppConfiguration@ContextHierarchy({ @ContextConfiguration("classpath:spring/business-config.xml"), @ContextConfiguration("classpath:spring/mvc-core-config.xml")})@ActiveProfiles("jdbc")public class PetControlIT extends AbstractTestNGSpringContextTests {
@Test public void should_display_create_form() throws Exception { WebApplicationContext wac = (WebApplicationContext) applicationContext; MockMvc mvc = MockMvcBuilders.webAppContextSetup(wac).build(); MockHttpServletRequestBuilder newPet =
get("/owners/{ownerId}/pets/new", 1); mvc.perform(newPet) .andExpect(view().name("pets/createOrUpdatePetForm")) .andExpect(model().attributeExists("pet")); }}
![Page 71: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/71.jpg)
72https://leanpub.com/integrationtest
The JavaEE world
JavaEE has unique challenges
CDI has no explicit wiring You can @Veto you own
classes But no compiled ones
Different application servers Same specifications Different implementations
![Page 72: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/72.jpg)
73https://leanpub.com/integrationtest
Deploy only what you want
Standalone API to deploy only resources relevant to the test
Just pick and choose
Maven Integration
Gradle too…
![Page 73: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/73.jpg)
74https://leanpub.com/integrationtest
Shrinkwrap sample
String srcMainWebapp = "src/main/webapp/";ShrinkWrap.create(WebArchive.class, "myWar.war") .addClass(MyService.class) .addPackage(MyModel.class.getPackage()) .addAsWebInfResource("persistence.xml", "classes/META-INF/persistence.xml") .addAsWebInfResource( new File(srcMainWebapp, "WEB-INF/page/my.jsp"), "page/my.jsp") .addAsWebResource( new File(srcMainWebapp, "script/my.js"), "script/my.js") .setWebXML("web.xml");
![Page 74: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/74.jpg)
75https://leanpub.com/integrationtest
Maven integration sample
File[] libs = Maven.resolver() .loadPomFromFile("pom.xml") .importDependencies(COMPILE,
RUNTIME).resolve() .withTransitivity().asFile();
ShrinkWrap.create(WebArchive.class, "myWar.war") .addAsLibraries(libs);
![Page 75: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/75.jpg)
76https://leanpub.com/integrationtest
Different application servers
Abstraction layer to
Download
Deploy applications
Test
Container adapters
TomEE
JBoss
Weld
etc.
Full Maven integration
![Page 76: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/76.jpg)
77https://leanpub.com/integrationtest
Arquillian Test sample
public class ArquillianSampleIT extends Arquillian {
@Inject private MyService myService;
@Deployment public static JavaArchive createDeployment() { return ...; }
@Test public void should_handle_service() { Object value = myService.handle(); Assert.assertThat(...); }}
![Page 77: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/77.jpg)
78https://leanpub.com/integrationtest
Arquillian configuration sample
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="..." xsi:schemaLocation=" http://jboss.org/schema/arquillianhttp://jboss.org/schema/arquillian/arquillian_1_0.xsd"> <container qualifier="tomee" default="true"> <configuration> <property name="httpPort">-1</property> <property name="stopPort">-1</property> </configuration></arquillian>
![Page 78: 2014 Joker - Integration Testing from the Trenches](https://reader035.vdocuments.site/reader035/viewer/2022062308/55d57889bb61ebae2f8b45bf/html5/thumbnails/78.jpg)
https://leanpub.com/integrationtest
Twitter: @itfromtrenches