test first!
TRANSCRIPT
TestDrivenDevelopment
WhatisTDD• It'sadevelopmenttechniquebasedonashortdevelopment
process• It'sawaytodeeplyanalyzetheexpectedbehaviorofasoftware• It'sameantoimprovethequalityofthesourcecode• It'sapracticetoenhancethedocumentationofasoftware• It'sawaytoensureasaferwaytomodifythesoftwarebehavior
TDDandUnitTests
Unittestscanbewrittenbeforewritingthecode,afterthecodehasbeenwrittenorduringthedevelopment
• UnitTestingreferstowhatyouaretesting,TDDtowhenyouaretesting
• UnitTestingmeans,well,testingindividualunitsofbehavior
TheDintheMiddle• Youlettheteststodriveyou• Theteststellyouwhattodo,whattodonext,what'sdone• ThetestsaretheskeletonoftheAPIdesign
TDDWorkflow
TDDWorkflowTDDiswritingatestwhichwillfail,thenwritingtheminimum
amountofcoderequiredtomakeitrun,thenrefactoringthecodetomakeitclean
TheDattheEnd• It'ssupposedtomeandevelopmentbutoriginallywassupposed
tomeandesign• TestDrivenDesignisthedisciplineofusingUnitTesting(or
othertests)todesignthesoftware• Workingonabetterdesignit'spossibletoimprovethequalityof
thesoftware
SmallandTestable• Methodsandfunctionsshouldbesimpleinordertobetestable• Generallyspeaking,thecodeneededtosatisfyatestisusuallyaverysmallchunkofcode• AsaresultthepublicAPIaresimpleandeasytomaintain
TestDoubleThegeneralnameforobjectsusedtoreplacerealcomponentservers
fortestingpurposes
• Dummy,anobjectwithoutanyspecificimplementation• Stub,anobjectwithinterfaceorminimalimplementation
• Spy,astepupfromstubbecauseitrecordswhichobjectuseditself
• Fake,anobjectwithamorecompleximplementation• Mock,anobjectdynamicallycreatedbyalibrary(e.g.
http://sinonjs.org)
CommonSentences• “Itcoststoomuchtime,we’dbetterfixthesebugsfirst”
• “Oursystemistoobigforunittests”• “Wejustoughttobemorecarefulnottointroducebugs,that
willhelpusalot”• “Oursystemisnotsuitedforunittests”
• “WehaveaQA-teamthatwilldetecterrors”
TDDandQA• Testdrivendevelopmentisnotaqualityassurancemethod• Mostpeopleassociate"testing"with"qualityassurance"
• WithTDDyouwritecodeusingtestsasatool,theQAteamsearchesbugsusingthesametestsasatool
BestPractices
Assertions• Assertionsarestatementsthatperformanactualcheckonthesoftware’soutput• Asinglefunctioncalledassertisenoughtoexpressanycheck• TDDlibrarieshavemanyassertfunctionsforspecificneeds(assertFalse,assertEqual,s,etc.)• Asingleassertshouldbeusedineachtest• Anassertfailureshouldaddaclearmessagetothetestlogs
IntegrationTesting• Amid-leveltestingactivitythatverifiesacertainsetofmodulesworkcorrectlytogether• Integrationtestsarelikeunittestswithoutusingtestdoublesforsomedependencies
Source&TestsSeparation
PicktheFirstTest• Carefullyreadtherequirementsandeventuallysplitthemifneeded• Choosearequirementandwritealistoftestsforthisrequirement• Selectatestthatisatomicandwellisolated• Trytoprioritizethem(e.g.testfirstusercreationthanlogin!)
WritetheAssertionFirst
Determinehowthespecification(i.e.thetest)isgoingtobevalidated
FirstTimeFailure• Howtotestsomethingthatdoesn'texist?• Byaddingmethodsorfunctionstotestdevelopersstarttodesignfirstthecode
UnitTesting(UnitTestingreferstowhatyouaretesting,TDDtowhenyouare
testing)
Glossary
Glossary• Unit,thesmallestpieceofcodesoftwarethatcanbetestedin
isolation• Assertion,it'sapredicatethatstatestheprogrammer’s
intendedstateofasystem• Integrationtest,atestthatgooutsidethecurrentprocess
interactingwithsomethingelse• Interactiontest,atestonthewaythatobjectsworktogether• Fake,anystand-inobjectthat'susedinsteadoftherealthing• Stub,astand-inobjectthatprovidesadependencyrequiredby
thecodeundertest• Mock,asimulatedobjectthatmimicsaspecificbehavior
IndividualUnits• Sourcecodeistestedtounderstandifitcanbeusedbyother
partofthesoftware• Testcasesareseparatedandindependentbyeachother
• Methodstubs,mockobjectsandfakesdatacanbeusedtorunthetestsinisolation
Benefits• Helpsfindingproblemsearly
• Facilitateschanges(i.e.regressionstesting)• Simplifiesintegration
• Improvesthedocumentation
Limitations• Unittestingwillnotcatcheveryerrorintheprogram
• Integrationerrorswillbenotcatchbecausethetestitselfbydefinitiontestonlytheunit
• Codecoveragedoesn'tprovethesoftwareisworking• It'stimeconsuming
CommonChallenges• Settinguprealisticandusefultests
• Testingasynchronouscode• Testingprivatemethods• Writingflexibletests
• Effectivenames
Usefulness• Definerelevantinitialconditions
• Testshavetoexercisingthecodeinarealisticcontext• Avoidunnecessarypreconditions
• Don’tunit-testconfigurationsettings
Flexibility• Testsshouldneveroverspecifythebehaviorofthetargetcode• Testsshouldnevertestmorethanoncethesamecode(i.e.
don'trepeatyourself!)• Alwaysuseonlydatarelevanttoaparticulartestinthetest• Consideralwayshowtopassinputdata(e.g.Builderpattern)
AsyncCode• Themainissueistokeepthetestblockeduntiltheasynccode
hasbeenexecuted• Youcanrepeatedlypollingthetargetsystemforastatechange
(i.e.Sampling)• Youcanuseanevent-basedassertionthatwaitsforaneventby
blockingonamonitoruntilitgetsnotifiedortimesout(i.e.Listening)
PrivateMethods
Eventshandler,alsoifprivate,areyourpublicAPI
• Putthetestsintheclassyouwanttotest• Putthetestsinanotherclass/sourcefile&exposetheprivate
methodsyouwanttotestaspublicmethods
Naming• Thenameshouldclearlyindicatethetestedfeature
• Thetestnameshouldindicateswhattheunitdoesnotwhattheunitis
• Thetestnameshouldsaysomethingaboutthemotivationforthescenario
• UsetheTestDoxconventionwhereeachtestnamereadslikeasentence
AcceptanceTestDriven
Development
KeyFeatures• ATDDisapracticeinwhichthewholeteamcollaboratively
discussesrequirementsacceptability• ATDD,likeTDD,involvescreatingtestsbeforecode
• Theacceptanceteststhenbecomelikeexecutablerequirements
ExpectedBenefits• ATDDresultsinapplicationsdesignedtobeeasiertotest
• ATDDfavorsthecreationofinterfacesspecifictofunctionaltesting
• ATDDclarifytoalltheteammemberswhicharethecustomerexpectations
ATDDandUnitTesting
• ATDDdoesn'timplytoremoveunittestingfromthedevelopmentcycle
• ATDDimpliestheusageoftoolstoautomatethefunctionaltestingexecution(e.g.FitNess,Cucumber,Rspec)
TestingPyramid
Software
SoftwareRequirements
Asa<role>Iwantto<goal>sothat<motivation>
• Userstoriesarethecentralaxisaroundwhichasoftwareprojectrotates
• UserstoriesexpressrequirementsintermsofTheRole,TheGoal,andTheMotivation
• Userstoriesaren’texhaustiverequirementsspecifications
AcceptanceCriteria• Asetofconditionstherequirementmustfitintobeconsidered
done• It'stheresultofaconversationwiththecustomer(orproduct
owner)• It'sawaytodescribethetestsarequirementshouldpass
WritingAcceptanceCriteria
• AnacceptancecriteriashouldcontainanActor,aVerbandanObservableResult
• Anacceptancecriteriadescribeapre-condtionwhenanactorshouldperformanactionandobtaintheexpectedresult(e.g.
mandatoryfields)• Anacceptancecriteriashouldbealsoidentifyperformances
expectations
AcceptanceTests
Concreteexamples,concretebehavior,noambiguity
• Aformaldescriptionofthebehaviorofasoftwareproductexpressedasanexample
• Arethecombinationofacceptancecriteriaandrealexamples(i.e.dataandscenarios)
ATDDCycle
ATDDCycle
BehaviorDrivenDevelopment
KeyFeatures• Helptowriteteststhatreflectthebehaviordesiredbythe
stakeholders• UsesaUbiquitousLanguagethatcanbeunderstoodbyboththe
developerandthecustomer
TestDifferent• Unittestingforcedeveloperstothinkintermsoftestsandassertionswhilebehaviordrivendevelopmentbringthemto
considertestsaspartofspecification• Whenyourealizethatit'sallaboutspecifyingbehaviorandnot
writingtests,yourpointofviewshifts
It’sStillTDD?NothinginBehavior-DrivenDevelopmentchangesTestDriven
Development’smechanics(i.e.writethetest->passit->refactor)
BDDandCodeDesign
• Unittestingisoftenspecificallyaboutthedesignofcodeunitsandmodulessuchasclasses
• BDDisalsoconcernedwithunitdesign,butaddressesabroaderrangeofdesignconcerns
BDDandAcceptanceCriteria
• Acceptancecriteriaaretransformedintolower-levelspecificationswrittenincode,andexecutedusingatestingor
specificationframework
SignofUse• Significantportionof"functionaldocumentation"isintheformofUserStoriesaugmentedwithexecutablescenariosorexamples• Insteadofreferringto"tests",teammemberswillpreferthe
terms"scenario"and"specification"• Testsareameantodefinethespecificationsofthebehaviorof
aModule
CommonIssues• BDDrequiresfamiliaritywithagreaterrangeofconceptsthan
UnitTestingdoes• BDDdon'trequiresatthebeginningparticulartoolsor
programminglanguages,andisprimarilyaconceptualapproach• BDDrequiresadifferentdevelopmentcycle
BDDCycle
ContextandSpecifications
• Setsofrelatedobservations(tests)willbegatheredintocontexts
• Contextsaren’tsimplyarbitrarygroupings,theyrepresentcohesiveandconsistentcircumstancesthatsoftwaremodulescan
befoundin• SpecificationsarethetestswrittenusingaBDDtesting
framework
EffectiveScenarios• Captureasummaryscenario• Identifyactorsandtheirgoals
• Sentencesshouldbeinsequentialorder• Eachsentenceshouldhaveanactorperforminganaction
UnitTesting,ATDDandBDD
BDDisanevolutionoftest-drivendevelopmentthatenhanceandenforcethepracticesderivingfromunittestingandacceptance
testing
TDD===BDD
TestsAnatomy
UnitTeststest("prettydatebasics",function(){varnow="2008/01/2822:25:00";equal(prettyDate(now,"2008/01/2822:24:30"),"justnow");equal(prettyDate(now,"2008/01/2822:23:30"),"1minuteago");equal(prettyDate(now,"2008/01/2821:23:30"),"1hourago");equal(prettyDate(now,"2008/01/2722:23:30"),"Yesterday");equal(prettyDate(now,"2008/01/2622:23:30"),"2daysago");equal(prettyDate(now,"2007/01/2622:23:30"),undefined);});
ATDDTests
BDDTestsfunctionaddValues(a,b){returna+b;}
describe("addValues(a,b)function",function(){it("shouldequal3",function(){expect(addValues(1,2)).toBe(3);});it("shouldequal3.75",function(){expect(addValues(1.75,2)).toBe(3.75);});it("shouldNOTequal'3'asaString",function(){
Jasmine(JavaScripttestingsuite)
JasmineProvides• AnaturalBDDsyntaxfororganizingthetestlogic
• Asynchronoustestingsupport• Mocksobject
• Spies• Custommatchers
SampleTestdescribe("Helloworld",function(){it("sayshello",function(){expect(helloWorld()).toEqual("Helloworld!");});});
Suite• describe("Helloworld"...)iswhatiscalledasuite• Thenameofthesuite(“Helloworld”inthiscase)definesacomponentofyourapplication
Spec• Insideofthatsuite(technically,insideofananonymous
function),istheit()block• Thisiscalledaspecification,oraspecforshort
Matcher• Inthiscase,you’retestingifhelloWorld()doesindeedreturn
"Helloworld!"• Thischeckiscalledamatcher...Jasminesupportsseveralmatchers!
Specs.htmlItcontainsfourscripttags:
• ThefirstsectionincludestheJasminetestrunnerfiles• Inthenexttwosections,youreferenceyourJavaScriptcodeto
betestedaswellasthetests• Thefourthrunsthetests
AsyncCallsit("doesanasynchronouscall",function(){
exampleAsyncCall(function(response){expect(response).toContain("somethingexpected");done();});
});RunningTestswith
RunningTestswithGrunt
• AJavaScripttaskrunner• Aprojectscaffoldingtool• Useittoautomatecommontaskexecutionexecution• Configurablepluginssuchasrequire.js,handlebar,jasmine,etc.
• Configurablepluginssuchasrequire.js,handlebar,jasmine,etc.
UsingGrunt• Firstofallinstallgruntcommandlinetoolnpminstall-ggrunt-cli
• Mostgrunt-inittemplateswillautomaticallycreateapackage.jsonfile
• Installgruntanthepluginsnpminstallgrunt--save-dev• Installthejasminepluginnpminstallgrunt-contrib-jasmine--save-dev
TheGrunt.jsFilemodule.exports=function(grunt){'usestrict';grunt.initConfig({jasmine:{src:'src/**/*.js',options:{specs:'spec/**/*.js',template:require('grunt-template-jasmine-istanbul'),templateOptions:{coverage:'reports/coverage.json',report:'reports/coverage'}
Questions&Answers
Links
Links• http://msdn.microsoft.com/en-us/magazine/cc163358.aspx
• http://guide.agilealliance.org/guide/atdd.html• http://guide.agilealliance.org/guide/acceptance.html
• http://www.codemag.com/article/0805061• http://www.slideshare.net/nashjain/acceptance-test-driven-
development-350264• http://testobsessed.com/wp-
content/uploads/2011/04/atddexample.pdf• http://programmers.stackexchange.com/questions/135218/what-
is-the-difference-between-bdd-and-tdd• http://www.slideshare.net/emwendelin/test-your-javascriptMyLatestBook
• http://www.slideshare.net/emwendelin/test-your-javascriptMyLatestBook
What'sNext