Effective out-of-container Integration Testing
Upcoming SlideShare
Loading in...5
×
 

Effective out-of-container Integration Testing

on

  • 3,220 views

Modern application frameworks like Spring promote a POJO-based programming model, and POJOs are inherently easy to unit test. But how can we effectively integration test our application outside the ...

Modern application frameworks like Spring promote a POJO-based programming model, and POJOs are inherently easy to unit test. But how can we effectively integration test our application outside the container while still getting as close to a production-like environment as possible? This session will show attendees how to approximate a target production environment using the Spring TestContext Framework to drive fast, repeatable, "out-of-container" integration tests. To simulate a live system, the session will cover open source integration testing techniques such as the use of in-memory databases, JMS providers, and Servlet containers as well as mock SMTP and FTP servers.

Statistics

Views

Total Views
3,220
Slideshare-icon Views on SlideShare
3,201
Embed Views
19

Actions

Likes
1
Downloads
57
Comments
0

3 Embeds 19

http://www.swiftmind.com 15
http://www.techgig.com 2
http://swiftmind.kundf.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Effective out-of-container Integration Testing Effective out-of-container Integration Testing Presentation Transcript

    • Effective out-of-container Integration Testing
 Sam
Brannen
 Swi+mind
GmbH

    • Speaker
Profile
•  Senior
So+ware
Consultant
–
Swi+mind
GmbH
•  Java
developer
with
13+
years
experience
•  Spring
Framework
Core
Developer
 –  Author
of
the
Spring
TestContext
Framework

•  Previous
SpringSource
dm
Server™
developer
•  Regular
speaker
at
conferences
on
Spring,
dm
 Server,
Java,
OSGi,
and
tesOng
•  Lead
author
of
Spring
in
a
Nutshell;
 chief
technical
reviewer
for
Spring
Recipes

    • Agenda
•  Background
•  Goals
of
IntegraOon
TesOng
•  The
Challenge
•  Proposed
SoluOon
•  DI
and
IoC
as
Enablers
•  SimulaOng
a
ProducOon
Environment
•  Spring
TestContext
Framework
•  Q&A

    • Background

    • Types
of
Tests
•  unit
tests
•  integraOon
tests
 –  
component
interacOon:
mulOple
units
 –  
cross‐process
interacOon:
database,
mail,
etc.
•  system
tests
 –  end‐to‐end
tesOng
with
live
systems
•  user
acceptance
tests

    • Unit
Tests
•  are
simple
to
set
up
•  use
dynamic
mocks
or
stubs
for
dependencies
•  instanOate
the
SUT
and
test
it
•  run
fast
•  but
only
test
a
single
unit

    • IntegraOon
Tests
•  test
interacOons
between
mulOple
 components
•  relaOvely
easy
to
set
up
without
external
 system
dependencies
•  challenging
to
set
up
with
external
system
 dependencies
•  more
challenging
when/if
applicaOon
code
 depends
on
the
container

    • Modern
Enterprise
Java
ApplicaOons
•  Integrate
with
external
systems
 –  SMTP,
FTP,
LDAP,
RDBMS,
Web
Services,
JMS
•  Rely
on
container‐provided
funcOonality
 –  data
sources,
connecOon
factories,
transacOon
 manager

    • Goals
of
Integra3on
Tes3ng

    • EffecOve
IntegraOon
TesOng
•  Fast
•  Repeatable
•  Automated
•  Easy
to
configure
•  Provide
good
code
coverage
of
end‐to‐end
 business
use
cases

    • Out‐of‐container
•  Zero
reliance
on
availability
of
external
 systems
•  Can
be
run
anywhere
 –  developer
workstaOon
 –  CI
server
•  Approximate
a
target
producOon
environment

    • The
Challenge

    • How
can
we
effec9vely
integraOon
test
an
enterprise
Java
applicaOon...
outside
the
container...
while
sOll
ge_ng
as
close
as
possible
to
a
producOon‐like
environment?

    • Proposed
Solu3on

    • Approximate
the
producOon
 environment
by...
•  Using
open
source
libraries
and
frameworks
to
 simulate
 –  a
single
external
system
dependency,
or
 –  mulOple
external
system
dependencies
•  Using
the
Spring
TestContext
Framework
to
 drive
fast,
out‐of‐container
integraOon
tests
 –  with
simulated
external
systems
started
in‐ memory

    • DI
and
IoC
as
Enablers
Dependency
Injec9on
and
Inversion
of
Control
collec9vely
decouple
applica9on
code
from
the
deployment
environment.

    • DI
and
IoC

Increase
Testability
•  Dependencies
are
injected,
not
explicitly
 instanOated
 –  Not
only
for
applicaOon
components,
but
also
for
 infrastructure
components
•  JNDI
look‐ups
for
container
provided
resources
 –  EJBs,
data
sources,
connecOon
factories,
etc.
•  Programming
to
interfaces
 –  Allows
us
to
transparently
swap
implementaOons

    • Simula3ng
a
Produc3on
Environment

    • Step
1
•  Ensure
your
applicaOon
configuraOon
can
be
 split
into:
 –  applicaOon‐specific
configuraOon
 •  business
logic
 •  service
layer,
repository
layer,
etc.
 –  environment‐specific
configuraOon
 •  infrastructure

    • Step
2
•  Ensure
environment‐specific
components
can
 be
easily
overridden
in
test
configuraOon
–
for
 example,
by
using
well
defined
bean
IDs.
 –  DataSource:
dataSource
 –  PladormTransacOonManager:
 transac9onManager
 –  JMS
ConnecOonFactory:
connec9onFactory

    • Step
3
•  Use
open
source
replacements
for
 environment‐specific
components
 –  preferably
configurable
via
Spring
 ApplicaOonContext
 –  typically
in‐memory
(a.k.a.,
embedded
mode)

    • Open
Source
Frameworks
for
 Embedded
Use

    • Database
•  Use
an
in‐memory
database
such
as
 –  HSQL,
H2,
or
Derby
•  Spring
3.0
provides
explicit
support
for
 –  Embedded
databases
 –  PopulaOng
exisOng
databases

    • Embedded
Database
in
XML
<jdbc:embedded-database id="dataSource" type="H2"> <jdbc:script location="classpath:/my-schema.sql" /> <jdbc:script location="classpath:/my-data.sql" /> </jdbc:embedded-database> Or simply… <jdbc:embedded-database id="dataSource" />

    • Embedded
Database
in
Code
private EmbeddedDatabase db; @Before public void launchDatabase() { db = new EmbeddedDatabaseBuilder()
 .addDefaultScripts()
 .build(); } // tests … @After public void shutdownDatabase(){ db.shutdown(); }
    • Populate
Database
in
XML
<jdbc:initialize-database data-source="dataSource"> <jdbc:script location="classpath:/schema_01.sql" /> <jdbc:script location="classpath:/schema_02.sql" /> <jdbc:script location="classpath:/data_01.sql" /> <jdbc:script location="classpath:/data_02.sql" /> </jdbc:initialize-database>

    • JMS
•  Use
an
in‐memory
message
broker
such
as
 AcOveMQ
•  AcOveMQ
can
be
easily
configured
in
a
Spring
 ApplicaOonContext
•  Versions
>
4.1
even
provide
an
<amq
/>
XML
 namespace
for
DSL‐like
configuraOon

    • AcOveMQ
Spring
ConfiguraOon
<bean id="connectionFactory" class= "org.apache.activemq.spring.ActiveMQConnectionFactory” p:brokerURL="vm://localhost?broker.persistent=false" /> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="connectionFactory" />

    • SMTP
Server
•  Use
Dumbsters
SimpleSmtpServer
 –  Configurable
port
number
 –  Tracks
all
mails
sent

 –  Provides
methods
for
retrieving
 •  Number
of
mails
sent
 •  Individual
mails
 •  Mail
headers
 •  Mail
body

    • AbstractEmailSenderTest
(1/2)
public abstract class AbstractEmailSenderTest { protected SimpleSmtpServer server; @Before public void startSmtpServer() { server = SimpleSmtpServer.start(getSmtpPort()); } @After public void stopSmtpServer() { server.stop(); } protected abstract int getSmtpPort();
    • AbstractEmailSenderTest
(2/2)
protected void assertNumEmailsSent(SimpleSmtpServer server, int expected) { assertEquals("Verifying number of e-mails sent.”, expected, server.getReceivedEmailSize()); } protected void assertEmailHeaderValue(SmtpMessage email, String header, String expected) { assertEquals(expected, email.getHeaderValue(header)); } protected void assertEmailBodyContains(SmtpMessage email, String expected) { assertTrue(email.getBody().contains(expected)); }
    • PlainEmailSenderTest
(1/2)
@ContextConfiguration("/applicationContext.xml") public class PlainEmailSenderTest extends AbstractEmailSenderTest { @Autowired private PlainEmailSenderImpl plainEmailSender; @Override protected int getSmtpPort() { return 62525; }
    • PlainEmailSenderTest
(2/2)
@Test public void plainEmail() throws Exception { plainEmailSender.sendSimpleEmail(recipientEmail); assertNumEmailsSent(server, 1); SmtpMessage email = (SmtpMessage) server.getReceivedEmail().next(); assertEmailHeaderValue(email, "Subject", "testing"); assertEmailHeaderValue(email, "From", "foo@bar.com"); assertEmailBodyContains(email, "This is a test email"); }
    • FTP
Server
•  Use
MockFtpServers
 –  FakeFtpServer
 •  Virtual
or
in‐memory
file
system
 •  User
accounts
and
permissions
 –  StubFtpServer
 •  Low‐level
FTP
server
commands

    • Servlet
Container
•  Use
Jeny
or
Tomcat
in
embedded
mode
•  Configure
Jeny
with
Maven
and
execute
the
 jeny:run
goal

    • ConfiguraOon
Tips
•  Externalize
connecOon
se_ngs
in
Java
 ProperOes
files
•  Define
different
ProperOes
files
for
producOon
 and
tesOng
•  Use
Springs
PropertyPlaceholderConfigurer
or
 <context:property‐placeholder>
for
property
 replacement

    • Avoid
Hostname
&
Port
Collisions
•  Pay
special
anenOon
to
hostnames
and
ports
 –  SMTP
 –  FTP
 –  Servlet
container
•  Consider
using
something
like
Springs
 FreePortScanner

    • Demo
Embedded
HSQL
database
with
Spring’s
<jdbc
/>
namespace
HibernateEventRepositoryTests

    • Demo
JMS
with
an
in‐memory
AcOveMQ
message
broker
JmsNamespaceTest

    • Demo
Email
with
Dumbster’s
SimpleSmtpServer
PlainEmailSenderTest

    • Demo
Embedded
Jeny
Servlet
container
AbstractJeKyTest

    • Further
Resources
•  HSQLDB
 –  hnp://hsqldb.org
•  H2
 –  hnp://www.h2database.com
•  AcOveMQ
 –  hnp://acOvemq.apache.org
•  Dumbster
 –  hnp://quintanaso+.com/dumbster
•  MockFtpServer
 –  hnp://mock+pserver.sourceforge.net
•  Jeny
 –  hnp://jeny.codehaus.org
•  Tomcat
 –  hnp://tomcat.apache.org

    • Q&A
Sam
Brannen
sam.brannen
[at]
swi+mind
[dot]
com
hnp://www.swi+mind.com
hnp://twiner.com/sam_brannen
“Spring
in
a
Nutshell” hnp://oreilly.com/catalog/9780596801946
 available
from
O’Reilly
in
2011