You are on page 1of 54

Minimalist Testing Techniques for Enterprise Java Technologybased Applications

Chris Richardson Author of POJOs in Action Chris Richar son Consu!tin"# $nc %%%&chrisrichar son&net
TS-4439
2007 JavaOneSM Conference | Session TS-4439 |

What ou Will !earn"

'ast( thin"s can ha))en to (ou %hen (ou on*t %rite tests

#$T

$t isn*t too ifficu!t to %rite a fe% fast runnin" tests

2007 JavaOneSM Conference | Session TS-4439|

About Chris
+ ,re% u) in -n"!an + .ive in Oa/!an # CA + 20 (ears of soft%are eve!o)1ent e2)erience
+ OO eve!o)1ent since 0934 + Java5 )!atfor1 since 0994 + Java P!atfor1# -nter)rise - ition 6Java --7 since 0999

+ Author of POJOs in Action + S)ea/er at JavaOneSM conference# JavaPo!is# '8JS# S9 :est# J;,s#< + Chair of the e=$, Java S$, in Oa/!an 6%%%&e>i"&or"7 + Run a consu!tin" an trainin" co1)an( that he!)s or"ani?ations >ui! >etter soft%are faster
2007 JavaOneSM Conference | Session TS-4439| 3

Agenda
When %evelopers Write Tests 8ast 8ee >ac/ $s -ssentia! =usiness Tier Tests Persistence Tier Tests :e> Tier Tests ,ettin" Starte

2007 JavaOneSM Conference | Session TS-4439|

The &tate of %eveloper Testing


+ 6A!1ost7 -ver(>o ( a"rees that auto1ate tests are "oo i ea
=;T T@P$CA..@

+ 9eve!o)ers on*t %rite tests + AA oes 61anua!7 testin"

2007 JavaOneSM Conference | Session TS-4439|

'bstacles to %eveloper Testing


+ Cu!tura! o>stac!es to testin"
+ + + + Perceive as e2tra %or/ that is AA*s res)onsi>i!it( ;nnecessar(BCM( co e a!%a(s %or/sD 'ot a!%a(s re%ar e B)ara o2 of e2ce!!enceE So1ethin" ne% to !earn

+ Technica! o>stac!es to testin"


+ S)a"hetti co e + So1e fra1e%or/s 1a/e testin" ifficu!t + 8ra1e%or/ eve!o)ers 1ust consi er testa>i!it(

2007 JavaOneSM Conference | Session TS-4439|

Edit and (ray %evelopment


+ @ou can )erha)s !ive %ith fe% tests at the start of a )roFect + =ut ver( Guic/!( (ou nee to chan"e e2istin" co e# an eve!o)1ent s!o%s o%n
+ 'o testsB1a/e chan"es ver( carefu!!( + .ots of 1anua! testin"

+ More >u"s .on" ni"hts# stress#< + @our a))!ication eca(s


+ 'o one has confi ence or ti1e to refactor co e + -ven s!o%er )ro"ress + -ventua!!( (ou nee to thro% it a%a( an start over
2007 JavaOneSM Conference | Session TS-4439| 7

#ut if ou Write Tests"


+ 8e%er >u"s that i1)act custo1ers and eve!o)1ent + :rite ne% co e 1ore easi!(
+ Auto1ates %hat %e are oin" a!rea (Bri"htHE + Run fast unit tests instea of s!o%er %e> a))!ication + ;se T99 to incre1enta!!( so!ve a )ro>!e1

+ Tests are a safet( net


+ Confi ent!( chan"e e2istin" co e + -asier to refactor co e to )revent eca( + The a))!ication has !on"er# hea!thier !ife
2007 JavaOneSM Conference | Session TS-4439| 8

('J's Ma)e Testing Easier


+ A P!ain O! Java O>Fect
+ 9oes not i1)!e1ent an( s)ecia! interfaces + 9oes not ca!! infrastructure AP$s + 9ecou)!es >usiness !o"ic fro1 infrastructure

+ 9e)en enc( inFection %ires co1)onents to"ether


+ Si1)!ifies co e + Pro1otes !oose cou)!in" >et%een co1)onents + Ma/es it eas( to )ass in 1oc/s for testin"

+ As)ects han !e cross-cuttin" concerns


+ Si1)!ifies co e that i1)!e1ents >usiness !o"ic + 9ecou)!es it fro1 infrastructure
2007 JavaOneSM Conference | Session TS-4439| 9

Agenda
:hen 9eve!o)ers :rite Tests *ast *eedbac) +s Essential =usiness Tier Tests Persistence Tier Tests :e> Tier Tests ,ettin" Starte

2007 JavaOneSM Conference | Session TS-4439|

10

*ast *eedbac) +s Essential


+ @ou chan"e a co1)!e2 interest ca!cu!ation + :hen o (ou %ant to fin out %hether it %or/sE
+ 0I 1inutes !ater after run %e> testsE + 00 secon s !ater after runnin" a hun re unit testsE
Web tier
Test Test

Test Test

Business Tier

Test

Test

Test Test

+ :rite unit tests at ever( !eve!


+ 8ast runnin" + -as( to re!ate test fai!ure %ith cause

Persistence Tier

Test

Test

Test Test

2007 JavaOneSM Conference | Session TS-4439|

11

*ast #uilds are Also Essential


+ $f (ou are "oo at %ritin" tests !ots of tests + ;nit tests run ver( Guic/!( >ut !ots of functiona! tests can ta/e a !on" ti1e to run + =ui! in" an testin" an a))!ication can >e s!o%
+ On so1e )ast )roFects it too/ 30-I0 1inutes + @et this ha to >e one )rior to chec/-in

+ ConseGuences
+ Chec/-in %as a >i" ea! rare!( one + 9eve!o)ers i n*t run tests >ro/en >ui! s
2007 JavaOneSM Conference | Session TS-4439| 12

'ne Reason for &lo, Tests - .oing 'utside of the /irtual Machine for the Java (latform 0J/M1 +nterface2
+ Tests that cross JJM interface >oun aries are "enera!!( s!o% + 9ata>ases are s!o%
+ Testin" at ever( !a(er hit the ata>ase over an over a"ain
WebTests

JVM
Web

ServiceTests

Service

+ :e> tests ten to >e s!o%


+ JavaServer Pa"es5 6JSP57 techno!o"( co1)i!ation ti1e + 'et%or/in"

DAOTests DAO

9ata>ase

The ter1s CJava Jirtua! MachineD an CJJMD 1ean a Jirtua! Machine for the Java5 )!atfor1
2007 JavaOneSM Conference | Session TS-4439| 13

Minimi3ing Test Times


+ So!utions
+ :rite !ots of fast runnin" tests# i&e& unit tests + Run ifferent tests at ifferent ti1es

+ 9eve!o)ers shou! run 1ain!( fast tests


+ 9urin" eve!o)1ent run 1ost!( unit tests + =efore chec/-in run so1e functiona! tests

+ Continuous inte"ration server


+ + + + Runs s!o%er >ut 1ore thorou"h tests =ut "ettin" fast fee >ac/ is a!so i1)ortant Consi er 1u!ti)!e !eve!s of C$ server testin" ;se a )ara!!e!i?e >ui! server
2007 JavaOneSM Conference | Session TS-4439| 14

Avoid the #oiled *rog (roblem


+ More eve!o)1ent 1ore tests !on"er test ti1es + Su en!(# the tests ta/e too !on" + =ut (ou on*t /no% ho% to fi2 it + =e vi"i!antH $nvest in re ucin" the >ui! ti1e %hen necessar(
2007 JavaOneSM Conference | Session TS-4439| 15

Agenda
:hen 9eve!o)ers :rite Tests 8ast 8ee >ac/ $s -ssentia! #usiness Tier Tests Persistence Tier Tests :e> Tier Tests ,ettin" Starte

2007 JavaOneSM Conference | Session TS-4439|

16

The E4ample #usiness !ogic


9oes it i1)!e1ent the >usiness ru!es correct!(E
MoneyTransferService BankingTransaction transfer(fromId, toId, amount)

BankingTransaction Repository addTransaction()

Banking Transaction amount date

from to

Account balance debit(amount) credit(amount)

Account Repository findAccount(id)

<<interface>> OverdraftPolicy

oOverdraft Policy

!i"ited Overdraft limit

2007 JavaOneSM Conference | Session TS-4439|

17

Testing a ('J' %omain 'b5ect


public class Account { private String accountId; private double balance; private OverdraftPolicy overdraftPolicy; public double getBalance() { return balance; } public void debit(double amount) { } public void credit(double amount) { }
public class Account!ests e"tends !est#ase { private Account account; public void set$p() { account % Account&ot'er (ma)eAccount(*+(+); } public void test,normal() { assert&oney-.uals(*+(+/ account(getBalance()); account(debit(0); assert&oney-.uals(0(+/ account(getBalance()); account(credit(*+); assert&oney-.uals(*0(+/ account(getBalance()); }

Re!ative!( eas( to %rite tests that run >!in in"!( fast

2007 JavaOneSM Conference | Session TS-4439|

18

#ut 6o, to Test a &ervice7


public class &oney!ransferServiceImpl implements &oney!ransferService { private final Account1epository account1epository; private final Ban)ing!ransaction1epository ban)ing!ransaction1epository; public &oney!ransferServiceImpl(Account1epository account1epository/ Ban)ing!ransaction1epository ban)ing!ransaction1epository) { t'is(account1epository % account1epository; t'is(ban)ing!ransaction1epository % ban)ing!ransaction1epository; } public Ban)ing!ransaction transfer(String fromAccountId/ String toAccountId/ double amount) t'ro2s &oney!ransfer-"ception { Account fromAccount % account1epository(findAccount(fromAccountId); Account toAccount % account1epository(findAccount(toAccountId); fromAccount(debit(amount); toAccount(credit(amount); !ransfer!ransaction t"n % ne2 !ransfer!ransaction(fromAccount/ toAccount/ amount/ ne2 3ate()); ban)ing!ransaction1epository(add!ransaction(t"n); return t"n; }

9ata>ase access

2007 JavaOneSM Conference | Session TS-4439|

19

The &lo, Way8 Write +ntegration Tests


+ -ach test
+ $nitia!i?es the ata>ase + Ca!!s the service + Jerifies state of ata>ase

+ =ut !ots of ata>ase accesses s!o% test + ReGuire !ots of setu)


+ Settin" u) the ata>ase + $nitia!i?in" the ata>ase + <

+ $nte"ration tests are va!ua>!e >ut<


2007 JavaOneSM Conference | Session TS-4439| 20

*aster Testing ,ith Moc) 'b5ects


+ A 1oc/ o>Fect si1u!ates the rea! o>Fect
+ Returns va!ues or thro%s e2ce)tions + Jerifies that the e2)ecte 1etho s are ca!!e
MoneyTransfer ServiceTests

MoneyTransfer Service

+ ;sin" 1oc/s
+ Si1)!ifies tests Mock AccountRepository + S)ee s u) tests + -na>!es an o>Fect to >e findAccount() teste in iso!ation + -na>!es to)- o%n eve!o)1ent
2007 JavaOneSM Conference | Session TS-4439| 21

Mock BankingTransaction Repository addTransaction()

Creating Moc)s
+ :rite (our o%n 1oc/s
+ Si1)!e for interfaces >ut it >eco1es te ious + Ko% to 1oc/ concrete c!assesE

+ ;se a 1oc/ o>Fect fra1e%or/


+ FMOCL# -as(Moc/

+ Create an confi"ure 1oc/ o>Fect


+ S)ecif( e2)ecte 1etho an ar"u1ents + 9efine 1etho >ehaviorM return va!ue or thro% e2ce)tion
2007 JavaOneSM Conference | Session TS-4439| 22

Moc) 'b5ects E4ample8 (art 9


public class &oney!ransferService!ests e"tends !est#ase { protected void set$p() t'ro2s -"ception { super(set$p(); account1epository % create&oc)(Account1epository(class); ban)ing!ransaction1epository % create&oc)(Ban)ing!ransaction1epository(class); service % ne2 &oney!ransferServiceImpl(account1epository/ ban)ing!ransaction1epository); fromAccount % Account&ot'er(ma)eAccount(*++); toAccount % Account&ot'er(ma)eAccount(4++); fromAccountId % fromAccount(getAccountId(); toAccountId % toAccount(getAccountId(); }

Create service %ith 1oc/s

2007 JavaOneSM Conference | Session TS-4439|

23

Moc) 'b5ects E4ample8 (art :


public class &oney!ransferService!ests e"tends !est#ase { public void test!ransfer,normal() { e"pect(account1epository(findAccount(fromAccountId))(and1eturn(fromAccount); e"pect(account1epository(findAccount(toAccountId))(and1eturn(toAccount); ban)ing!ransaction1epository(add!ransaction(isA(Ban)ing!ransaction(class)); replay(account1epository/ ban)ing!ransaction1epository); Ban)ing!ransaction result % service(transfer(fromAccountId/ toAccountId/ 0+); assert5ot5ull(result); assert&oney-.uals(0+(+/ fromAccount(getBalance()); assert&oney-.uals(40+(+/ toAccount(getBalance()); verify(account1epository/ ban)ing!ransaction1epository); }

2007 JavaOneSM Conference | Session TS-4439|

24

%o,nsides of Moc)s
+ Testin" the co!!a>oration of o>Fects N %hite >o2 testin" + Tests can >e >ritt!e
+ Chan"e esi"n %ithout chan"in" %hat it oes fai!in" tests + 9iscoura"es eve!o)ers fro1 %ritin" tests

+ 8ortunate!(# 1an( co!!a>orations are sta>!e


+ e&"& >et%een services an re)ositories

+ Moc/ se!ective!(H

2007 JavaOneSM Conference | Session TS-4439|

25

Agenda
:hen 9eve!o)ers :rite Tests 8ast 8ee >ac/ $s -ssentia! =usiness Tier Tests (ersistence Tier Tests :e> Tier Tests ,ettin" Starte

2007 JavaOneSM Conference | Session TS-4439|

26

(ersistence Tier Components


<<interface>> Account Repository <<interface>> BankingTransaction Repository

Can 1( a))!ication create# fin # u) ate an e!ete )ersistent o>FectsE 9oes the ata en u) in the correct ta>!eOco!u1nE

#ibernate AccountRepository

#ibernate BankingTransaction Repository

!ibernate"ma##ing #ackage$%net&c!risric!ardson&banking'(am#le&domain% default"access$%field%) class name$%Account% table$%BA*+,A--./*T% ) id name$%id% column$%A--./*T,I0%) generator class$%nati1e% 2) 2id) #ro#ert3 name$%balance% column$%BA4A*-'% 2) 2class) & 2!ibernate"ma##ing)

#ibernate

Session

$uery

2007 JavaOneSM Conference | Session TS-4439|

27

The &lo, Way to Test


+ :rite !ots of tests that >an" a"ainst the ata>ase
+ + + + $nitia!i?e the ata>ase .oa an o>Fect Save an o>Fect Jerif( the state of the ata>ase

+ 9ra%>ac/s
+ .ots of ata>ase access s!o% + 'ee to initia!i?e the ata>ase ifficu!t to %rite

+ :e sti!! nee so1e tests !i/e this >ut %e can o >etter<


2007 JavaOneSM Conference | Session TS-4439| 28

Avoid the %# ;98 Moc) the 'RM *rame,or)


+ Pro>!e1
+ =u"s in the !o"ic of the 9AOs + Testin" a"ainst the ata>ase is s!o%
6ibernateAccount %A'Tests test8in Account67

+ So!ution
+ Moc/ the ORM fra1e%or/ AP$s

6ibernateAccount %A' fin Account6i 7

Moc) 6ibernate

2007 JavaOneSM Conference | Session TS-4439|

29

Avoid the %# ;:8 Test the '<R Mapping


+ Pro>!e1
+ $ncorrect!( efine 1a))in"# + e&"& for"ettin" to 1a) a fie! is a co11on >u" + =ut tests that save o>Fects an chec/ the contents of the 9= are s!o% to e2ecute an te ious to %rite + Rea PM. OORM an 1a/e assertions a>out it + ORM;nit fra1e%or/ 1a/es this eas( to o

+ So!ution

class Ban)ing&apping!ests e"tends 6ibernate&apping!ests { public void testAccount() { assert#lass&apping(Account(class/ 7BA58,A##O$5!7); assertAll9ields&apped(); }
2007 JavaOneSM Conference | Session TS-4439| 30

*aster Tests ;98 $se an +n-memory %#


+ 8or e2a1)!eM KSA.9= + T()ica!!( 1uch faster than a tra itiona! 9=
+ Co11ittin" transactions + Recreatin" the sche1a

+ 'o insta!!Bit*s Fust a Java Archive 6JAR7 fi!e + OORM N 9= )orta>i!it( 1a/es this eas( + $ssues
+ 9ifficu!t to o if usin" han -co e SA. + So1e inco1)ati>i!itiesM e&"& ti1e )recision

2007 JavaOneSM Conference | Session TS-4439|

31

*aster Tests ;:8 Rollbac) Transactions


+ -2ecute entire test in a transaction# %hich is ro!!e >ac/ + Tests run faster + .eaves the ata>ase unchan"e + $ssues to consi er
+ Sin"!e transaction Sin"!e SessionO-ntit(Mana"er )otentia!!( ver( ifferent >ehavior + Co11it-ti1e constraints not chec/e + Co e in a ifferent JJM interface can*t see the chan"es
2007 JavaOneSM Conference | Session TS-4439| 32

%EM'
:a!/throu"h Persistence Tests Co e

2007 JavaOneSM Conference | Session TS-4439 |

33

Agenda
:hen 9eve!o)ers :rite Tests 8ast 8ee >ac/ $s -ssentia! =usiness Tier Tests Persistence Tier Tests Web Tier Tests ,ettin" Starte

2007 JavaOneSM Conference | Session TS-4439|

34

Web Tier %esign


9o the !in/s# >uttons an fie! s e2ist an >ehave as e2)ecte E
8TTP re9uest Web%tier Web%class%& J5P 6

Web%class%'

J5P 7

8TTP res#onse: 8TM42&

(((

&

J5; Managed Beans 5truts Action 5#ring MV- controllers &&


2007 JavaOneSM Conference | Session TS-4439| 35

Vie< Tem#lates: J5P, Velocit3,

$nit Test Web Components


+ Si1u!ate KTTP reGuest
+ + + + ReGuest )ara1eters Coo/ies Session state <

+ ;se 1oc/s for services + Jerif(


+ Service invocation + Jie% se!ection + 9ata )asse to vie%
2007 JavaOneSM Conference | Session TS-4439| 36

Web Application Testing


+ Si1u!ate a user c!ic/in" an t()in" in a >ro%ser + Su)erficia! tests
+ Test ha))( )aths + -as( %a( to test >asic functiona!it(

+ More thorou"h tests


+ Test !ots of ifferent scenarios + .ots of %or/

2007 JavaOneSM Conference | Session TS-4439|

37

Web Testing With &elenium


+ Se!eniu1
+ O)en source %e> a))!ication testin" too! + Tests run in a rea! >ro%ser 6$-O8irefo2O<7

+ Three co1)onents
+ Core N JavaScri)t5 techno!o"( !i>rar( that runs in the >ro%ser + $9- N 8irefo2 )!u"-in for recor in" an e2ecutin" tests + Re1ote Contro! 6RC7 N fra1e%or/ for %ritin" auto1ate tests in JavaO&'-TORu>(O<

2007 JavaOneSM Conference | Session TS-4439|

38

&elenium RC=Code E4ample


public :eb!est e"tends { public void set$p() t'ro2s -"ception { selServer % ne2 SeleniumServer(); selServer(start(); selenium % ne2 3efaultSelenium(7local'ost7/ selServer(getPort()/ 7;ie"plore7/ 7'ttp<==local'ost<>+>+7); selenium(start(); } public void test#reatePro?ect(Selenium selenium) { selenium(open(7=ptrac)=acegilogin(?sp7); selenium(type(7?,username7/ 7pro?,mgr7); selenium(type(7?,pass2ord7/ 7faces7); selenium(clic)(7@ogin7); }

2007 JavaOneSM Conference | Session TS-4439|

39

&tarting and &topping the Web Container


+ Testin" %ith an e1>e
+ e&"& Jett( + Avoi s havin" to >ui! a :AR + T()ica!!( starts u) faster

e %e> container

+ Testin" %ith a %e> container in a se)arate JJM interface + ;se the Car"o o)en-source fra1e%or/
+ T()ica!!( s!o%er + ReGuires a :AR to >e >ui!t

+ $nsta!!sOstartsOsto)s %e> containers + 9e)!o(sOun- e)!o(s %e> a))!ications + Java AP$# Maven P!u"-in# Ant tas/s# $9- )!u"-ins
2007 JavaOneSM Conference | Session TS-4439| 40

Cargo E4ample
public :eb!est e"tends { public void set$p() t'ro2s -"ception { Aip$1@Installer installer % ne2 Aip$1@Installer( ne2 $1@(7'ttp<==apac'e(tradebit(com=(((=?a)artaBtomcatB0(+(4>(Cip7)/ ne2 9ile(temp3ir/ 7tomcatBinstall7)); installer(install(); !omcat0"Standalone@ocal#onfiguration config % ne2 !omcat0"Standalone@ocal#onfiguration( ne2 9ile(temp3ir/ 7tomcatBdeploy7)); config(setProperty(ServletPropertySet(PO1!/ 7>+>+7)); :A1 2ar % ne2 :A1(locate:A1(72ebapp=target=ptrac)(2ar7)); config(add3eployable(2ar); container % ne2 !omcat0"Installed@ocal#ontainer(config); 9ile 'ome % installer(get6ome(); container(set6ome('ome); container(start(); }

2007 JavaOneSM Conference | Session TS-4439|

41

%EM'
Revie% an Run Se!eniu1OCar"o Test Co e

2007 JavaOneSM Conference | Session TS-4439 |

42

&peeding $p Web Tests


+ :e> tests can >e s!o%
+ .ots of inter-)rocess co11unication + 9ata>ase access + JSP techno!o"( )a"e co1)i!ation

+ Mini1i?e start an sto)s of >ro%ser an %e> a))!ication


+ J;nit 9ecorator that starts >ro%serOserver once for a set of tests + Test', Q=eforeC!ass

+ 9on*t run a!! the %e> tests on eve!o)er*s es/to)# e&"&


+ On!( run e1>e e %e> container tests + On!( run a su>set of the tests

2007 JavaOneSM Conference | Session TS-4439|

43

Agenda
:hen 9eve!o)ers :rite Tests 8ast 8ee >ac/ $s -ssentia! =usiness Tier Tests Persistence Tier Tests :e> Tier Tests .etting &tarted

2007 JavaOneSM Conference | Session TS-4439|

44

.etting &tarted +ncrementally


+ -2istin" a))!ication N !ots of co e + $1)ractica! to sto) an create tests for ever(thin" + 'ee an incre1enta! strate"(

2007 JavaOneSM Conference | Session TS-4439|

45

+nstall Continuous +ntegration &erver 0+f you 6aven>t Already2


e&"& CruiseContro!

2007 JavaOneSM Conference | Session TS-4439|

46

Create &ome Web $+ Tests


+ ;se Se!eniu1 $9to create >asic tests
+ Push >uttons + C!ic/ !in/s + <

+ Run
+ =efore chec/-in + :ith CruiseContro!

2007 JavaOneSM Conference | Session TS-4439|

47

%EM'
Recor in" a :e> Test :ith Se!eniu1 $9-

2007 JavaOneSM Conference | Session TS-4439 |

48

Write More Tests When"


+ 8i2in" a >u"
+ :rite a functiona! %e> ;$ test + :rite a !o%-!eve! unit test

+ :or/in" on a co1)onent
+ :rite characteri?ation tests for e2istin" >ehavior + :rite so1e tests for the ne% >ehavior + Ma/e the tests )ass

2007 JavaOneSM Conference | Session TS-4439|

49

+f our Code - #ig #all of Mud


+ This %on*t sto) (ou %ritin" functiona! tests + =ut it*s ifficu!t to %rite unit tests

2007 JavaOneSM Conference | Session TS-4439|

50

&ummary
+ =a thin"s can ha))en %ithout tests
+ 9eve!o)1ent s!o%s o%n + The a))!ication eca(s + $t can >e a o%n%ar s)ira!

+ :ritin" so1e >asic tests isn*t that ifficu!t


+ + + + :rite tests for the POJO >usiness !o"ic Test the OROM 1a))in" 1eta ata ;se Se!eniu1 for %e> testin" $ncre1enta!!( %rite tests for e2istin" co e

+ Just o itH
2007 JavaOneSM Conference | Session TS-4439| 51

*or More +nformation


+ Sen e1ai! + ORM;nit %e>site
+ chrisQchrisrichar son&net + htt)MOOco e&"oo"!e&co1O)Oor1unitO + htt)MOOco e&"oo"!e&co1O)O)roFecttrac/O + %%%&chrisrichar son&net

+ ProFectTrac/ Sa1)!e Co e

+ M( %e>site for other resources + Other sessions

+ TS-7032B=ui! in" JavaServer 8aces A))!ications %ith S)rin" an Ki>ernate + =O8-7344BThe .on"-Tai! Treasure Trove + =O8-432IBTestin" :e> 2&0 8eatures# ;sin" Rea!-:or! A))!ications + TS-4I33BA vance -nter)rise 9e>u""in" TechniGues
2007 JavaOneSM Conference | Session TS-4439| 52

?@A

2007 JavaOneSM Conference | Session TS-4439 |

53

Minimalist Testing Techniques for Enterprise Java Technologybased Applications


Chris Richardson Author of POJOs in Action Chris Richar son Consu!tin"# $nc& %%%&chrisrichar son&net
TS-4439
2007 JavaOneSM Conference | Session TS-4439 |

You might also like