effective out-of-container integration testing

Post on 10-May-2015

2.922 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

Effective out-of-container Integration Testing

SamBrannenSwi+mindGmbH

SpeakerProfile

•  SeniorSo+wareConsultant–Swi+mindGmbH•  Javadeveloperwith13+years'experience•  SpringFrameworkCoreDeveloper– AuthoroftheSpringTestContextFramework

•  PreviousSpringSourcedmServer™developer•  RegularspeakeratconferencesonSpring,dmServer,Java,OSGi,andtesOng

•  LeadauthorofSpringinaNutshell;chieftechnicalreviewerforSpringRecipes

Agenda

•  Background•  GoalsofIntegraOonTesOng•  TheChallenge•  ProposedSoluOon•  DIandIoCasEnablers•  SimulaOngaProducOonEnvironment•  SpringTestContextFramework•  Q&A

Background

TypesofTests

•  unittests•  integraOontests–  componentinteracOon:mulOpleunits

–  cross‐processinteracOon:database,mail,etc.

•  systemtests– end‐to‐endtesOngwithlivesystems

•  useracceptancetests

UnitTests

•  aresimpletosetup•  usedynamicmocksorstubsfordependencies

•  instanOatetheSUTandtestit•  runfast•  butonlytestasingleunit

IntegraOonTests

•  testinteracOonsbetweenmulOplecomponents

•  relaOvelyeasytosetupwithoutexternalsystemdependencies

•  challengingtosetupwithexternalsystemdependencies

•  morechallengingwhen/ifapplicaOoncodedependsonthecontainer

ModernEnterpriseJavaApplicaOons

•  Integratewithexternalsystems– SMTP,FTP,LDAP,RDBMS,WebServices,JMS

•  Relyoncontainer‐providedfuncOonality– datasources,connecOonfactories,transacOonmanager

GoalsofIntegra3onTes3ng

EffecOveIntegraOonTesOng

•  Fast•  Repeatable•  Automated

•  Easytoconfigure•  Providegoodcodecoverageofend‐to‐endbusinessusecases

Out‐of‐container

•  Zerorelianceonavailabilityofexternalsystems

•  Canberunanywhere– developerworkstaOon– CIserver

•  ApproximateatargetproducOonenvironment

TheChallenge

Howcanweeffec9velyintegraOontestanenterpriseJavaapplicaOon...

outsidethecontainer...

whilesOllge_ngascloseaspossibletoaproducOon‐likeenvironment?

ProposedSolu3on

ApproximatetheproducOonenvironmentby...

•  Usingopensourcelibrariesandframeworkstosimulate– asingleexternalsystemdependency,or– mulOpleexternalsystemdependencies

•  UsingtheSpringTestContextFrameworktodrivefast,out‐of‐containerintegraOontests– withsimulatedexternalsystemsstartedin‐memory

DIandIoCasEnablers

DependencyInjec9onandInversionofControlcollec9velydecoupleapplica9oncodefromthedeploymentenvironment.

DIandIoCIncreaseTestability

•  Dependenciesareinjected,notexplicitlyinstanOated– NotonlyforapplicaOoncomponents,butalsoforinfrastructurecomponents

•  JNDIlook‐upsforcontainerprovidedresources– EJBs,datasources,connecOonfactories,etc.

•  Programmingtointerfaces– AllowsustotransparentlyswapimplementaOons

Simula3ngaProduc3onEnvironment

Step1

•  EnsureyourapplicaOonconfiguraOoncanbesplitinto:– applicaOon‐specificconfiguraOon•  businesslogic•  servicelayer,repositorylayer,etc.

– environment‐specificconfiguraOon•  infrastructure

Step2

•  Ensureenvironment‐specificcomponentscanbeeasilyoverriddenintestconfiguraOon–forexample,byusingwelldefinedbeanIDs.– DataSource:dataSource– PladormTransacOonManager:transac9onManager

–  JMSConnecOonFactory:connec9onFactory

Step3

•  Useopensourcereplacementsforenvironment‐specificcomponents– preferablyconfigurableviaSpringApplicaOonContext

–  typicallyin‐memory(a.k.a.,embeddedmode)

OpenSourceFrameworksforEmbeddedUse

Database

•  Useanin‐memorydatabasesuchas– HSQL,H2,orDerby

•  Spring3.0providesexplicitsupportfor– Embeddeddatabases– PopulaOngexisOngdatabases

EmbeddedDatabaseinXML<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" />

EmbeddedDatabaseinCodeprivate EmbeddedDatabase db;

@Before public void launchDatabase() { db = new EmbeddedDatabaseBuilder() .addDefaultScripts() .build();}// tests …

@After public void shutdownDatabase() { db.shutdown();}

PopulateDatabaseinXML<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

•  Useanin‐memorymessagebrokersuchasAcOveMQ

•  AcOveMQcanbeeasilyconfiguredinaSpringApplicaOonContext

•  Versions>4.1evenprovidean<amq/>XMLnamespaceforDSL‐likeconfiguraOon

AcOveMQSpringConfiguraOon<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" />

SMTPServer

•  UseDumbster'sSimpleSmtpServer– Configurableportnumber

– Tracksallmailssent– Providesmethodsforretrieving•  Numberofmailssent

•  Individualmails•  Mailheaders

•  Mailbody

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)@Testpublic 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");}

FTPServer

•  UseMockFtpServer's– FakeFtpServer•  Virtualorin‐memoryfilesystem•  Useraccountsandpermissions

– StubFtpServer•  Low‐levelFTPservercommands

ServletContainer

•  UseJenyorTomcatinembeddedmode•  ConfigureJenywithMavenandexecutethejeny:rungoal

ConfiguraOonTips

•  ExternalizeconnecOonse_ngsinJavaProperOesfiles

•  DefinedifferentProperOesfilesforproducOonandtesOng

•  UseSpring'sPropertyPlaceholderConfigureror<context:property‐placeholder>forpropertyreplacement

AvoidHostname&PortCollisions

•  PayspecialanenOontohostnamesandports– SMTP

– FTP– Servletcontainer

•  ConsiderusingsomethinglikeSpring'sFreePortScanner

EmbeddedHSQLdatabasewithSpring’s<jdbc/>namespace

HibernateEventRepositoryTests

Demo

JMSwithanin‐memoryAcOveMQmessagebroker

JmsNamespaceTest

Demo

EmailwithDumbster’sSimpleSmtpServer

PlainEmailSenderTest

Demo

EmbeddedJenyServletcontainer

AbstractJeKyTest

Demo

FurtherResources•  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

SamBrannen

sam.brannen[at]swi+mind[dot]com

hnp://www.swi+mind.com

hnp://twiner.com/sam_brannen

“SpringinaNutshell” hnp://oreilly.com/catalog/9780596801946 availablefromO’Reillyin2011

top related