This document discusses the importance of automated testing and provides tips for effective testing. It notes that while initial setup is time-consuming, automated tests pay off over time by increasing quality and preventing bugs. Tips include using SQLite for isolation, grouping tests by speed, mocking dependencies, and cultivating a test-driven culture. The document advocates for a mix of unit, functional and behavioral tests to achieve good coverage and ensure stability when refactoring code.
3. An introduction
I work in software industry for about 9 years
Care a lot about robust and testable architectures
Loves software craftsmanship, sophisticated architectures, Big Data
and ice hockey
15. It's a myth!
A 2005 study found that using TDD meant writing
more tests and, in turn, programmers who wrote
more tests tended to be more productive
by American Scientists
16. But this ain't that hard ...
casRmnovre
ls oaCnetr
{
poetd$ovrin =[
rtce cnesos
10 = '' 90= 'M,50= '' 40= 'D,10= ''
00 > M, 0 > C' 0 > D, 0 > C' 0 > C,
9 = 'C,5 = '' 4 = 'L,1 = ''
0 > X' 0 > L, 0 > X' 0 > X,
9= 'X,5= '' 4= 'V,1= '';
> I'
> V,
> I'
> I]
pbi fnto cnet$nrbc
ulc ucin ovr(iAai)
{
i (i_uei(iAai) {
f !snmrc$nrbc)
trwnwnaiAgmnEcpin' cnetnmrc';
ho e Ivldruetxeto(I ovr ueis)
}
i (iAai < 0 {
f $nrbc = )
rtr ';
eun '
}
ls (aai,$oa)=$hs>ovrinatro(iAai)
it $rbc rmn
ti-cnesoFcoFr$nrbc;
}
rtr $oa .$hs>ovr(iAai -$rbc;
eun rmn
ti-cnet$nrbc
aai)
poetdfnto cnesoFcoFr$nrbc
rtce ucin ovrinatro(iAai)
{
frah(ti-cnesosa $rbc= $oa){
oec $hs>ovrin s aai > rmn
i (aai < $nrbc {
f $rbc = iAai)
rtr [aai,$oa]
eun $rbc rmn;
}
}
}
}
17. ... start from obvious things
casRmnovreTs etnsPPntFaeokTsCs
ls oaCnetret xed HUi_rmwr_etae
{
pbi fnto tsEpy)
ulc ucin etmt(
{
$hs>setqas',(e Rmnovre)>ovr(')
ti-asrEul(' nw oaCnetr-cnet');
}
}
29. Fake it till you make it
casMceTs etnsPPntFaeokTsCs
ls okdet xed HUi_rmwr_etae
{
pbi fnto tsNnxsigauOjcs)
ulc ucin etoEitnVlebet(
{
$ofgrto =okr:mc(ofgrtoVlebet,[
cniuain
Mcey:ok'CniuainauOjc'
'eUl = 'tp/tdsnpap'
gtr' > ht:/d.zak.l,
'eFra'= 'm')
gtomt > xl];
$hs>setqas'm' $ofgrto-gtomt);/ O
ti-asrEul(xl, cniuain>eFra() / K
}
}
30. Mock things
that can't be tested quickly or nonreproducable
casMceTs etnsPPntFaeokTsCs
ls okdet xed HUi_rmwr_etae
{
pbi fnto tsAial(
ulc ucin etpCls)
{
$uzok okr:mc(uzBosr)
bzMc= Mcey:ok'Bzrwe';
$uzok>hudeev(gt)
bzMc-solRcie'e'
-adeun'rsos>mo>wsmt<mo>/epne';
>nRtr(<epne<odAeoiy/od<rsos>)
/ ti as i ws slto,t wiexlfxue i fl
/ hs lo s ie ouin o rt m itrs n ie
/ $uzok>hudeev(gt)>ne)
/ bzMc-solRcie'e'-oc(
/
/
-adeunfl_e_otns_DR_.'fxue.m')
>nRtr(iegtcnet(_I_
/itrsxl);
}
}
$p =nwpCnue(bzMc)
ai
e Aiosmr$uzok;
$p-asrEul(Aeoiy,$p-gturnMo() / O
ai>setqas'wsmt' ai>eCretod); / K
31. Expect declared behaviors
casMceTs etnsPPntFaeokTsCs
ls okdet xed HUi_rmwr_etae
{
pbi fnto tsEpcainDcaain(
ulc ucin etxettoselrtos)
{
$uzok okr:mc(uzBosr)
bzMc= Mcey:ok'Bzrwe';
$uzok>hudeev(gt)
bzMc-solRcie'e'
-adeun'rsos>mo>wsmt<mo>/epne';
>nRtr(<epne<odAeoiy/od<rsos>)
$ogrok=okr:mc(oooogr)
lgeMc
Mcey:ok'MnlgLge';
/ w js wn t b sr ta Lge:if wscle ol oc
/ e ut at o e ue ht ogr:no a ald ny ne
$ogrok>hudeev(if'-oc(;
lgeMc-solRcie'no)>ne)
}
}
$p =nwpCnue(bzMc,$ogrok;
ai
e Aiosmr$uzok lgeMc)
$p-asrEul(Aeoiy,$p-gturnMo() / O
ai>setqas'wsmt' ai>eCretod); / K
32. Be prepared for failures
and check if you prepared for unexpected situations
casMceTs etnsPPntFaeokTsCs
ls okdet xed HUi_rmwr_etae
{
/*@xetdxeto yxetoWapr*
* epceEcpin MEcpinrpe /
pbi fnto tsFieCneto(
ulc ucin etaldoncin)
{
$uzok okr:mc(uzBosr)
bzMc= Mcey:ok'Bzrwe';
$uzok>hudeev(gt)
bzMc-solRcie'e'
-adho(uzEcpinCinEcpin)
>nTrw'Bzxetoletxeto';
$ogrok=okr:mc(oooogr)
lgeMc
Mcey:ok'MnlgLge';
$ogrok>hudeev(if'-nvr)
lgeMc-solRcie'no)>ee(;
$ogrok>hudeev(er)>ne)
lgeMc-solRcie'r'-oc(;
}
}
(e pCnue(bzMc,$ogrok)>eCretod)
nw Aiosmr$uzok lgeMc)-gturnMo(;
35. Call your API and check if it
returns prepared data
casEpniueotolretetnsWbetae
ls xedtrCnrleTs xed eTsCs
{
ueIoaeTssri;/ i rst ts evrnet
s sltdetTat / t ees et niomn
pbi fnto tsGtitnsn)
ulc ucin eteLsIJo(
{
$let=sai:cetCin(;
cin
ttc:raelet)
$let>eus(GT,'epniue.sn)
cin-rqet'E' /xedtrsjo';
$sn=jo_eoe$let>eRsos(-gtotn()
jo
sndcd(cin-gtepne)>eCnet);
}
}
$hs>setre$let>eRsos(-iScesu()
ti-asrTu(cin-gtepne)>sucsfl);
$hs>seton(0 $sn;
ti-asrCut8, jo)
$hs>setraeTaOEul
ti-asrGetrhnrqa(
nwaeie$sn7]>rae_t,
e DtTm(jo[9-cetda)
nwaeie$sn0-cetda);
e DtTm(jo[]>rae_t)
36. Use fixtures and reset
environment
IsolatedTestsTrait should do the trick
37. Steps required to effectively
run in isolation
1.
2.
3.
4.
5.
6.
7.
configure PDO SQLite in file
create database
drop schema
load fixtres
copy database as a backup
copy database from backup for every test
delete database backup after test suite
42. Simple example
Faue lo frajb
etr: ok o
o
I odrt fn co jb
n re o id ol o
A a aprn porme
s n siig rgamr
Ine t b al t ls jbofr
ed o e be o it o fes
Seai:ls ofr frP vrin
cnro it fes o L eso
GvnIa o ""
ie
m n /
Te Isol se"oązd tau
hn
hud e Dłc o em"
Adcik"oązd tau
n lc Dłc o em"
Te Isol b o "krea
hn
hud e n /air"
AdIsol se"H Sno Dvlpr(lwc)
n
hud e PP eir eeoe Giie"
Seai:n ofr frE st
cnro o fes o N ie
GvnIa o "e"
ie
m n /n
Te Isol ntse"oązd tau
hn
hud o e Dłc o em"
AdIsol ntsea "ji-s eeet
n
hud o e n #onu" lmn
52. TDD enforces better
Object Oriented design
Smaller units of code and lower coupling always leads to better
understanding of the codebase by future devs