04-testing and object methodscharlie/courses/17-214/2020-spring/slides/20200123-testing and...the...
TRANSCRIPT
117-214
PrinciplesofSoftwareConstruction:Objects,Design,andConcurrency
TestingandObjectMethodsinJava
JoshBloch CharlieGarrod
217-214
Administrivia
• Homework1dueToday 11:59p.m.– Everyonemustreadandsignourcollaborationpolicy– TAswillbeavailabletohelpyou– Youhavelatedays,buyyoumightwanttosaveforlater
• Secondhomeworkwillbepostedshortly
317-214
KeyconceptsfromTuesday
• Interfaces-baseddesignsareflexible• Informationhidingiscrucialtogooddesign• Exceptionsarewaybetterthanerrorcodes• Usetry-with-resources;notmanualcleanup
417-214
Outline
I. Specifyingprogrambehavior– contractsII. Testingcorrectness– JunitandfriendsIII. OverridingObjectmethods
517-214
Whatisacontract?
• Agreementbetweenanobjectanditsuser• Includes–Methodsignature(typespecifications)– Functionalityandcorrectnessexpectations– Performanceexpectations
• Whatthemethoddoes,nothow itdoesit– Interface(API),notimplementation
• “Focusonconceptsratherthanoperations”
617-214
Methodcontractdetails
• Definesmethod’sandcaller’sresponsibilities• Analogy:legalcontract– Ifyoupaymethisamountonthisschedule…– Iwillbuildaroomwiththefollowingdetailedspec– Somecontractshaveremediesfornonperformance
• Methodcontractstructure– Preconditions:whatmethodrequiresforcorrectoperation– Postconditions:whatmethodestablishesoncompletion– Exceptionalbehavior:whatitdoesifpreconditionviolated
• Definescorrectnessofimplementation6
717-214
FormalcontractspecificationJavaModellingLanguage(JML)
/*@ requires len >= 0 && array != null && array.length == len;@@ ensures \result ==@ (\sum int j; 0 <= j && j < len; array[j]);@*/
int total(int array[], int len);
• Theoreticalapproach– Advantages
• Runtimechecksgeneratedautomatically• Basisforformalverification• Automaticanalysistools
– Disadvantages• Requiresalotofwork• Impracticalinthelarge• Someaspectsofbehaviornotamenabletoformalspecification
postcondition
precondition
817-214
Textualspecification- Javadoc
• Practicalapproach• Document– Everyparameter– Returnvalue– Everyexception(checkedandunchecked)– Whatthemethoddoes,including
• Purpose• Sideeffects• Anythreadsafetyissues• Anyperformanceissues
• Donot documentimplementationdetails
917-214
SpecificationsintherealworldJavadoc
/*** Returns the element at the specified position of this list.* * <p>This method is <i>not</i> guaranteed to run in constant time.* In some implementations, it may run in time proportional to the* element position.* * @param index position of element to return; must be non-negative and * less than the size of this list.* @return the element at the specified position of this list* @throws IndexOutOfBoundsException if the index is out of range* ({@code index < 0 || index >= this.size()})*/E get(int index);
(Nosideeffects)
postcondition
precondition
1017-214
Outline
I. Specifyingprogrambehavior– contractsII. Testingcorrectness– JunitandfriendsIII. OverridingObjectmethods
1117-214
Semanticcorrectnessadherencetocontracts
• Compilerensurestypesarecorrect(type-checking)– Preventsmanyruntimeerrors,suchas“MethodNotFound”and“Cannotaddboolean toint”
• Staticanalysistools(e.g.,SpotBugs)recognizemanycommonproblems(bugpatterns)– Overridingequals withoutoverridinghashCode
• Buthowdoyouensuresemanticcorrectness?
1217-214
Formalverification
• Usemathematicalmethodstoprovecorrectnesswithrespecttotheformalspecification
• Formallyprovethatallpossibleexecutionsofanimplementationfulfillthespecification
• Manualeffort;partialautomation;notautomaticallydecidable
"Testingshowsthepresence,nottheabsenceofbugs.”
Edsger W.Dijkstra,1969
1317-214
Testing
• Executingtheprogramwithselectedinputsinacontrolledenvironment
• Goals– Revealbugs,sotheycanbefixed(maingoal)– Assessquality– Clarifythespecification,documentation
“Bewareofbugsintheabovecode;Ihaveonlyproveditcorrect,nottriedit.”
DonaldKnuth,1977
1417-214
Who’sright,Dijkstra orKnuth?
• They’rebothright!• Pleasesee“Extra,Extra- ReadAllAboutIt:NearlyAllBinarySearchesandMergesorts areBroken”– Official“GoogleResearch”blog– http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
• Thereisnosilverbullet– Usealltoolsatyourdisposal
1517-214
Manualtesting?
• LiveSystem?• ExtraTestingSystem?• Checkoutput/assertions?• Effort,Costs?• Reproducible?
1617-214
Automatetesting
• Executeaprogramwithspecificinputs,checkoutputforexpectedvalues
• Setuptestinginfrastructure• Executetestsregularly– Afterevery change
1717-214
Unittests
• Unittestsforsmallunits:methods,classes,subsystems– Smallesttestablepartofasystem– Testpartsbeforeassemblingthem– Intendedtocatchlocalbugs
• Typicallywrittenbydevelopers• Manysmall,fast-running,independenttests• Fewdependenciesonothersystempartsorenvironment• Insufficient,butagoodstartingpoint
1817-214
JUnit
• Popularunit-testingframeworkforJava• Easytouse• Toolsupportavailable• Canbeusedasdesignmechanism
1917-214
KentBeckonautomatedtesting
“Functionalitythatcan’tbedemonstratedbyautomatedtestsimplydon'texist.”
2017-214
Selectingtestcases:commonstrategies
• Readspecification• Writetestsfor
– Representativecase– Invalidcases– Boundaryconditions
• Writestresstests– Automaticallygeneratehugenumbersoftestcases
• Thinklikeanattacker– Thetester’sgoalistofindbugs!
• Howmanytestshouldyouwrite?– Aimtocoverthespecification– Workwithintime/moneyconstraints
2117-214
JUnit conventions
• TestCasecollectsmultipletests(inoneclass)• TestSuitecollectstestcases(typicallypackage)• Testsshouldrunfast• Testsshouldbeindependent
• Testsaremethodswithoutparameterandreturnvalue• AssertErrorsignalsfailedtest(uncheckedexception)
• TestRunnerknowshowtorunJUnittests– (usesreflectiontofindallmethodswith@Testannotat.)
2217-214
Testorganization
• Conventions(notrequirements)• HaveatestclassFooTest foreachpublicclassFoo
• Haveasourcedirectoryandatestdirectory– StoreFooTest andFoointhesamepackage
– Testscanaccessmemberswithdefault(package)visibility
2317-214
Testablecode
• Thinkabouttestingwhenwritingcode• Unittestingencouragesyoutowritetestablecode• Modularityandtestabilitygohandinhand• Sametestcanbeusedonmultipleimplementationsofaninterface!
• Test-DrivenDevelopment– Adesignanddevelopmentmethodinwhichyouwritetestsbeforeyouwritethecode
– WritingtestscanexposeAPIweaknesses!
2417-214
Runtestsfrequently
• Youshouldonlycommitcodethatispassingalltests• Runtestsbeforeeverycommit• Iftestsuitebecomestoolarge&slowforrapidfeedback– Runlocalpackage-leveltests(“smoketests”)frequently– Runalltestsnightly– Mediumsizedprojectseasilyhavethousandsoftestcases
• Continuousintegrationservershelptoscaletesting
2517-214
Continuousintegration- TravisCI
Automatically builds, tests, and displays the result
2617-214
Continuousintegration- TravisCI
You can see the results of builds over time
2717-214
Outlook:statementcoverage
• Tryingtotestallpartsoftheimplementation• Executeeverystatement,ideally
• Does100%coverageguaranteecorrectness?
2817-214
Outline
I. Specifyingprogrambehavior– contractsII. Testingcorrectness– JunitandfriendsIII. OverridingObjectmethods
2917-214
Methodscommontoallobjects
• Howdocollectionsknowhowtotestobjectsforequality?• Howdotheyknowhowtohashandprintthem?• TherelevantmethodsareallpresentonObject– equals - returnstrueifthetwoobjectsare“equal”– hashCode - returnsanint thatmustbeequalforequalobjects,andislikelytodifferonunequalobjects
– toString - returnsaprintablestringrepresentation
3017-214
Object implementations
• Provideidentitysemantics– equals(Object o) - returnstrue ifo referstothisobject
– hashCode() - returnsanear-randomint thatneverchangesovertheobjectlifetime
– toString() - returnsanastylookingstringconsistingofthetypeandhashcode• Forexample:java.lang.Object@659e0bfd
3117-214
OverridingObject implementations
• (nearly)AlwaysoverridetoString– println invokesitautomatically–Whysettleforugly?
• Noneedtooverrideequals andhashCode ifyouwantidentitysemantics–Whenindoubt,don'toverridethem– It'seasytogetitwrong
3217-214
OverridingtoString
OverridingtoString iseasyandbeneficialfinal class PhoneNumber {
private final short areaCode;private final short prefix;private final short lineNumber;...
@Override public String toString() {return String.format("(%03d) %03d-%04d",
areaCode, prefix, lineNumber);}
}
PhoneNumber jenny = ...;System.out.println(jenny);Prints:(707) 867-5309
3317-214
Theequals contract
Theequalsmethodimplementsanequivalencerelation.Itis:– Reflexive:Foranynon-nullreferencevaluex,x.equals(x)must
returntrue.– Symmetric:Foranynon-nullreferencevaluesxandy,x.equals(y)
mustreturntrueifandonlyify.equals(x)returnstrue.– Transitive:Foranynon-nullreferencevaluesx,y,z,ifx.equals(y)
returnstrueandy.equals(z)returnstrue,thenx.equals(z)mustreturntrue.
– Consistent:Foranynon-nullreferencevaluesxandy,multipleinvocationsofx.equals(y)consistentlyreturntrueorconsistentlyreturnfalse,providednoinformationusedinequalscomparisonsontheobjectsismodified.
– Foranynon-nullreferencevaluex,x.equals(null)mustreturnfalse.
3417-214
Theequals contractinEnglish
• Reflexive – everyobjectisequaltoitself• Symmetric – if a.equals(b) thenb.equals(a)• Transitive – ifa.equals(b) andb.equals(c),thena.equals(c)
• Consistent– equalobjectsstayequalunlessmutated• “Non-null”– a.equals(null) returnsfalse• Takentogethertheseensurethatequalsisaglobalequivalencerelationoverallobjects
3517-214
equals OverrideExamplepublic final class PhoneNumber {
private final short areaCode;private final short prefix;private final short lineNumber;
@Override public boolean equals(Object o) {if (!(o instanceof PhoneNumber)) // Does null check
return false;PhoneNumber pn = (PhoneNumber) o;return pn.lineNumber == lineNumber
&& pn.prefix == prefix&& pn.areaCode == areaCode;
}
...}
3617-214
ThehashCode contract
Wheneveritisinvokedonthesameobjectmorethanonceduringanexecutionofanapplication,thehashCode methodmustconsistentlyreturnthesameinteger,providednoinformationusedinequalscomparisonsontheobjectismodified.Thisintegerneednotremainconsistentfromoneexecutionofanapplicationtoanotherexecutionofthesameapplication.– Iftwoobjectsareequalaccordingtotheequals(Object)method,thencallingthe
hashCode methodoneachofthetwoobjectsmustproducethesameintegerresult.
– Itisnotrequiredthatiftwoobjectsareunequalaccordingtotheequals(Object)method,thencallingthehashCode methodoneachofthetwoobjectsmustproducedistinctintegerresults.However,theprogrammershouldbeawarethatproducingdistinctintegerresultsforunequalobjectsmayimprovetheperformanceofhashtables.
3717-214
ThehashCode contractinEnglish
• Equalobjectsmusthaveequalhashcodes– Ifyouoverrideequals youmustoverridehashCode
• Unequalobjectsshould havedifferenthashcodes– Takeallvaluefieldsintoaccountwhenconstructingit
• Hashcodemustnotchangeunlessobjectmutated
3817-214
hashCode overrideexample
public final class PhoneNumber {private final short areaCode;private final short prefix;private final short lineNumber;
@Override public int hashCode() {int result = 17; // Nonzero is goodresult = 31 * result + areaCode; // Constant must be oddresult = 31 * result + prefix; // " " " " result = 31 * result + lineNumber; // " " " " return result;
}
...}
3917-214
AlternativehashCode overrideLessefficient,butotherwiseequallygood!
public final class PhoneNumber {private final short areaCode;private final short prefix;private final short lineNumber;
@Override public int hashCode() {return Objects.hash(areaCode, prefix, lineNumber);
}
...}
Aoneliner.NoexcuseforfailingtooverridehashCode!
4017-214
Formorethanyouwanttoknowaboutoverridingobjectmethods,seeEffectiveJavaChapter2
4117-214
The== operatorvs.equalsmethodreview
• Forprimitivesyoumust use==• Forobjectreferencetypes– The== operatorprovidesidentitysemantics• ExactlyasimplementedbyObject.equals• EvenifObject.equals hasbeenoverridden• Thisisseldomwhatyouwant!
– Youshould(almost)alwaysuse.equals– Using == onanobjectreferenceisabadsmellincode
if (input == "yes") // A bug!!!
4217-214
Summary
• Contractsspecifymethodbehavior– Documentthecontractofeverymethod
• Testearly,testoften!• AlwaysoverridetoString• Overrideequalswhenyouneedvaluesemantics• OverridehashCodewhenyouroverrideequals