• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Automated tests - facts and myths
 

Automated tests - facts and myths

on

  • 343 views

The discussion on automated tests is hot topic. The approach has same number of advocates and skeptics. More and more tools eases testing, but also introduces a fundamental question: what, when and ...

The discussion on automated tests is hot topic. The approach has same number of advocates and skeptics. More and more tools eases testing, but also introduces a fundamental question: what, when and how to test? Practise and experience let's answer those questions or guide in the right direction.

In this talk usage examples of unit, functional and behavioral tests will be shown. Importance of properly handling dependencies and mocking them will be discussed as well. But most of important part will be hints on how to write code, that could be tested automaticaly.

Slides are available in interactive mode here: http://tdd.sznapka.pl/

Statistics

Views

Total Views
343
Views on SlideShare
343
Embed Views
0

Actions

Likes
1
Downloads
3
Comments
0

0 Embeds 0

No embeds

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

    Automated tests - facts and myths Automated tests - facts and myths Presentation Transcript

    • Automated tests Facts and myths Wojciech Sznapka / @sznapka
    • Cześć
    • 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
    • Test Driven Development What is this?
    • Add a test
    • Write an implementation
    • Refactor code
    • Repeat!
    • What's important here?
    • ... to have tests
    • You won’t go to hell if you’ll write a test after declaring an interface or prototyping a class ...
    • ... but you’ll surely end up in hell, if there won’t be a test coverage
    • Myths about automated tests
    • Boss doesn't pay for automated tests
    • 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
    • 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; } } } }
    • ... 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'); } }
    • ... provide some meat ... casRmnovreTs etnsPPntFaeokTsCs ls oaCnetret xed HUi_rmwr_etae { /*@aarvdrpoieetaa* * dtPoie rvdTsDt / pbi fnto tsCnesos$rbc $oa) ulc ucin etovrin(aai, rmn { $ovre =nwRmnovre(; cnetr e oaCnetr) $hs>setqas$oa,$ovre-cnet$rbc) ti-asrEul(rmn cnetr>ovr(aai); } } pbi fnto poieetaa) ulc ucin rvdTsDt( { rtr ary eun ra[ [47 'MCXVI] 39, MMDCI', [,'',[,'I] [,'I] [,'X] [0 'L] 1 I] 2 I', 6 V', 9 I', 4, X', [5 'L',[0 'C] [0,'',[0,'D] 4, XV] 9, X', 10 C] 40 C' ] ; }
    • ... test edge cases casRmnovreTs etnsPPntFaeokTsCs ls oaCnetret xed HUi_rmwr_etae { /*@xetdxeto naiAgmnEcpin* * epceEcpin Ivldruetxeto / pbi fnto tsEpy) ulc ucin etmt( { (e Rmnovre)>ovr(wfIa psighr') nw oaCnetr-cnet't m asn ee); } }
    • Help yourself with tests generation ppntsegn-ts Rmnovre hui-kle -et oaCnetr
    • ... or using Symfony's XSolveUnitSkelgenBundle .apcnoexov:kle:etAm/xmlBnl/evc/ /p/osl slesegnts ceEapeudeSrie. .apcnoexov:kle:etAm//otolr* /p/osl slesegnts ce*Cnrle/
    • We are building too complicated system for an automated tests
    • TDD forces you to write cleaner code
    • It's easier to test smaller units of code
    • so you write smaller classes which are less coupled and that makes your system more stable and open for an extension in the future
    • Your Object Oriented design becomes S.O.L.I.D. compilant and this is awesome!
    • You will of course tackle costly dependencies
    • Use PHPUnit's mock framework or Mockery
    • 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 } }
    • 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
    • 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
    • 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(;
    • We providing API for external consumers it can't be tested...
    • Use Symfony's WebTestCase to test your API I call it integration tests
    • 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)
    • Use fixtures and reset environment IsolatedTestsTrait should do the trick
    • 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
    • Requirements changes frequently we can't keep up with unit tests
    • Use behavioral approach Behat in PHP
    • Describe features as scenarios It will be readable for: business, developers and machines
    • Perfectly fits into Agile process
    • 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
    • Our tests are slow!
    • This could be true ...
    • Always use in-memory sqlite database Or create clean sqlite database and copy it for every test
    • Group your tests Use PHPUnit's @group or Behat's @tag
    • Create "smoke tests" groups Those should be fast test, which ensures your system is most likely stable
    • Slower tests should run during night
    • Facts
    • It gives you confidence about changes and your code
    • Team is able to rapidly experiment with code
    • TDD enforces better Object Oriented design Smaller units of code and lower coupling always leads to better understanding of the codebase by future devs
    • End user experiences better quality lower 500 error ratio in the production
    • Happier users ↓ more $$$ in future
    • Conclusion
    • Setting up an working environment for automated tests is timely costly at the begining, but it pays off in the future
    • System without any kind of automated tests has big potential to be a big ball of mud
    • Good coverage can be easily achieved with mix of unit, functional and behavioral tests
    • You need to build and cultivate TDD culture in your surrounding
    • Thank you so much for attending! Feedback is much appreciated wojciech@sznapka.pl Twitter: @sznapka GitHub: @wowo
    • Join XSolve team :-)