java for testers - index-of.co.ukindex-of.co.uk/programming/java for testers learn java...

291

Upload: others

Post on 06-Aug-2020

10 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to
Page 2: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

JavaForTesters

LearnJavafundamentalsfastThisversionwaspublishedon2015-02-27

TherightofAlanRichardsontobeidentifiedastheauthorofthisworkhasbeenassertedbyhiminaccordancewiththeCopyright,DesignandPatentsAct1988.

Theviewsexpressedinthisbookarethoseoftheauthor.

FirstpublishedinGreatBritainin2015by:

CompendiumDevelopmentshttp://www.compendiumdev.co.uk

contactdetails:

[email protected]

RelatedWebSites:

JavaForTesters:javaForTesters.comAuthor’sSoftwareTestingBlog:eviltester.comCompendiumDevelopments:compendiumdev.co.ukAuthor’sSeleniumBlog:seleniumSimplified.com

Everyefforthasbeenmadetoensurethattheinformationcontainedinthisbookisaccurateatthetimeofgoingtopress,andthepublishersandauthorcannotacceptanyresponsibilityforanyerrorsoromissions,howevercaused.Noresponsibilityforlossordamageoccasionedbyanypersonacting,orrefrainingfromaction,asaresultofthematerialinthispublicationcanbeacceptedbytheeditor,thepublisherortheauthor.

Apartfromanyfairdealingforthepurposesofresearchorprivatestudy,orcriticismorreview,aspermittedundertheCopyright,DesignandPatentsAct1988;thispublicationmayonlybereproduced,storedortransmitted,inanyformorbyanymeans,withthepriorpermissionofthepublishers,orinthecaseofreprographicreproductioninaccordancewiththetermsandlicensesissuedbytheCopyrightLicensingAgency,90TottenhamCourtRoad,London,W1T4LP.Enquiriesconcerningreproductionoutsidethesetermsshouldbesenttothepublishers.

e-bookISBN:978-0-9567332-4-5

©2013-2015AlanRichardson,CompendiumDevelopmentsLtd

Page 3: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Asever.ThisbookisdedicatedtoBillieandKeeran.

Page 4: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

TableofContents

IntroductionTestersuseJavadifferentlyExclusionsSupportingSourceCodeAbouttheAuthorAcknowledgments

ChapterOne-BasicsofJavaRevealedJavaExampleCode

ChapterTwo-InstalltheNecessarySoftwareIntroductionDoyoualreadyhaveJDKorMaveninstalled?InstallTheJavaJDKInstallMavenInstallTheIDECreateaProjectusingtheIDEAboutyournewprojectAddJUnittothepom.xmlfileSummary

ChapterThree-WritingYourFirstJavaCodeMyFirstJUnitTestPrerequisitesCreateAJUnitTestClassCreateaMethodMakethemethodaJUnittestCalculatethesumAssertthevalueRunthe@TestmethodSummaryReferencesandRecommendedReading

ChapterFour-WorkwithOtherClassesUse@TestmethodstounderstandJavaWarningsaboutIntegerSummaryReferencesandRecommendedReading

ChapterFive-WorkingwithOurOwnClassesContextFirstcreatean@Testmethod

Page 5: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Writecodethatdoesn’texistNewRequirementsNowRefactorSummary

ChapterSix-JavaClassesRevisited:Constructors,Fields,Getter&SetterMethodsContextConstructorGettersandSettersSummaryReferencesandRecommendedReading

ChapterSeven-BasicsofJavaRevisitedCommentsStatementPackagesJavaClassesImportingClassesStaticImportsDataTypesOperatorsStringsSummaryReferencesandRecommendedReading

ChapterEight-SelectionsandDecisionsTernaryOperatorsifstatementelsestatementNestedifelseswitchstatementSummaryReferencesandRecommendedReading

ChapterNine-ArraysandForLoopIterationArraysExercisesSummaryReferencesandRecommendedReading

ChapterTen-IntroducingCollectionsASimpleIntroductionIteratingwithwhileanddo…whileInterfacesSummary

Page 6: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ReferencesandRecommendedReading

ChapterEleven-IntroducingExceptionsWhatisanexception?CatchingExceptionsAnExceptionisanobjectCatchmorethanoneexceptionJUnitandExceptionsThrowinganExceptionfinally

SummaryReferencesandRecommendedReading

ChapterTwelve-IntroducingInheritanceInheritanceInheritfromInterfacesandAbstractClassesSummaryReferencesandRecommendedReading

ChapterThirteen-MoreAboutExceptionsUncheckedandCheckedExceptionsDifferencebetweenException,ErrorandThrowableCreateyourownExceptionclassSummaryReferencesandRecommendedReading

ChapterFourteen-JUnitExplored@Test

Before&After@Ignore

JUnitAssertionsAssertingwithHamcrestMatchersandassertThatfail

staticimportingSummaryReferencesandRecommendedReading

ChapterFifteen-StringsRevisitedStringSummarySystem.out.println

SpecialcharacterencodingStringConcatenationConvertingto/fromaStringConstructorsComparingStringsManipulatingStrings

Page 7: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

BasicStringparsingwithsplitManipulatingstringsWithStringBuilderConcatenation,.format,orStringBuilderSummaryReferencesandRecommendedReading

ChapterSixteen-RandomDataMath.random

java.util.random

SeedingrandomnumbersUsingRandomNumberstogenerateRandomStringsDiscussionrandomdatainautomationSummaryReferencesandRecommendedReading

ChapterSeventeen-DatesandTimescurrentTimeMillisandnanoTimeDate

SimpleDateFormat

Calendar

SummaryReferencesandRecommendedReading

ChapterEighteen-PropertiesandPropertyFilesPropertiesBasicsJava’sSystemPropertiesWorkingwithPropertyfilesSummaryReferencesandRecommendedReading

ChapterNineteen-FilesExampleofreadingandwritingafileFileWritingAndReadingFilesAdditionalFileMethodsFilesSummaryReferencesandRecommendedReading

ChapterTwenty-MathandBigDecimalBigDecimalMathSummaryReferencesandRecommendedReading

ChapterTwentyOne-CollectionsRevisitedSet

Page 8: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MapImplementationsSummaryReferencesandRecommendedReading

ChapterTwentyTwo-AdvancingConceptsInterfacesAbstractClassesGenericsLoggingEnumRegularExpressionsReflectionAnnotationsDesignPatternsConcurrencyAdditionalFileconsiderationsSummary

ChapterTwentyThree-NextStepsRecommendedReadingRecommendedVideosRecommendedWebSitesNextStepsReferences

Appendix-IntelliJHintsandTipsShortcutKeysCodeCompletionNavigatingSourceCodeRunningaJUnitTestLoadingProjectSourceHelpMenuSummary

Appendix-ExerciseAnswersChapterThree-MyFirstJUnitTestChapterFour-WorkWithOtherClassesChapterFive-WorkWithOurOwnClassesChapterSix-JavaClassesRevisited:Constructors,Fields,Getter&SetterMethodsChapterEight-SelectionsandDecisionsChapterNine-ArraysandForLoopIterationChapterTen-IntroducingCollectionsChapterEleven-IntroducingExceptionsChapterTwelve-IntroducingInheritanceChapterThirteen-MoreExceptions

Page 9: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterFourteen-JUnitExploredChapterFifteen-StringsRevisitedChapterSixteen-RandomDataChapterSeventeen-Dates&TimesChapterEighteen-PropertiesandPropertyFilesChapterNineteen-FilesChapterTwenty-MathandBigDecimalChapterTwentyOne-CollectionsRevisited

Page 10: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Introduction

Thisisanintroductorytext.Attimesittakesatutorialapproachandadoptsstepbystepinstructionstocoding.Somepeoplemorefamiliarwithprogrammingmightfindthisslow.Thisbookisnotaimedatthosepeople.

ThisbookisaimedatpeoplewhoareapproachingJavaforthefirsttime,specificallywithaviewtoaddingautomationtotheirtestapproach.Idonotcoverautomationtoolsinthisbook.

IdocoverthebasicJavaknowledgeneededtowriteandstructurecodewhenautomating.

Iprimarilywrotethisbookforsoftwaretesters,andtheapproachtolearningisorientedaroundwritingautomationcodetosupporttesting,ratherthanwritingapplications.AssuchitmightbeusefulforanyonelearningJava,whowantstolearnfroma“testfirst”perspective.

Automationtosupporttestingisnotlimitedtotestersanymore,sothisbookissuitableforanyonewantingtoimprovetheiruseofJavainautomation:managers,businessanalysts,users,andofcourse,testers.

TestersuseJavadifferentlyIrememberwhenIstartedlearningJavafromtraditionalbooks,andIrememberthatIwasunnecessarilyconfusedbysomeoftheconceptsthatIrarelyhadtousee.g.creatingmanifestfiles,andcompilingfromthecommandline.

TestersuseJavadifferently.

MostJavabooksstartwitha‘main’classandshowhowtocompilecodeandwritesimpleapplicationsfromthecommandline,thenbuildupintomoreJavaconstructsandGUIapplications.WhenIwriteJava,Irarelycompileittoastandaloneapplication,IspendalotoftimeintheIDE,writingandrunningsmallchecksandrefactoringtoabstractionlayers.

BylearningthebasicsofJavapresentedinthisbook,youwilllearnhowtoreadandunderstandexistingcodebases,andwritesimplechecksusingJUnitquickly.Youwillnotlearnhowtobuildandstructureanapplication.Thatisusefulknowledge,butitcanbelearnedafteryouknowhowtocontributetotheJavacodebasewithJUnittests.

MyaimistohelpyoustartwritingautomationcodeusingJava,andhavethebasicknowledgeyouneedtodothat.ThisbookfocusesoncoreJavafunctionalityratherthanalotofadditionallibraries,sinceonceyouhavethebasics,pickingupalibraryandlearninghowtouseitbecomesamatterofreadingthedocumentationandsamplecode.

Exclusions

Page 11: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thisisnota‘comprehensive’introduction.Thisisa‘gettingstarted’guide.EventhoughIconcentrateoncoreJava,therearestillaspectsofJavathatIhaven’tcoveredindetail,Ihavecoveredthem‘justenough’tounderstand.e.g.inheritance,interfaces,enums,innerclasses,etc.

Somepeoplemaylookdisparaginglyonthetextbasedontheexclusions.SoconsiderthisanopinionatedintroductiontoJavabecauseIknowthatIdidnotneedtousemanyofthoseexclusionsforthefirstfewyearsofmyautomationprogramming.

ImaintainthatthereisacoresetofJavathatyouneedinordertostartwritingautomationcodeandstartaddingvaluetoautomationprojects.Iaimtocoverthatcoreinthisbook.

Essentially,IlookedattheJavaIneededwhenIstartedwritingautomationtosupportmytesting,andusedthatasscopeforthisbook.WhileknowledgeofInterfaces,Inheritance,andenums,allhelpmakemyautomationabstractionsmorereadableandmaintainable;Ididnotusethoseconstructswithmyearlyautomation.

Ialsowanttokeepthebooksmall,andapproachable,sothatpeopleactuallyreaditandworkthroughit,ratherthanbuyingandleavingontheirshelfbecausetheyweretoointimidatedtopickitup.AndthatmeansleavingoutthepartsofJava,whichyoucanpickupyourself,onceyouhavemasteredtheconceptsinthisbook.

ThisbookdoesnotcoveranyJava1.8functionality.ThehighestversionofJavarequiredtoworkwiththisbookisJava1.7.ThecodeinthisbookwillworkwithJava1.8,Isimplydon’tcoveranyofthenewfunctionalityaddedinJava1.8becauseIwantyoutolearnthebasics,andstartbeingproductivequickly.Afteryoucompletethisbook,youshouldbeabletopickupthenewfeaturesinJava1.8whenyouneedthem.

SupportingSourceCodeYoucandownloadthesourcecodeforthisbookfromgithub.com.Thesourcecontainstheexamplesandanswerstoexercises.

Isuggestyouworkthroughthebookandgiveityourbestshotbeforeconsultingthesourcecode.

github.com/eviltester/javaForTestersCode

Thesourcecodehasbeenorganizedintotwohighlevelsourcefolders:mainandtest.Thefullsignificanceofthesewillbeexplainedinlaterchapters.Butfornow,thetestfoldercontainsalltheJUnitteststhatyouseeinthisbook.Eachchapterhasapackageandbeneaththatanexercisesandanexamplesfolder:

e.g.

ThemainfolderforChapter3is:src\test\java\com\javafortesters\chap003myfirsttest

itcontainsanexamplesfolderwithallthecodeusedinthemainbodyofthetextitcontainsanexercisesfolderwithallthecodefortheanswersIcreatedfortheexercisesinChapter3

Page 12: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thisshouldmakeiteasierforyoutonavigatethecodebase.Andifyouexperiencedifficultiestypinginanyofthecodethenyoucancompareitwiththeactualcodetosupportthebook.

Toallowyoutoreadthebookwithoutneedingtohavethesourcecodeopen,Ihaveaddedalotofcodeinthebodyofthebookandyoucanfindmuchofthecodefortheexercisesintheappendix.

TheAppendix“IntelliJHintsandTips”hasinformationonloadingthesourceandoffersareferencesectionforhelpingyounavigateandworkwiththesourcecodeinIntelliJ.

AbouttheAuthorAlanRichardsonhasworkedasaSoftwareprofessionalsince1995(althoughitfeelslonger).PrimarilyworkingwithSoftwareTesting,althoughhehaswrittencommercialsoftwareinC++,andavarietyofotherlanguages.

Alanhasavarietyofon-linetrainingcourses,bothfreeandcommercial:

“Selenium2WebDriverWithJava”“StartUsingSeleniumWebDriver”“TechnicalWebTesting”

Youcanfinddetailsofhisotherbooks,trainingcourses,conferencepapersandslides,andvideos,onhismaincompanywebsite:

CompendiumDev.co.uk

Alanmaintainsanumberofwebsites:

SeleniumSimplified.com:WebAutomationusingSeleniumWebDriverEvilTester.com:TechnicaltestingJavaForTesters.com:Java,aimedatsoftwaretesters.

JavaForTesters.comalsoactsasthesupportsiteforthisbook.

Alantweetsusingthehandle@eviltester

AcknowledgmentsThisbookwascreatedasa“workinprogress”onleanpub.com.Mythanksgotoeveryonewhoboughtthebookinitsearlystages,thisprovidedthecontinuedmotivationtocreatesomethingthataddedvalue,andthenspendtheextratimeneededtoaddpolishandreadability.

Specialthanksgotothefollowingpeoplewhoprovidedearlyandhelpfulfeedbackduringthewritingprocess:JayGehlot,FaezehSeyedarabi,SzymonKazmierczak,SrinivasKadiyala,TonyBruce,James‘Drew’Cobb,AdrianRapan.

IamalsogratefultoeveryJavadeveloperthatIhaveworkedwithwhotookthetimetoexplaintheircode.Youhelpedmeobservewhatagooddeveloperdoesandhowthey

Page 13: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

work.Thefactthatyouweregood,forcedmeto‘upmygame’andimprovebothmycodingandtestingskills.

Allmistakesinthisbookaremyfault.Ifyoufindany,pleaseletmeknowviacompendiumDev.co.uk/contactorviaanyofthesitesmentionedabove.

Page 14: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterOne-BasicsofJavaRevealed

ChapterSummaryAnoverviewofJavacodetosetthescene:

classisthebasicbuildingblockaclasshasmethodsmethodnamesstartwithlowercaselettersclassnamesstartwithuppercaselettersaJUnittestisamethodannotatedwith@TestJUnittestmethodscanberunwithoutcreatinganapplication

InthisfirstchapterIwillshowyouJavacode,andthelanguageIusetodescribeit,withlittleexplanation.

Idothistoprovideyouwithsomecontext.IwanttowrapyouinthelanguagetypicallyusedtodescribeJavacode.AndIwanttoshowyousmallsectionsofcodeincontext.Idon’texpectyoutounderstandityet.Justreadthepageswhichfollow,lookatthecode,soakitin,acceptthatitworks,andisconsistent.

Theninlaterpages,Iwillexplainthecodeconstructsinmoredetail,youwillwritesomecode,andI’llreinforcetheexplanations.

JavaExampleCode

Remember-justreadthefollowingsectionJustreadthefollowingsection,anddon’tworryifyoudon’tunderstanditallimmediately.Iexplainitinlaterpages.IhaveemphasizedtextwhichIwillexplainlater.Soifyoudon’tunderstandwhatanemphasizedwordmeans,thendon’tworry,youwillinafewpagestime.

AnemptyclassAclassisthebasicbuildingblockthatweusetobuildourJavacodebase.

Allthecodethatwewritetodostuff,wewriteinsideaclass.IhavenamedthisclassAnEmptyClass.1packagecom.javafortesters.chap001basicsofjava.examples.classes;

2

3publicclassAnEmptyClass{

4}

Justlikeyourname,ClassnamesstartwithanuppercaseletterinJava.I’musingsomethingcalledCamelCasetoconstructthenames,insteadofspacestoseparatewords,wewritethefirstletterofeachwordinuppercase.

Page 15: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThefirstlineisthepackagethatIaddedtheclassto.Apackageislikeadirectoryonthefilesystem,thisallowsustofind,anduse,theClassintherestofourcode.

AclasswithamethodAclass,onitsown,doesn’tdoanything.Wehavetoaddmethodstotheclassbeforewecandoanything.Methodsarethecommandswecancall,tomakesomethinghappen.

InthefollowingexampleIhavecreatedanewclasscalledAClassWithAMethod,andthisclasshasamethodcalledaMethodOnAClasswhich,whencalled,printsout"HelloWorld"totheconsole.1packagecom.javafortesters.chap001basicsofjava.examples.classes;

2

3publicclassAClassWithAMethod{

4

5publicvoidaMethodOnAClass(){

6System.out.println("HelloWorld");

7}

8}

Methodnamesstartwithlowercaseletters.

WhenwestartlearningJavawewillcallthemethodsofourclassesfromwithinJUnittests.

AJUnitTestForthecodeinthisbookwewilluseJUnit.JUnitisacommonlyusedlibrarywhichmakesiteasyforustowriteandrunJavacodewithassertions.

AJUnittestissimplyamethodinaclasswhichisannotatedwith@Test(i.e.wewrite@Testbeforethemethoddeclaration).1packagecom.javafortesters.chap014junit.examples;

2

3importcom.javafortesters.chap001basicsofjava.examples.classes.AClassWithAMethod;

4importorg.junit.Test;

5

6publicclassASysOutJunitTest{

7

8@Test

9publicvoidcanOutputHelloWorldToConsole(){

10AClassWithAMethodmyClass=newAClassWithAMethod();

11myClass.aMethodOnAClass();

12}

13}

Intheabovecode,IinstantiateavariableoftypeAClassWithAMethod(whichisthenameIgavetotheclassearlier).IhadtoimporttheclassandpackagebeforeIcoulduseit,andIdidthatasoneofthefirstlinesinthefile.

IcanrunthismethodfromtheIDEwithoutcreatingaJavaapplicationbecauseIhaveusedJUnitandannotatedthemethodwith@Test.

WhenIrunthismethodthenIwillseethefollowingtextprintedouttotheJavaconsoleinmyIDE:

Page 16: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

HelloWorld

SummaryIhavethrownyouintothedeependhere;presentingyouwithapageofpossiblegobbledygook.AndIdidthattointroduceyoutoatheJavaProgrammingLanguagequickly.

JavaProgrammingLanguageConcepts:

ClassMethodJUnitAnnotationPackageVariablesInstantiatevariablesTypeImport

ProgrammingConventionConcepts:

CamelCaseJUnitTestsareJavamethodsannotatedwith@Test

IntegratedDevelopmentEnvironmentConcepts:

Console

Overthenextfewchapters,I’llstarttoexplaintheseconceptsinmoredetail.

Page 17: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTwo-InstalltheNecessarySoftware

ChapterSummaryInthischapteryouwilllearnthetoolsyouneedtoprograminJava,andhowtoinstallthem.YouwillalsofindlinkstoadditionalFAQsandVideotutorials,shouldyougetstuck.

Thetoolsyouwillinstallare:

JavaDevelopmentKitMavenAnIntegratedDevelopmentEnvironment(IDE)

Youwillalsolearnhowtocreateyourfirstproject.

Whenyoufinishthischapteryouwillbereadytostartcoding.

Isuggestyoufirst,readthiswholechapter,andthenworkthroughthechapterfromthebeginningandfollowthestepslisted.

IntroductionProgrammingrequiresyoutosetupabunchoftoolstoallowyoutowork.

ForJava,thismeansyouneedtoinstall:

JDK-JavaDevelopmentKitIDE-IntegratedDevelopmentEnvironment

Forthisbookwearealsogoingtoinstall:

Maven-adependencymanagementandbuildtool

InstallingMavenaddsanadditionaldegreeofcomplexitytothesetupprocess,buttrustme.ItwillmakethewholeprocessofbuildingprojectsandtakingyourJavatothenextlevelaloteasier.

Ihavecreatedasupportpageforinstallation,withvideosandlinkstotroubleshootingguides.

JavaForTesters.com/install

Ifyouexperienceanyproblemsthatarenotcoveredinthischapter,oronthesupportpages,thenpleaseletmeknowsoIcantrytohelp,oramendthischapter,andpossiblyaddnewresourcestothesupportpage.

DoyoualreadyhaveJDKorMaveninstalled?

Page 18: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Someofyoumayalreadyhavethesetoolsinstalledwithyourmachine.Thefirstthingweshoulddoislearnhowtocheckiftheyareinstalledornot.

JavaJDKManyofyouwillalreadyhaveaJREinstalled(JavaRuntimeEnvironment),butwhendevelopingwithJavaweneedtouseaJDK.

Ifyoutypejavac-versionatyourcommandlineandgetanerrorsayingthatjavaccannotbefound(orsomethingsimilar).ThenyouneedtoinstallandconfigureaJDK.

Ifyouseesomethingsimilarto:javac1.7.0_10

ThenyouhaveaJDKinstalled.ItisworthfollowingtheinstructionsbelowtocheckifyourinstalledJDKisuptodate,butifyouhavea1.7.xJDK(orhigher)installedthenyouhaveagoodenoughversiontoworkthroughthisbookwithoutamendment.IfyourJDKisversion1.6thensomeofthecodeexampleswillnotwork.

JavaHasMultipleVersionsTheJavalanguageimprovesovertime.Witheachnewversionaddingnewfeatures.IfyouareunfortunateenoughtonotbeallowedtoinstallJava1.7atwork(thenIsuggestyouworkthroughthisbookathome,oronaVM),thenpartsofthesourcecodewillnotworkandthecodeyoudownloadforthisbookwillthrowerrors.

Specifically,wecoverthefollowingfeaturesintroducedinJava1.7:

TheDiamondoperator<>intheCollectionschaptersBinaryliteralse.g.0b1001Underscoresinliteralse.g.9_000_000_000LswitchstatementsusingStrings

Theabovestatementsmaynotmakesenseyet,butifyouareusingaversionofJavalowerthan1.7thenyoucanexpecttoseetheseconceptsthrowerrorswithJDK1.6orbelow.

InstallMavenMavenrequiresaversionofJavainstalled,soifyoucheckedforJavaanditwasn’tthere,youwillneedtoinstallMaven.

Ifyoutypemvn-versionatyourcommandline,andreceiveanerrorthatmvncannotbefound(orsomethingsimilar).ThenyouneedtoinstallandconfigureMavenbeforeyoufollowthetextinthisbook.

Ifyouseesomethingsimilarto:ApacheMaven3.0.4(r1232337;2012-01-1708:44:56+0000)

Mavenhome:C:\mvn\apache-maven-3.0.4

Javaversion:1.7.0_10,vendor:OracleCorporation

Javahome:C:\ProgramFiles\Java\jdk1.7.0_10\jre

Defaultlocale:en_GB,platformencoding:Cp1252

OSname:"windows8",version:"6.2",arch:"amd64",family:"windows"

Page 19: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThenyouhaveMaveninstalled.Thisbookdoesn’trequireaspecificversionofMaven,buthavingaversionof3.x.xoraboveshouldbefine.

InstallTheJavaJDKTheJavaJDKcanbedownloadedfromoracle.com.Ifyoumistakenlydownloadfromjava.comthenyouwillbedownloadingtheJRE,andfordevelopmentworkweneedtheJDK.

oracle.com/technetwork/java/javase/downloads

Fromtheabovesiteyoushouldfollowtheinstallationinstructionsforyourspecificplatform.

YoucanchecktheJDKisinstalledbyopeninganewcommandlineandrunningthecommand:javac-version

Thisshouldshowyoutheversionnumberwhichyoudownloadedandinstalledfromoracle.com

InstallMavenMavenisadependencymanagementandbuildtool.WewilluseittoaddJUnittoourprojectandwriteourcodebasedonMavenfolderconventionstomakeiteasierforotherstoreviewandworkwithourcodebase.

TheofficialMavenwebsiteismaven.apache.org.YoucandownloadMavenandfindinstallationinstructionsontheofficialwebsite.

DownloadMavenbyvisitingthedownloadpage:

maven.apache.org/download.cgi

Theinstallationinstructionscanalsobefoundonthedownloadpage:

maven.apache.org/download.cgi#Installation_Instructions

Isummarizetheinstructionsbelow:

UnzipthedistributionarchivewhereyouwanttoinstallMavenCreateanM2_HOMEuser/environmentvariablethatpointstotheabovedirectoryCreateanM2user/environmentvariablethatpointstoM2_HOME\bin

onWindows%M2_HOME%\binsometimesonWindows,IfindIhavetoavoidre-usingtheM2_HOMEvariableandinsteadcopythepathinagain

onUnix$M2_HOME/binAddtheM2user/environmentvariabletoyourpathMakesureyouhaveaJAVA_HOMEuser/environmentvariablethatpointstoyourJDKrootdirectory

Page 20: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

AddJAVA_HOMEtoyourpath

Youcancheckitisinstalledbyopeningupanewcommandlineandrunningthecommand:mvn-version

ThisshouldshowyoutheversionnumberthatyoujustinstalledandthepathforyourJDK.

Irecommendyoutakethetimetoreadthe“Mavenin5Minutes”guideontheofficialMavenwebsite:

maven.apache.org/guides/getting-started/maven-in-five-minutes.html

InstallTheIDEWhilethecodeinthisbookwillworkwithanyIDE,IrecommendyouinstallIntelliJ.IfindthatIntelliJworkswellforbeginnerssinceittendstopickuppathsanddefaultlocationsbetterthanEclipse.

Forthisbook,IwilluseIntelliJandanysupportingvideosIcreateforthisbook,oranyshortcutkeysImentionrelatingtotheIDEwillassumeyouareusingIntelliJ.

TheofficialIntelliJwebsiteisjetbrains.com/idea

IntelliJcomesintwoversionsa‘Community’editionwhichisfree,andan‘Ultimate’editionwhichyouhavetopayfor.

Forthepurposesofthisbook,andmostofyourautomationdevelopmentwork,the‘Community’editionwillmeetyourneeds.

DownloadtheCommunityEditionIDEfrom:

jetbrains.com/idea/download

Theinstallationshouldusethestandardinstallationapproachforyourplatform.

Whenyouarecomfortablewiththeconceptsinthisbook,youcanexperimentwithotherIDEse.g.EclipseorNetbeans.

IsuggestyoustickwithIntelliJuntilyouaremorefamiliarwithJavabecausethenyouminimizetheriskofissueswiththeIDEconfusingyouintobelievingthatyouhaveaproblemwithyourJava.

CreateaProjectusingtheIDETocreateyourfirstproject,useIntelliJtodothehardwork.

StartyourinstalledIntelliJChooseFile\NewProjectOntheNewProjectwizard:

chooseMavenModule

Page 21: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

typeaprojectnamee.g.javafortesterschoosealocationfortheprojectsourcefilesIntelliJshouldhavefoundyourinstalledJDKSelectNext

Youshouldbeabletouseallthedefaultsettingsforthewizard.

AboutyournewprojectTheNewProjectwizardshouldcreateanewfolderwithastructuresomethinglikethefollowing:+javaForTesters

+.idea

+src

+main

+java

+resources

+test

+java

javaForTesters.iml

pom.xml

Intheabovehierarchy,

the.ideafolderiswheremostoftheIntelliJconfigurationfileswillbestored,the.imlfilehasotherIntelliJconfigurationdetails,thepom.xmlfileisyourMavenprojectconfigurationfile.

Ifthewizardcreatedany.javafilesinanyofthedirectoriesthenyoucandeletethemastheyarenotimportant.Youwillbestartingthisprojectfromscratch.

TheabovedirectorystructureisastandardMavenstructure.MavenexpectscertainfilestobeincertaindirectoriestousethedefaultMavenconfiguration.Sinceyouarejuststartingyoucanleavethedirectorystructureasitis.

Certainconventionsthatyouwillfollowtomakeyourlifeasabeginningdevelopereasier:

AddyourJUnitTestClassesintothesrc\test\javafolderhierarchyWhenyoucreateaJUnitTestClass,makesureyouappendTesttotheClassname

Thesrc\main\javafolderhierarchyisforJavacodethatisnotusedforassertingbehaviour.Typicallythisisapplicationcode.Wewillusethisforourabstractionlayercode.Wecouldaddallthecodewecreateinthisbookinthesrc\test\javahierarchybutwherepossibleIsplittheabstractioncodeintoaseparatefolder.

Theaboveconventiondescriptionmaynotmakesenseatthemoment,buthopefullyitwillbecomeclearasyouworkthroughthebook.Don’tworryaboutitnow.

Thepom.xmlfilewillprobablylooklikethefollowing:<?xmlversion="1.0"encoding="UTF-8"?>

<projectxmlns="http://maven.apache.org/POM/4.0.0"

Page 22: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>javaForTesters</groupId>

<artifactId>javaForTesters</artifactId>

<version>1.0-SNAPSHOT</version>

</project>

Thisisthebasicsforablankprojectfileanddefinesthenameoftheproject.

Youcanfindinformationaboutthepom.xmlfileontheofficialMavensite.

maven.apache.org/pom.html

AddJUnittothepom.xmlfileWewillusealibrarycalledJUnittohelpusrunourcode.

junit.org

YoucanfindinstallationinstructionsforusingJUnitwithMavenontheJUnitwebsite.

github.com/junit-team/junit/wiki/Download-and-Install

Webasicallyeditthepom.xmlfiletoincludeadependencyonJUnit.WedothisbycreatingadependenciesXMLelementandadependencyXMLelementwhichdefinestheversionofJUnitwewanttouse.Atthetimeofwritingitisversion4.11

Thepom.xmlfilethatwewilluseforthisbook,onlyrequiresadependencyonJUnit,soitlookslikethis:<?xmlversion="1.0"encoding="UTF-8"?>

<projectxmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>javaForTesters</groupId>

<artifactId>javaForTesters</artifactId>

<version>1.0-SNAPSHOT</version>

<packaging>jar</packaging>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

<dependencies>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.11</version>

Page 23: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.1</version>

<configuration>

<source>1.7</source>

<target>1.7</target>

</configuration>

</plugin>

</plugins>

</build>

</project>

YoucanseeIalsoaddedabuildsectionwithamaven-compiler-plugin.ThiswasmainlytocutdownonwarningsintheMavenoutput.Ifyoureallywanttomakethepom.xmlfilesmallyoucouldgetawaywithaddingthe<dependencies>XMLelementandallitscontaininginformationaboutJUnit.

Amendyourpom.xmlfiletocontainthedependenciesandbuildelementsabove.IntelliJshoulddownloadtheJUnitdependencyreadyforyoutowriteyourfirstJUnitTest,inthenextchapter.

YoucanfindmoreinformationaboutthispluginontheMavensite:

maven.apache.org/plugins/maven-compiler-plugin

SummaryIfyoufollowedtheinstructionsinthischapterthenyoushouldnowhave:

Maveninstalled-mvn-versionJDKinstalled-javac-versionIntelliJIDEinstalledCreatedyourfirstprojectApom.xmlfilewithJUnitasadependency

Ican’tanticipatealltheproblemsyoumighthaveinstallingthethreetoolslistedinthischapter(JDK,Maven,IDE).

Theinstallationshouldbesimple,butthingscangowrong.

IhavecreatedafewvideosontheJavaForTesters.com/installsitewhichshowhowtoinstallthevarioustools.

JavaForTesters.com/install

IaddedsomeMavenTroubleshootingHintsandTipstothe“JavaForTesters”blog:

Page 24: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

javafortesters.blogspot.co.uk/2013/08/maven-troubleshooting-faqs-and-tips.html

Ifyoudogetstuckthentryanduseyourfavouritesearchengineandcopyandpastetheexacterrormessageyoureceiveintothesearchengineandyou’llprobablyfindsomeoneelsehasalreadymanagedtoresolveyourexactissue.

Page 25: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterThree-WritingYourFirstJavaCode

ChapterSummaryInthistutorialchapteryouwillfollowalongwiththetextandcreateyourfirstJUnittest.Youwilllearn:

HowtoorganizeyourcodeandimportotherclassesCreatingclassesandnamingclassesasJUnittestsMakingJavamethodsrunasJUnittestsAddingassertstoreporterrorsduringtheexecutionHowtorunJUnittestsfromtheIDEandthecommandlineHowtowritebasicarithmeticstatementsinJavaAboutJavacomments

Followalongwiththetext,andusetheexamplecodeasaguide.Ifyouhaveissuesthencomparethecodeyouhavewrittencarefullyagainstthecodeinthebook.

Inthischapterwewilltakeaslightlydifferentapproach.Wewilladvancestep-by-stepthroughthechapterandwewillwriteasimplemethodwhichwewillrunasaJUnittest.

MyFirstJUnitTestThecodewillcalculatetheanswerto“2+2”,andthenassertthattheansweris“4”.

Thecodewewritewillbeverysimple,andwilllooklikethefollowing:1packagecom.javafortesters.chap003myfirsttest.examples;

2importorg.junit.Test;

3importstaticorg.junit.Assert.assertEquals;

4

5publicclassMyFirstTest{

6

7@Test

8publicvoidcanAddTwoPlusTwo(){

9intanswer=2+2;

10assertEquals("2+2=4",4,answer);

11}

12}

I’mshowingyouthisnow,soyouhaveanunderstandingofwhatweareworkingtowards.Ifyougetstuck,youcanreferbacktothisfinalstateandcompareitwithyourcurrentstatetohelpresolveanyproblems.

PrerequisitesI’massumingthatyouhavefollowedthesetupchapterandhavethefollowinginplace:

JDKInstalledIDEInstalledMavenInstalledCreatedaproject

Page 26: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

AddedJUnittotheprojectpom.xml

Wearegoingtoaddallthecodewecreateinthisbooktotheprojectyouhavecreated.

CreateAJUnitTestClassThefirstthingwehavetodoiscreateaclass,towhichwewilladdourJUnittestmethod.

AclassisthebasicbuildingblockforourJavacode.SowewanttocreateaclasscalledMyFirstTest.

ThenameMyFirstTesthassomeveryimportantfeatures.

ItstartswithanuppercaseletterIthasthewordTestattheendItusescamelcase

Itstartswithanuppercaseletterbecause,byconvention,Javaclassesstartwithanuppercaseletter.Byconventionmeansthatitdoesn’thaveto.Youwon’tseeJavathrowanyerrorsifyounametheclassmyFirstTestwithalowercaseletter.Whenyourunthecode,Javawon’tcomplain.

Buteveryonethatyouworkwithwill.

WeexpectJavaclassestostartwithanuppercaseletterbecausetheyarepropernames.

Trustme.

Getinthehabitofnamingyourclasseswiththefirstletterinuppercase.Thenwhenyoureadcodeyoucantellthedifferencebetweenaclassandavariable,andyou’llexpectthesamefromcodethatotherpeoplehavewritten.

IthasthewordTestattheend.Wecantakeadvantageofthe‘outofthebox’MavenfunctionalitytorunourJUnittestsfromthecommandline,insteadoftheIDE,bytypingmvntest.Thismightnotseemimportantnow,butatsomepointwearegoingtowanttorunourcodeautomaticallyaspartofabuildprocess.AndwecanmakethateasierifweaddTestintheClassname,eitherasthestartoftheclassname,orattheend.Bynamingourclassesinthisway,MavenwillautomaticallyrunourJUnittestclassesattheappropriatepartofthebuildprocess.

IncorrectlyNamedClassesWillRunFromtheIDE

VeryoftenwerunourJUnittestcodefromtheIDE.AndtheIDEwillrunthemethodsinJUnittestclasseseveniftheclassesarenotnamedasMavenrequires.IfwedonotnameaclasscorrectlythenitwillnotrunfromthecommandlinewhenwetypemvntestbutbecausewesawitrunintheIDE,webelieveitisrunning.

Thisleavesusthinkingwehavemorecoveragethanweactuallydo.

Itusescamelcasewhereeach‘word’inastringofconcatenatedwordsstartswithanuppercaseletter.ThisagainisaJavaconvention,itisnotenforcedbythecompiler.Butpeoplereadingyourcodewillexpecttoseeitwrittenlikethis.

Page 27: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MavenProjectsneedtobeimportedAsyoucode,ifyouseealittlepopupinIntelliJwhichsays“MavenProjectsneedtobeimported”.Clickthe“EnableAuto-Import”.Thiswillmakeyourlifeeasierasitwillautomaticallyaddimportstatementsinyourcodeandupdatewhenyouchangeyourpom.xmlfile.

TocreatetheclassIntheIDE,openuptheProjecthierarchysothatyoucanseethesrc\test\javabranchandthesrc\main\javabranch.

Myprojecthierarchylookslikethis:+javaForTesters

+.idea

+src

+main

+java

+resources

+test

+java

.ideaistheIntelliJfolder,soIcanignorethat.

IrightclickonthejavafolderundertestandselecttheNew\JavaClassmenuitem.

Or,Icouldclickonthejavafolderundertestandusethekeyboardshortcutalt+insert,andselectJavaClass(onaMacusectrl+n)

TypeinthenameoftheJavaclassthatyouwanttocreatei.e.MyFirstTestandselect[OK]

Don’tworryaboutthepackagestructurefornow.Wecaneasilymanuallymoveourcodearoundlater.OrhaveIntelliJmoveitaroundforususingrefactoring.

TemplatecodeYoumightfindthatyouhaveacodeblockofcommentswhichIntelliJaddedautomatically/**

*CreatedwithIntelliJIDEA.

*User:Alan

*Date:24/04/13

*Time:11:48

*TochangethistemplateuseFile|Settings|FileTemplates.

*/

Youcanignorethiscodeasitisacomment.Youcandeleteallthoselinesifyouwantto.

Page 28: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IntroductiontoCommentsInJavaCommentsareexplanatorytextthatisnotexecuted.

Youcanuse//tocommentouttotheendofaline.

Youcancommentoutblocksoftextbyusing/*and*/

Where/*delimitsthestartofthecommentand*/delimitstheendofthecomment.

So/*everythinginsideisacomment*/

/*Commentscreatedwithforwardslashasteriskcanspanmultiplelines*/

AddtheclasstoapackageIntelliJwillhavecreatedanemptyclassforus.e.g.publicclassMyFirstTest{

}

Andsincewedidn’tspecifyapackage,itwillbeattherootlevelofourtest\javahierarchy.

Wehavetwowaysofcreatingapackageandthenmovingtheclassintoit:

ManuallycreatethepackageanddraganddroptheclassintoitAddthepackagestatementintoourcodeandhaveIntelliJmovetheclass

ManuallycreatethepackageanddraganddroptheclassintoitbyrightclickingonthejavafolderundertestandselectingNew\Package,thenenterthepackagenameyouwanttocreate.

Forthisbook,I’mgoingtosuggestthatyouusethetoplevelpackagestructure:

com.javafortesters

Andthennameanysubstructuresasrequired.Soforthisclasswecouldcreateapackagecalledcom.javafortesters.chap003myfirsttest.examples.Youdon’thavetousethechap003prefix,butitmighthelpyoutraceyourcodebacktothechapterinthebook.Iusethisconventiontohelpyoufindtheexampleandexercisesourcecodeinthesourcedownload.

PackageNamingInJava,packagenamestendtobealllowercase,andnotusecamelCase.

Ifwewantto,wecanaddthepackagestatementintoourcodeandhaveIntelliJmovetheclass:

Addthefollowinglineasthefirstlineintheclass:

Page 29: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

packagecom.javafortesters.chap003myfirsttest.examples;

Thesemi-colonattheendofthelineisimportantbecauseJavastatementsendwithasemi-colon.

IntelliJwillhighlightthislinewitharedunderscorebecauseourclassisnotinafolderstructurethatrepresentsthatpackage.

IntelliJcandomorethanjusttelluswhatourproblemsare,itcanalsofixthisproblemforusifweclickthemouseintheunderscoredtext,andthenpressthekeysalt+return.

IntelliJwillshowapopupmenuwhichwillofferustheoptionto:Movetopackagecom.javafortesters.chap003myfirsttest.examples

SelectthisoptionandIntelliJwillautomaticallymovetheclasstothecorrectlocation.

YoucouldcreatethepackagefirstOfcourse,Icouldhavecreatedthepackagefirst,butsometimesIliketocreatetheclasses,andconcentrateonthecode,beforeIconcentrateontheorderingandcategorizationofthecode.

Youwilldevelopyourownstyleofcodingasyoubecomemoreexperienced.IliketohavetheIDEdoasmuchworkformeasIcan,whileIremaininthe‘flow’ofcoding.

TheEmptyClassExplainedpackagecom.javafortesters.chap003myfirsttest.examples;

publicclassMyFirstTest{

}

Ifyou’vefollowedalongthenyouwillhaveanemptyclass,inthecorrectpackageandtheProjectwindowwillshowadirectorystructurethatmatchesthepackagehierarchyyouhavecreated.

PackageStatement

Thepackagestatementisalineofcodewhichdefinesthepackagethatthisclassbelongsin.packagecom.javafortesters.chap003myfirsttest.examples;

Whenwewanttousethisclassinourlatercodethenwewouldimporttheclassfromthispackage.

Thepackagemapsontothephysicalfolderstructurebeneathyoursrc\testfolder.Soifyoulookinexplorerunderyourprojectfolderyouwillseethatthepackageisactuallyanestedsetoffolders.+src

+test

+java

Andunderneaththejavafolderyouwillhaveafolderstructurethatrepresentsthepackagestructure.+com

+javafortesters

Page 30: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

+chap003myfirsttest

+examples

Javaclassesonlyhavetobeuniquelynamedwithinapackage.SoIcouldcreateanotherclasscalledMyFirstTestandplaceitintoadifferentpackageinmysourcetreeandJavawouldnotcomplain.Iwouldsimplyhavetoimportthecorrectpackagestructuretogetthecorrectversionoftheclass.

ClassDeclaration

Thefollowinglines,areourclassdeclaration.publicclassMyFirstTest{

}

Wehavetodeclareaclassbeforeweuseit.Andwhenwedoso,wearealsodefiningtherulesabouthowotherclassescanuseittoo.

Heretheclasshaspublicscope.Thismeansthatanyclass,inanypackage,canusethisclassiftheyimportit.

JavahasmorescopedeclarationsJavahasotherscopedeclarations,likeprivateandprotectedbutwedon’thavetoconcernourselveswiththoseyet.

WhenwecreateclassesthatwillbeusedforJUnittests,weneedtomakethempublicsothatJUnitcanusethem.

The{and}areblockmarkers.Theopeningbrace{delimitsthestartofablock,andtheclosingbrace}delimitstheendofablock.

Allthecodethatwewriteforaclasshastogobetweentheopeningandclosingblockthatrepresentstheclassbody.

Inthiscasetheclassbodyisempty,becausewehaven’twrittenanycodeyet,butwestillneedtohavetheblockmarkers,otherwiseitwillbeinvalidJavasyntaxandyourIDEwillflagthecodeasbeinginerror.

CreateaMethodWearegoingtocreateamethodtoaddtwonumbers.Specifically2+2.

Icreateanewmethodbytypingoutthemethoddeclaration:publicvoidcanAddTwoPlusTwo(){

}

Remember,themethoddeclarationisenclosedinsidetheclassbodyblock:publicclassMyFirstTest{

publicvoidcanAddTwoPlusTwo(){

}

}

Page 31: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

public

ThismethodisdeclaredaspublicmeaningthatanyclassthatcanuseMyFirstTestcancallthemethod.

WhenweuseJUnit,anymethodthatwewanttouseasaJUnittestshouldbedeclaredaspublic.

void

Thevoidmeansthatthemethoddoesnotreturnavaluewhenitiscalled.Wewillcoverthisindetaillater,butasageneralrule,ifyouaregoingtomakeamethodaJUnittest,youprobablywanttodeclareitasvoid.

()

Everymethoddeclarationhastodefinewhatparametersthemethodcanbecalledwith.Atthemomentwehaven’texplainedwhatthismeansbecauseourmethoddoesn’ttakeanyparameters,andsoafterthemethodnamewehave“()”,theopenandcloseparentheses.Ifwedidhaveanyparameterstheywouldbedeclaredinsidetheseparentheses.

{}

Inordertowritecodeinamethodweadditinthecodeblockofthemethodbodyi.e.insidetheopeningandclosingbraces.

Wehaven’twrittenanycodeinthemethodyet,sothecodeblockisempty.

NamingJUnitTest`MethodsAlotofpeopledon’tgiveenoughthoughttoJUnittestmethodnames.AndusenameslikeaddTestoraddNumbers.Itrytowritenamesthat:

explainthepurposeofthemethodwithoutwritingadditionalcommentsdescribethecapabilityorfunctionwewanttocheckshowthescopeofwhatisbeingchecked

MakethemethodaJUnittestWecanmakethemethodaJUnittest.Byannotatingitwith@Test.

Inthisbookwewilllearnhowtouseannotations.Werarelyhavetocreatecustomannotationswhenautomating,sowewon’tcoverhowtocreateyourownannotationsinthisbook.

JUnitimplementsafewannotationsthatwewilllearn.Thefirst,andmostfundamental,isthe@Testannotation.JUnitonlyrunsthemethodswhichareannotatedwith@TestasJUnittests.Wecanhaveadditionalmethodsinourclasseswithouttheannotation,andJUnitwillnottryandrunthose.

Page 32: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Becausethe@TestannotationcomeswithJUnitwehavetoimportitintoourcode.

Whenyoutype@Testonthelinebeforethemethoddeclaration.TheIDEwillhighlightitasanerror.@Test

publicvoidcanAddTwoPlusTwo(){

}

Whenweclickonthelinewiththeerrorandpressthekeycombinationalt+returnthenwewillreceiveanoptionto:ImportClass

ChoosingthatoptionwillresultinIntelliJaddingtheimportstatementintoourclass.importorg.junit.Test;

Wehavetomakesurethatwelookatthelistofimportoptionscarefully.Sometimeswewillbeofferedmultipleoptions,becausetheremaybemanyclasseswiththesamename,wherethedifferenceisthepackagetheyhavebeenplacedinto.

IfyouselectthewrongimportIfyouaccidentallyselectthewrongimportthensimplydeletetheexistingimportstatementfromthecode,andthenuseIntelliJtoalt+returnandimportthecorrectclassandpackage.

CalculatethesumToactuallycalculatethesum2+2Iwillneedtocreateavariable,thenIcanstoretheresultofthecalculationinthevariable.intanswer=2+2;

Variablesareasymbolwhichrepresentsomeothervalue.Inprogramming,weusethemtostorevalues:strings,integersetc.sothatwecanusethemandamendthemduringtheprogramcode.

Iwillcreateavariablecalledanswer.

Iwillmakethevariablean‘int’.intdeclaresthetypeofvariable.intisshortforintegerandisaprimitivetype,sodoesn’thavealotoffunctionalityotherthanstoringanintegervalueforus.Anintisnotaclasssodoesn’thaveanymethods.

Thesymbol2inthecodeiscalledanumericliteral,oranintegerliteral.

AninthaslimitsAnintcanstorevaluesfrom-2,147,483,648to2,147,483,647.e.g.

intminimumInt=-2147483648;

intmaximumInt=2147483647;

WhenIcreatethevariableIwillsetitto2+2.

Page 33: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

JavawilldothecalculationforusbecauseIhaveusedthe+operator.The+operatorwillactontwointoperandsandreturnaresult.i.e.itwilladd2and2andreturnthevalue4whichwillbestoredintheintvariableanswer.

JavaOperatorsJavahasafewobviousbasicoperatorswecanuse:

+toadd-tosubtract*tomultiply/todivide

Therearemore,butwewillcoverthoselater.

AssertthevalueThenextthingwehavetodoisassertthevalue.assertEquals("2+2=4",4,answer);

Whenwewrite@Testmethodswehavetomakesurethatweassertsomethingbecausewewanttomakesurethatourcodereportsfailurestousautomatically.

Anassertisaspecialtypeofcheck:

Ifthecheckfailsthentheassertthrowsanassertionerrorandourmethodwillfail.Ifthecheckpassesthentheassertdoesn’thaveanyside-effects

TheassertswewillinitiallyuseinourcodecomefromtheJUnitAssertpackage.

SowhenItypetheassert,IntelliJwillshowthestatementasbeinginerror,becauseIhaven’timportedtheassertEqualsmethodorAssertclassfromJUnit.

TofixtheerrorIwillalt+returnontheassertEqualsstatementandchooseto:staticimportmethod…

from

Assert.assertEqualsintheorg.junitpackage

IntelliJwillthenaddthecorrectimportstatementintomycode.importstaticorg.junit.Assert.assertEquals;

TheassertEqualsmethodispolymorphic.Whichsimplymeansthatitcanbeusedwithdifferenttypesofparameters.

Ihavechosentouseaformof:assertEquals("2+2=4",4,answer);

Where:

assertEqualsisanassertthatchecksiftwovaluesareequal

Page 34: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

"2+2=4"isamessagethatisdisplayediftheassertfails.4isanintliteralthatrepresentstheexpectedvalue,i.e.Iexpect2+2toequal4answeristheintvariablewhichhastheactualvalueIwanttocheckagainsttheexpectedvalue

Icouldhavewrittentheassertas:assertEquals(4,answer);

Inthisform,Ihavenotaddedamessage,soiftheassertfailstherearefewercluestellingmewhatshouldhappen,andinsomecasesImightevenhavetoaddacommentinthecodetoexplainwhattheassertdoes.

ItrytoremembertoaddamessagewhenIusetheJUnitassertmethodsbecauseitmakesthecodeeasiertoreadandhelpsmewhenassertsdofail.

Notethatinbothforms,theexpectedresultistheparameter,beforetheactualresult.

IfyougetthesethewrongwayroundthenJUnitwon’tthrowanerror,sinceitdoesn’tknowwhatyouintended,buttheoutputfromafailedassertwouldmisleadyou.e.g.ifIaccidentallywrote2+3wheninitializingtheintanswer,andIputtheexpectedandactualresultthewrongwayround,thentheoutputwouldsaysomethinglike:java.lang.AssertionError:2+2=4expected:<5>butwas:<4>

Andthatwouldconfuseme,becauseIwouldexpect2+2toequal4.

AssertionTipsTrytoremembertoaddamessageintheassertiontomaketheoutputreadable.

Makesurethatyouputtheexpectedandactualparametersinthecorrectorder.

Runthe@TestmethodNowthatwehavewrittenthemethod,itistimetorunitandmakesureitpasses.

Todothateither:

Runallthe@Testannotatedmethodsintheclass

rightclickontheclassnameintheProjectHierarchyandselect:Run'MyFirstTest'

clickontheclassintheProjectHierarchyandpressthekeycombination:ctrl+shift+F10

rightclickontheclassnameinthecodeeditorandselect:Run'MyFirstTest'

Runasingle@Testannotatedmethodintheclass

rightclickonthemethodnameinthecodeeditorandselect:Run'canAddTwoPlusTwo()'

Page 35: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

clickonthemethodnameinthecodeeditorandpressthekeycombination:ctrl+shift+F10

Sinceweonlyhaveone@Testannotatedmethodatthemomenttheywillbothachievethesameresult,butwhenyouhavemorethanone@Testannotatedmethodintheclassthentheabilitytorunindividualmethods,ratherthanallthemethodsintheclasscancomeinveryhandy.

Runallthe@Testannotatedmethodsfromthecommandline

Ifyouknowhowtousethecommandlineonyourcomputer,andchangedirectorythenyoucanalsorunthe@Testannotatedmethodsfromthecommandlineusingthecommand:

mvntest

Todothis:

openacommandprompt,ensurethatyouareinthesamefolderastherootofyourproject.i.ethesamefolderasyourpom.xmlfilerunthecommandmvntest

YoushouldseetheannotatedmethodsrunandtheMavenoutputtothecommandline.

SummaryThatwasafairlyinvolvedexplanationofaverysimpleJUnittestclass:1packagecom.javafortesters.chap003myfirsttest.examples;

2importorg.junit.Test;

3importstaticorg.junit.Assert.assertEquals;

4

5publicclassMyFirstTest{

6

7@Test

8publicvoidcanAddTwoPlusTwo(){

9intanswer=2+2;

10assertEquals("2+2=4",4,answer);

11}

12}

Hopefullywhenyoureadthecodenow,itallmakessense,andyoucanfeelconfidentthatyoucanstartcreatingyourownsimpleselfcontainedtests.

ThisbookdiffersfromnormalpresentationsofJava,becausetheywouldstartwithcreatingsimpleapplicationswhichyourunfromthecommandline.

Whenwewriteautomationcode,wespendalotoftimeworkingintheIDEandrunningthe@TestannotatedmethodsfromtheIDE,sowecodeandrunJavaslightlydifferentlythanifyouwerewritinganapplication.

ThisalsomeansthatyouwilllearnJavaconceptsinaslightlydifferentorderthanotherbooks,buteverythingyoulearnwillbeinstantlyusable,ratherthanlearningthingsin

Page 36: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ordertoprogressthatyouarenotlikelytouseveryoftenintherealworld.

Althoughthereisnotalotofcode,wehavecoveredthebasicsofalotofimportantJavaconcepts.

OrderingclassesintopackagesImportingclassesfrompackagestousethemCreatingandnamingclassesCreatingmethodsCreatingaJUnitTestAddinganassertiontoaJUnittestRunning@TestannotatedmethodsfromtheIDEprimitivetypesbasicarithmeticoperatorsanintroductiontoJavavariablesJavacommentsJavastatementsJavablocks

YoualsoencounteredthefollowingIntelliJshortcutkeys:

Function Windows MacCreateNew alt+insert ctrl+n

IntentionActions alt+enter alt+enter

IntentionActions alt+return alt+return

RunJUnitTest ctrl+shift+F10 ctrl+shift+F10

Andnowthatyouknowthebasics,wecanproceedfasterthroughthenextsections.

Exercise:Checkfor5insteadof4Amendthecodesothattheassertionmakesacheckfor5astheexpectedvalueinsteadof4:

Runthemethodandseewhathappens.Thiswillgetyouusedtoseeingtheresultofafailingmethod.

Exercise:Createadditional@Testannotatedmethodstocheck:2-2=04/2=22*2=4

Page 37: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:CheckthenamingoftheJUnittestclasses:WhenyourunJUnittestclassesfromtheIDEtheydonotrequire‘Test’atthestartorendofthename.ButtheydoneedthatconventiontorunfromMaven.Verifythis.

Createaclasswithamethodcontainingafailingasserte.g.assertTrue(false);

Renametheclasstothedifferentrulesbelow,andrunitfrommvntestandfromtheIDEsoyouseethenamingmakesadifference.

Testatthestarte.g.TestNameClassrunsintheIDEandfrommvntestTestattheende.g.NameClassTestrunsintheIDEandfrommvntestTestinthemiddlee.g.NameTestClassrunsintheIDEbutnotfrommvntestwithoutTeste.g.NameClassrunsintheIDEbutnotfrommvntest

ReferencesandRecommendedReading

CamelCaseexplanationonWikiPediaen.wikipedia.org/wiki/CamelCase

OfficialOracleJavaDocumentationWhatisanObject?

docs.oracle.com/javase/tutorial/java/concepts/object.htmlWhatisaClass?

docs.oracle.com/javase/tutorial/java/concepts/class.htmlJavaTutorialonPackageNamingconventions

docs.oracle.com/javase/tutorial/java/package/namingpkgs.htmlJavacodeblocks

docs.oracle.com/javase/tutorial/java/nutsandbolts/expressions.htmlJavaOperators

docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.htmlJUnit

HomePagejunit.org

Documentationgithub.com/junit-team/junit/wiki

APIDocumentationjunit.org/javadoc/latest

@Testjunit.org/javadoc/latest/org/junit/Test.html

IntelliJIntelliJEditorAutoImportSettings

jetbrains.com/idea/webhelp/maven-importing.htmlIntelliJMavenImportingSettings

jetbrains.com/idea/webhelp/maven-importing.html

Page 38: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterFour-WorkwithOtherClasses

ChapterSummaryInthischapteryouwilllearn:

HowtousestaticmethodsofanotherclassHowtoinstantiateaclasstoanobjectvariableHowtoaccessstaticfieldsandconstantsonaclassThedifferencebetweenIntegervalueandinstantiation

Inthischapteryouaregoingtolearnhowtouseotherclassesinyour@Testmethodcode.Eventuallythesewillbeclassesthatyouwrite,butforthemomentwewilluseotherclassesthatarebuiltintoJava.

Youhavealreadydonethisinthepreviouschapter.BecauseyouusedtheJUnitAssertclasstocheckconditions,butweimporteditstatically,soyoumightnothavenoticed.(I’llexplainwhatstaticimportmeansinthenextchapter).

Butfirst,someguidanceonhowtolearnJava.

Use@TestmethodstounderstandJavaWhenIworkwithpeoplelearningJava,IencouragethemtowritemethodsandassertionswhichhelpthemunderstandtheJavalibrariestheyareusing.

Forexample,youhavealreadyseenaprimitivetypecalledanint.

JavaalsoprovidesaclasscalledInteger.

BecauseIntegerisaclass,ithasmethodsthatwecancall,andwecaninstantiateanobjectvariableasanInteger.

WhenIcreateanintvariable,allIcandowithit,isstoreanumberinthevariable,andretrievethenumber.

IfIcreateanIntegervariable,Igainaccesstoalotofmethodsontheintegere.g.

compareTo-compareittoanotherintegerintValue-returnanintprimitivelongValue-returnalongprimitiveshortValue-returnashortprimitive

ExploretheIntegerclasswith@TestmethodsInfactyoucanseeforyourselfthemethodsavailabletoaninteger.

Createanewpackage:com.javafortesters.chap004testswithotherclasses.examples

Page 39: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

CreateanewclassIntegerExamplesTestCreateamethodintegerExplorationAnnotatethemethodwith@TestsoyoucanrunitwithJUnit

Youshouldendupwithsomethinglikethefollowing:packagecom.javafortesters.chap004testswithotherclasses.examples;

importorg.junit.Test;

publicclassIntegerExamplesTest{

@Test

publicvoidintegerExploration(){

}

}

WecanusetheintegerExplorationmethodtoexperimentwiththeIntegerclass.

InstantiateanIntegerClass

ThefirstthingweneedtodoiscreateavariableoftypeInteger.Integerfour=newInteger(4);

BecauseIntegerisaclass,thisiscalledinstantiatingaclassandthevariableisanobjectvariable.

intwasaprimitivetype.Integerisaclass.TouseaclassweinstantiateitwiththenewkeywordThenewkeywordcreatesanewinstanceofaclassThenewinstanceisreferredtoasanobjectoraninstanceofaclass

YoucanalsoseethatIpassedintheliteral4asaparameter.IdidthisbecausetheIntegerclasshasaconstructormethodwhichtakesanintasaparametersotheobjecthasavalueof4.

WhatisaConstructor?Aconstructorisamethodonaclasswhichiscalledwhenanewinstanceoftheclassiscreated.

Aconstructorcantakeparameters,butneverreturnsavalueandisdeclaredwithoutareturntype.e.g.publicInteger(intvalue){...}

Aconstructorhasthesamenameastheclassincludingstartingwithanuppercaseletter.

TheIntegerclassactuallyhasmorethanoneconstructor.Youcanseethisforyourself.

TypeinthestatementtoinstantiateanewIntegerobjectwiththevalue4Clickinsidetheparentheseswherethe4is,asifyouwereabouttotypeanewparameter,pressthekeysctrl+p(cmd+ponaMac)

Page 40: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Youshouldseeapop-upshowingyoualltheformstheconstructorcantake.InthecaseofanIntegeritcanacceptanintoraString.

CheckthatintValuereturnsthecorrectint

WeknowthattheIntegerclasshasamethodintValuewhichreturnsanint,sowecancreateanassertiontocheckthereturnedvalue.

AfterthestatementwhichinstantiatestheInteger.

AddanewstatementwhichassertsthatintValuereturnsanintwiththevalue4.assertEquals("intValuereturnsint4",

4,four.intValue());

Whenyourunthismethoditshouldpass.

InstantiateanIntegerwithaString

WesawthatoneoftheconstructorsforIntegercantakeaString,soletswritesomecodetoexperimentwiththat.

InstantiateanewIntegervariable,callingtheIntegerconstructorwiththeString"5",AssertthatintValuereturnstheInteger5

Integerfive=newInteger("5");

assertEquals("intValuereturnsint5",

5,five.intValue());

QuickSummary

Itmightnotseemlikeitbutwejustcoveredsomeimportantthingsthere.

Didyounoticethatyoudidn’thavetoimporttheIntegerclass?BecausetheIntegerclassisbuiltintothelanguage,wecanjustuseit.Thereareafewclasseslikethat,Stringisanotherone.Theclassesdoexistinapackagestructure,theyareinjava.lang,butyoudon’thavetoimportthemtousethem.

Wejustlearnedthattouseanobjectofaclass,thatsomeoneelsehasprovided,orthatwewrite,wehavetoinstantiatetheobjectvariablesusingthenewkeyword.Usectrl+ptohavetheIDEshowyouwhatparametersamethodcantake(cmd+ponaMac).Whenweinstantiateaclasswiththenewkeyword,aconstructormethodontheclassiscalledautomatically.

AutoBoxing

IntheversionsofJavathatwewillbeusing,wedon’tactuallyneedtoinstantiatetheIntegerclasswiththenewkeyword.

WecantakeadvantageofaJavafeaturecalled‘autoboxing’whichwasintroducedinJavaversion1.5.Autoboxingwillautomaticallyconvertfromaprimitivetypetotheassociatedclassautomatically.

Page 41: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

SowecaninsteadsimplyassignaninttoanIntegerandautoboxingwilltakecareoftheconversionforuse.g.Integersix=6;

assertEquals("autoboxingassignmentfor6",

6,six.intValue());

StaticmethodsontheIntegerclass

Anotherfeaturethatclassesprovidearestaticmethods.

YoualreadyusedstaticmethodsontheAssertclassfromJUnit.i.e.assertEquals

Astaticmethodoperatesattheclasslevel,ratherthantheinstanceorobjectlevel.Whichmeansthatwedon’thavetoinstantiatetheclassintoavariableinordertocallastaticmethod.

e.g.Integerprovidesstaticmethodslike:

Integer.valueOf(Strings)-returnsanIntegerinitializedwiththevalueoftheString

Integer.parseInt(Strings)-returnsanintinitializedwiththevalueoftheString

YoucanseeallthestaticmethodsbylookingatthedocumentationforInteger,orinyourcodewriteInteger.thenimmediatelyaftertypingthe.theIDEshouldshowyouthecodecompletionforallthestaticmethods.

Foreachofthesemethods,ifyoupressctrl+q(ctrl+jonaMac)youshouldseethehelpfileinformationforthatmethod.

Exercise:ConvertaninttoHex:IntegerhasastaticmethodcalledtoHexStringwhichtakesanintasparameter,thisreturnstheintasaStringformattedinhex.

Writean@TestannotatedmethodwhichusestoHexStringandasserts:

that11becomesbthat10becomesathat3becomes3that21becomes15

PublicConstantsontheIntegerclass

Itispossibletocreatevariablesataclasslevel(thesearecalledfields)whicharealsostatic.Thesefieldvariablesareavailablewithoutinstantiatingtheclass.TheIntegerclassexposesafewofthesebutthemostimportantonesareMIN_VALUEandMAX_VALUE.

Inadditiontobeingstaticfields,thesearealsoconstants,inthatyoucan’tchangethem.(We’llcoverhowtodothisinalaterchapter).Thenamingconventionforconstantsistouseonlyuppercase,with_astheworddelimiter.

Page 42: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MIN_VALUEandMAX_VALUEcontaintheminimumandmaximumvaluesthatanintcansupport.Itisworthusingthesevaluesinsteadof-2147483648and2147483647toensurefuturecompatibilityandcrossplatformcompatibility.

Toaccessaconstant,youdon’tneedtoaddparenthesisbecauseyouareaccessingavariable,andnotcallingamethod.

i.e.youwrite“Integer.MAX_VALUE”andnot“Integer.MAX_VALUE()”.

Exercise:ConfirmMAXandMINIntegersizes:Inthepreviouschapterwesaidthatanintrangedfrom-2147483648,to2147483647.IntegerhasstaticconstantsMIN_VALUEandMAX_VALUE.

Writean@Testannotatedmethodtoassertthat:

Integer.MIN_VALUEequals-2147483648Integer.MAX_VALUEequals2147483647

DothisregularlyIencourageyoutodothefollowingregularly.

Whenyouencounter:

anyJavalibrarythatyoudon’tknowhowtousepartsofJavathatyouareunsureofcodeonyourteamthatyoudidn’twriteanddon’tunderstand

Thenyoucan:

readthedocumentation-ctrl+q(ctrl+jonMac)oron-linewebdocsreadthesource-ctrlandclickonthemethod,toseethesourcewritesome@Testannotatedmethods,withassertions,tohelpyouexplorethefunctionalityofthelibrary

Whenwritingthe@Testmethodsyouneedtokeepthefollowinginmind:

writejustenoughcodetotriggerthefunctionalityensureyouwriteassertionstatementsthatcoverthefunctionalitywellandarereadableexperimentwith‘odd’circumstances

Thiswillhelpyouwhenyoucometowriteassertionsagainstyourowncodeaswell.

WarningsaboutIntegerIusedIntegerinthischapterbecauseweusedtheintprimitiveinanearlierchapterandIntegeristherelatedfollowonclass.

Page 43: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

But…experienceddeveloperswillnowbeworriedthatyouwillstartusingIntegerinyourcode,andworse,instantiatingnewintegersinyourcodee.g.newInteger(0)

Theyworrybecausewhileanintequalsanint,anIntegerdoesnotalwaysequalanInteger.

I’mlessworriedbecause:

Itrustyou,Automationcodehasslightlydifferentusagesthanproductioncodeandyou’llmorethanlikelyusetheIntegerstaticmethodsI’musingthisasanexampleofinstantiatingaclassandusingstaticmethods,Thisisonly“Chapter4”andwestillhaveawaytogo

I’llillustratewithacodeexample,whytheexperienceddevelopersareconcerned.Youmightnotunderstandthenextfewparagraphsyet,butIjustwanttogiveyoualittledetailastowhyoneInteger,oroneObject,doesnotalwaysequalanotherObject.

e.g.ifthefollowingassertionswereinan@Testmethodthentheywouldpass:assertEquals(4,4);

assertTrue(4==4);

Notethat“==”istheJavaoperatorforcheckingifonethingequalsanother.

Ifthefollowingcodewasinan@Testmethod,thenthesecondassertionwouldfail:IntegerfirstFour=newInteger(4);

IntegersecondFour=newInteger(4);

assertEquals(firstFour,secondFour);

assertTrue(firstFour==secondFour);

Specifically,thefollowingassertionwouldfail:assertTrue(firstFour==secondFour);

Whyisthis?

Well,primitivesaresimpleandthereisnodifferencebetweenvalueandidentityforprimitives.Every4inthecodereferstothesame4.

Objectsaredifferent,weinstantiatethem,sothetwoIntegervariables(firstFourandsecondFour)bothrefertodifferentobjects.Eventhoughtheyhavethesame‘value’,theyaredifferentobjects.

WhenIdoanassertEquals,JUnitusestheequalsmethodontheobjecttocomparethe‘value’ortheobject(i.e.4inthiscase).ButwhenIusethe"=="operator,Javaischeckingifthetwoobjectvariablesrefertothesameinstantiation,andtheydon’t,theyrefertotwoindependentlyinstantiatedobjects.

SotheassertEqualsisactuallyequivalentto:assertTrue(firstFour.equals(secondFour));

Don’tworryifyoudon’tunderstandthisyet.Itwillmakesenselater.

Fornow,justrecognizethat:

Page 44: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

youcancreateobjectinstancesofaclasswiththenewkeyword,andusethenon-staticmethodsontheclasse.g.anInteger.intValue()youcanaccessthestaticmethodsontheclasswithoutinstantiatingtheclassasanobjecte.g.Integer.equals(..).

SummaryYoulearnedthatinIntelliJyoucanpressctrlandthentheleftmousebuttontoclickonamethodnameandIntelliJwilljumptothesourceofthatmethod.

Youlearnedthefollowingshortcutkeys:

Function Windows MacShowParameters ctrl+p cmd+p

ShowJavaDoc ctrl+q ctrl+j

Youalsolearnedaboutstaticmethodsandthedifferencebetweenobjectvalueandobjectidentity.

Whateveryoulearninthisbook,makesureyoucontinuetoexperimentwithwritingassertionsaroundcodethatyouuseorwanttounderstand.

Youalsolearnedhowtoinstantiateanewobjectandwhataconstructordoes.

ReferencesandRecommendedReading

CreatingObjectsdocs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html

Autoboxingdocs.oracle.com/javase/tutorial/java/data/autoboxing.html

Integerdocs.oracle.com/javase/7/docs/api/java/lang/Integer.html

Page 45: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterFive-WorkingwithOurOwnClasses

ChapterSummaryInthischapteryouwilllearnhowto:

WriteyourownclassWrite@TestannotatedmethodstohelpcheckyourclassmethodfunctionalityCallthemethodsontheclassCreatestaticmethodsandstaticconstantsSeethedifferencebetweenstaticandnon-staticUsetheIDEtowritemuchofyourcodeforyou

AndyouwilllearnhowtodoallofthisusingTestDrivenDevelopment.

WhenwewritecodeusingTDD(TestDrivenDevelopment)wewrite@Testmethodsandassertionsfirst,andthenwritethecodetomaketheassertionspass.

IliketodothiswhenI’mwritingcodebecauseIcanusetheIDE’sfeaturestohelpmetypelessandwritecodewithfewersyntaxerrors.

ContextThroughoutthisbookIwanttouseexamplesandcodewhichprepareyouforusingJavaintherealworldwhenwritingautomationcodetosupporttesting.AssuchwearegoingtobebuildingdifferenttypesofexamplesthanwewouldinanormalJavabook.

Wearegoingtostartsmall,andIwanttointroduceyoutotheconceptofa‘domain’object.A‘domain’objectisanobjectinstantiatedfromaClasswhichrepresentssomethinginthe‘domain’youareworkingine.g.ifyouworkonabankingapplicationthenyoumighthave‘domain’objectssuchas:account,balance,transaction,etc.

Whenwebuildautomationcodeweneedtobuildalibraryofsupportingobjectstohelpus.Wedothissothat:

ourcodeismaintainable,ourcodebecomemorereadable,ourcodeisfastertowrite,becausewehavehigherlevelabstractionstohelp,weavoidrepeatingcode.

Alloftheabovearenormalcodingprocessgoodness.Becausewhenwewriteautomationcodeforaproductionapplication,wearewritingproductioncode,anditmuststanduptothesamescrutinythatweapplytotheliveproductioncode.

Wehaveanumberofpossibleobjectgroupingswhenwritingautomationcode,thefollowingisoneIusealot:

Physical

Page 46: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Applicatione.g.loginpage,navigationmenu

Environmentale.g.installedURI,port

LogicalDomainEntities

e.g.user,account

Essentiallyyoucanbuildasmanycategorizationsandmodelinglevelsasyouneed,inordertoeffectivelymodelyoursystem.Irecommendthebook‘DomainDrivenDesign’byEricEvans,ifyouwanttolearnmoreaboutdomainmodeling.

FortheexamplesinthischapterwearegoingtolookatanenvironmentaldomainobjectcalledTestAppEnvwhichrepresentsthetestenvironmentwerunourautomationandassertionsagainst.

Imaginethatyouhaveanapplicationundertest,thatyouhaveinstalleditonanumberoftestenvironments,andyouwanttorunyourautomationcodeonanyofthoseenvironments(andpossiblyonlive).

Youdon’twanttohavetochangeyourautomationcodeeverytimeyouuseadifferentenvironment,soyouwanttoabstractawaytheactualenvironmentconfigurationbehindanobjectthatwillhandlethatforyou.

Soinsteadofwritingan@Testmethodlikethefollowing:@Test

publicvoidcheckTitleCorrectOnApp(){

FirefoxDriverdriver=newFirefoxDriver();

driver.get("http://192.123.0.3:67");

assertEquals("Titleshouldmatch",

"TestApp",driver.getTitle());

}

Note:theabovesamplecodeaboveusestheWebDriverAPI,soitwon’tworkifyoutypeitin.Whatitsaysis:startFirefoxbrowser,opentheURL"http://192.123.0.3:67"andcheckthepagetitleis"TestApp".

Youcouldinsteadabstractawaytheapplicationconnectiondetailsintoanenvironmentdomainobject,e.g.TestAppEnv:@Test

publicvoidcheckTitleCorrectOnAppWithDomainObject(){

FirefoxDriverdriver=newFirefoxDriver();

driver.get(TestAppEnv.getUrl());

assertEquals("Titleshouldmatch",

"TestApp",driver.getTitle());

}

Bydoingthis,insteadofhavingahardcodedStringliteral"http://192.123.0.3:67"inallyour@Testmethods,youmakeacalltoanobjectTestAppEnv.getUrl().

Page 47: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Byfollowingalongwiththetextinthischapter,youaregoingtobuildtheTestAppEnvclass,withitsassociated@Testmethodsandassertions.

Firstcreatean@TestmethodThefirstthingwewanttodo,iscreatean@Testmethod.

Todothat,weneedaClasstoputthemethodin.

@Testmethodsresideinthetestfolderhierarchyofyourproject.I’mgoingtocreateapackagecalled

com.javafortesters.chap005testwithourownclasses.domainobject.examples

Andinthatpackage,createaclasscalledTestAppEnvironmentTest.

ReminderonpackageandJUnittestclasscreationUsetheProjectTreetocreatepackages.Clickontheparentpackage,intheappropriatesrcfolderbranche.g.src\test\javathenrightclickandselectNew\Package.Thenenterthepackagename.

Ifyoumessitupyoucandeleteitandstartagain,orjustdragitintothecorrectplaceusingtheProjectTree.

UsetheProjectTreetocreateclasses.RepeattheabovebutchooseNew\JavaClassinthepackageyouwanttocreatetheclass.

packagecom.javafortesters.chap005testwithourownclasses.domainobject.examples;

publicclassTestAppEnvironmentTest{

}

[email protected]’mgoingtocreateonecalledcanGetUrlStaticallybecauseIhavedecidedthatIwanttobeabletoretrievetheURLfromtheTestAppEnvclassstatically,ratherthaninstantiateanewinstanceofTestAppEnveverytimeIwanttouseit.@Test

publicvoidcanGetUrlStatically(){

}

Reminderon@TestmethodcreationCreatethemethodcodeinsidethebodyoftheclass,betweenthestart{andend}codeblockbraces.

Remembertoaddimportorg.junit.Test;toimportthe@TestannotationiftheIDEdoesnotadditautomatically.

Writecodethatdoesn’texistSinceIhaven’tcreatedtheTestAppEnvclassyet,anycodethatIwriteusingit,isn’tgoingtowork.

Thenaturaltendencythen,wouldbetogooffancreatetheTestAppEnvclass,writethecode,andthencomebacktoourJUnittestclassandwritemethodsandassertionsto

Page 48: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

checkit.

Wearenotgoingtodothat.Wearegoingtodriveourcodecreationbywritingautomationcode.

SointhecanGetUrlStatically@Testmethodwearegoingtowritethecodethatwewanttoseeexist.

Ineffectwearedesigningthecodebyseeingitinausagecontext.

SoinmymethodcanGetUrlStaticallyIwritetheline:assertEquals("ReturnsHardCodedURL",

"http://192.123.0.3:67",

TestAppEnv.getUrl());

WecanautomaticallyaddtheimportforassertEqualsfromtheJUnitAssertpackage.ButtheIDEwillcomplainthatitcannotresolvesymbolTestAppEnv.Nosurprisethere,sincewehaven’twrittenityet.

ButwearegoingtolettheIDEdothehardliftinghere,andhaveitcreatetheclassforus.

CreateaClassClickonTestAppEnvandpressthekeysalt+enter(IntelliJ’sIntentionActionsshortcutkey)andyoushouldseeasmallpopupmenuofquickfixoptions.Somethinglike:

Createlocalvariable'TestAppEnv'

Createclass'TestAppEnv'

Createfield'TestAppEnv'

Createinnerclass'TestAppEnv'

Createparameter'TestAppEnv'

etc.

TheimportantoneforusisCreateclass'TestAppEnv'

SelectCreateclass'TestAppEnv'thenweneedtotelltheIDEwherewewanttocreateit.

Wearegoingtouseadifferentpackage.

Weusepackagestoorganizeourcode,andjustbecauseour@Testmethodcodehasbeenorganizedintoapackageforthischapter,itdoesn’tmeanthatourdomainobjectneedstobeinthesamepackage.

I’mgoingtouseapackage:packagecom.javafortesters.domainobject;

Sincethisisclassispartofmyabstractionlayer,Idon’twantititinthesrc\test\javafolderstructure,Iwantitinmymaincodesrc\main\java.MakesureyouchangetheTargetdestinationfolderandcreateitinthemaincodebase.

Page 49: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Don’tworryifyoumessitupItisimportantthatwetrytochoosegoodpackagenames,butitisalsoimportantthatwedon’tgettoohunguponit,becausere-organizingthecodeintodifferentpackagesisprettyeasyoncethecodeisworking,andtheIDEhasalotofautomatedrefactoringtoolstomakethatsimple.

Samewiththetargetdestination.Ifyoumessitup,justdeleteitandtryagain,ordragdropthefilesintheProjecttreetogetitthewayyouwant.

Withthedomainobjectclasscreated,jumpbacktoyourJUnittestclass,andseewhatnewerrorexistsinthecode.

CreateamethodNowtheIDEshouldhavehighlightedgetUrl()ashavingaproblembecauseitCannotresolvemethod'getUrl()'

Again,wehaven’tcreatedthatmethod.AndwecanusetheIDEquickfixfunctionalitytohelpus.

ClickonthegetUrlcodeandpressthekeysalt+enterandselectCreatemethod'getUrl'

TheIDEwillcreatethemethodandmayevenaddareturnnull;inthereforustoo,tomakethecodevalid.1packagecom.javafortesters.domainobject;

2

3publicclassTestAppEnv{

4

5publicstaticStringgetUrl(){

6returnnull;

7}

8}

Addthecodetomakethe@TestmethodpassSinceour@Testmethodisbeingwrittentomatchourfictionalenvironment.WeneedthegetUrlmethodtoreturn"http://192.123.0.3:67".

Allwedothen,isreplacenullinthemethodbodycodeblock,withtheStringwewanttoreturn.publicclassTestAppEnv{

publicstaticStringgetUrl(){

return"http://192.123.0.3:67";

}

}

Ifwejumpbacktoour@Testmethodnow.

Weshouldhavenosyntaxerrorsandwecanrunthe@Testmethod.

AquickexplanationofthecodeTherearenonewconceptsinthe@Testmethodyouhavewritten,weareusingthesame

Page 50: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

conceptsthatweusedinthepreviouschapter.

TheTestAppEnvclass,allowsustorevisitafewconceptsinmoredetail.

ThemethodgetURLwasdeclaredaspublicstaticString

publicthismethodisaccessibletoanyclassthatimportsTestAppEnvstaticthismethodcanbeusedandcalled,withoutinstantiatingaTestAppEnvobjectStringthismethodreturnsastring,tothecallingcode

BecausethemethodneedstoreturnaStringweaddareturnstatement.return"http://192.123.0.3:67";

ThisparticularreturnstatementpassesbackaStringliteral.WhichisthenusedintheassertEqualsstatementinthemethod.

Exercise:ExperimentwiththecodeReplacetheStringwithanint.Whathappens?ReplacetheStringliteral"http://192.123.0.3:67"[email protected]?

WhatwejustlearnedAgain,wehavecondensedawholebunchofconceptsintoafairlysmallpieceofworkingcode.

Youlearned:

HowtouseIntelliJQuickFixfunctionality“IntentionActions”(alt+enter)towritecodeThebasicsofTDD:

writeafailing@Testmethod,runit,watchitfail,writejustenoughcodetomakeitpass,runit,watchitpass,repeat.

HowtocreateastaticmethodHowtodeclareamethodthatreturnsavalueHowtoreturnavaluefromamethodHowtocallastaticmethodonaClassHowtouseamethod’sreturnedvalueinanassertstatement

NewRequirements

Page 51: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Nowthatwehaveaworking@Testmethod,wecanstarttorefactortheobjectandmakeitmoresuitableforourneeds.

Immediatelythough,ifwehadusedtheString"http://192.123.0.3:67"anywhereinourcode,wecouldreplaceitwithTestAppEnv.getUrl()andgainthebenefitsofabstractionandmaintenance.

I’mgoingtoaddafewmorerequirementssothatwecanlearnalittlemoreJavaandamendourclass.

Sometimesinourautomationcodewedon’talwayswanttogetthefullURL,sometimeswewant,justtheDomainorjustthePort.

Myinitialideaisthatwewanttobeabletodothefollowing:@Test

publicvoidcanGetDomainAndPortStatically(){

assertEquals("JusttheDomain",

"192.123.0.3",

TestAppEnv.DOMAIN);

assertEquals("Justtheport",

"67",

TestAppEnv.PORT);

}

Notice,thatagain,I’mthinkingthroughtheusageandthecodewithan@Testmethod.BywritingthecodeIwanttosee,Icanexperimentwithdifferentconceptsbeforeactuallywritinganyimplementationcodetomakethe@Testmethodpass.

AllwehavetodonowisimplementthetwonewConstantFieldsDOMAINandPORT.

Typeinthenew@Testmethodcode,andusetheIntelliJQuickfixfunctiontocreatetheseConstantFields.

FieldsAfieldisaJavavariablethatisattheclasslevelratherthanlocaltoamethod.

Constantmeansthatitwon’tchangeonceavaluehasbeenassigned.

Fieldsarelocatedwithintheclasscodeblock.And,byconvention,beforeanymethods.

YoushouldendupwithcodelikethefollowinginyourTestAppEnvobject.publicstaticfinalStringDOMAIN="192.123.0.3";

publicstaticfinalStringPORT="67";

public-thefieldcanbeaccessedbyanycodethatimportstheTestAppEnvclassstatic-TestAppEnvdoesnotneedtobeinstantiatedwithnewbeforeusagefinal-thevariablecannotchangeonceavaluehasbeenassignedString-declaresthevariableasaStringobjectDOMAIN,PORT-byconventionconstantsarewritteninuppercase,withmultiplewordsdelimitedby_underscore

Page 52: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IsettheconstantstothethestringvaluesthatwepassedbackoriginallyinthegetUrlmethod.

Ifwerunour@Testmethods,theyshouldpass.

NowRefactorAnimportantelementofTDD,andallprogramming,istorefactor.

Thismeansgoingback.Lookingatourcode.Identifyingwasteandimprovements.Andchangingthecode,suchthatthe@Testannotatedmethodscontinuetopass,andnoexternalinterfacetothecodeisamended.

Inourcase,thismeansthatwecanchangeanyofthecodeinourTestAppEnvsolongaswestillhavetwofieldsnamedDOMAINandPORTandamethodgetUrlwhichreturnsthesameStringobjectsasthatcheckedbytheassertions.

TheobviousthingtochangeisthatwehaverepeatedStringliteralsinourdomainobjectsinceourDOMAINstringandPORTstringarerepeatedaspartofthehardcodedStringingetUrl.i.e.thefollowinglinereturn"http://192.123.0.3:67";

AlittlestringconcatenationSincethevaluesoftheDOMAINconstantandthePORTconstantarepartofthehardcodedStringingetUrlwereallywanttobuildtheStringpassedbackfromgetUrlusingtheDOMAINandPORTconstants,thatwayiftheenvironmentdetailschangethenweonlyhavetoamendthefields,andnottheStringinthemethods.

Stringconcatenationissomethingwedoalotwhenbuildingautomationcodee.g.:

creatingmessagestosendtosystemsgeneratinginputdatacreatinglogmessagesetc.

I’mgoingtoquicklyshowthesimplestwayofconcatenatingStrings.Andinfactyou’vealreadyseenthecodeweneedtouse.+

Yes,the‘plus’signcanjointhevaluesofStringobjectstogether.

IcanamendthegetUrlmethodsothatitusesDOMAINandPORTreturn"http://"+DOMAIN+":"+PORT;

Bydoingthis,IhavereducedtheduplicatedcodeandonlyhavetochangeasinglelineofcodeintheabstractionlayerifIwanttochangetheenvironmentdetailsusedbythe@Testmethods.

RuntheJUnittestclassandmakesurethatthe@Testmethodsstillpass.

Page 53: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThereismorethatIcoulddotothisclass,butfornowitisgoodenough,andwewillrevisititlater.

TheTestAppEnvcodeI’veincludedthesourcecodewebuiltinthischaptersoyoucancheckyourresults.LaterchapterswillnotincludethefullsourcecodesinceIrecommendthatyoudownloadandviewthefullsourceusedforthebook(seetheIntroductionchapterfordetails).

Afterallthechanges,yourTestAppEnvclassshouldlooklikethefollowing:1packagecom.javafortesters.domainobject;

2

3publicclassTestAppEnv{

4

5publicstaticfinalStringDOMAIN="192.123.0.3";

6publicstaticfinalStringPORT="67";

7

8publicstaticStringgetUrl(){

9return"http://"+DOMAIN+":"+PORT;

10}

11}

Sinceitisaverysimpleclass,wehavenothadtoaddanyadditionalimports.

AndthecodefortheTestAppEnvironmentTestclasswhichweusedtocreateTestAppEnvisshownbelow:1packagecom.javafortesters.chap005testwithourownclasses.domainobject.examples;

2

3importcom.javafortesters.domainobject.TestAppEnv;

4importorg.junit.Test;

5importstaticorg.junit.Assert.assertEquals;

6

7publicclassTestAppEnvironmentTest{

8

9@Test

10publicvoidcanGetUrlStatically(){

11assertEquals("ReturnsHardCodedURL",

12"http://192.123.0.3:67",

13TestAppEnv.getUrl());

14}

15

16@Test

17publicvoidcanGetDomainAndPortStatically(){

18

19assertEquals("JusttheDomain",

20"192.123.0.3",

21TestAppEnv.DOMAIN);

22

23assertEquals("Justtheport",

24"67",

25TestAppEnv.PORT);

26}

27}

StaticUsageversusStaticImport

Page 54: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Onethingtopointout,nowthatwehaveexamples,isthedifferencebetween‘StaticUsage’and‘StaticImport’.

YoucanseeexamplesofbothintheTestAppEnvironmentTestcode.

StaticUsage

WeusethestaticconstantsfromTestAppEnv.SoweimporttheTestAppEnvclass:importcom.javafortesters.domainobject.TestAppEnv;

AndeverytimewewanttousethestaticconstantsDOMAINorPORT,weprefixthemwiththeclassthattheyarefrom,i.e.TestAppEnv,asshowninthecodebelow:TestAppEnv.DOMAIN);

StaticImport

WestaticallyimporttheassertEqualsfromJUnit.importstaticorg.junit.Assert.assertEquals;

ThismeansthatwecantypeassertEqualsinourcodewithouthavingtoprefixitwithAssertinthesamewaythatwedofortheDOMAINandPORTconstantsfromTestAppEnve.g.assertEquals("ReturnsHardCodedURL",

"http://192.123.0.3:67",

TestAppEnv.getUrl());

Theonlydifferenceistheimport

BoththeassertEqualsmethod,andtheconstantsDOMAINandPORT,aredeclaredasstaticandpublic,intheirrespectiveclasses.

TheonlydifferenceinourJUnittestcode,ishowweimportedthem.

HadIimportedtheJUnitassertinanon-staticmanneri.e.thesamewayIimportedTestAppEnv:importorg.junit.Assert;

ThenIwouldnothavebeenabletowriteassertEqualsinmycode,IwouldhavetoprefixitwithAsserte.g.Assert.assertEquals("ReturnsHardCodedURL",

"http://192.123.0.3:67",

TestAppEnv.getUrl());

Similarly,IcouldhaveimportedtheTestAppEnvconstantsDOMAINandPORTstatically,andthenavoidedtheprefixTestAppEnvoneachusage.

IcouldeitherimportstatictheDOMAINandPORTasseparateimports,orjustimporteverythingfromTestAppEnv,andthenIwouldn’thavetoprefixcallstogetUrle.g.importstaticcom.javafortesters.domainobject.TestAppEnv.*;

Page 55: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:ConvertfromStaticUsagetoStaticImportExperimentwiththestaticimportinyourTestAppEnvironmentTest.

ConverttheassertEqualsimportstatictoanimportofjusttheAssertandamendthe@TestmethodsaccordinglysoyouprefixeachusageofassertEqualswithAssert.ConverttheimportofTestAppEnvtoanimportstaticoftheDOMAINandthePORT,andconvertthe@Testmethodssoyouusethemwithouttheprefix.ConverttheimportofTestAppEnvtoanimportstaticofeverythinginTestAppEnvandconvertthe@Testmethodssotheconstantshavenoprefix.

Asyoumakethechanges,reflecton:howdoestheautomationcodelook?isitmaintainable?etc.

Howtodecidewhattostaticimport

Decidingwhattoimportstaticallymightbemadeforyouthroughorganizationalcodingstandards.i.e.someteamsalwayswriteAssert.assertEquals

Iusuallymakethedecisionbasedonmystandardsofreadability,soIgenerallyimportstatictheassertmethodsIuse.ButIprobablywouldnotimportstatictheTestAppEnvconstantssinceIdon’tthinkthatseeingDOMAINorPORTinthe@TestmethodsreallygivesmeenoughinformationandI’dwonder“whichdomain?”and“whichport?”,butIrarelywonder“whichassertEquals?”.

Overuseofimportstaticcanmakeyourcodelessreadablebecausepeoplemightconfuseyourstaticallyimportedmethod,orconstant,asonewhichislocallydefined.

Theimportantpointatthemomentistoknowthatyou:

haveachoiceoverhowyoustaticallyimport.decidewhichapproachtouseonacasebycasebasis(orfollowyourorganizationalstandards).canmakecodelessreadableandmaintainableifyouimportstatictoomanymethodsandconstants,sousethispowersparingly.

SummaryAgain,I’vetriedtocondenseabunchoflearningintoasinglechapter.Ihopeyoumanagedtofollowalong.Ifnot,gobackthroughthischapterandtryagain,orcompareyourcodetothemainGithubsource(orincludedabove).

Wecoveredalotoffundamentalconcepts,andhavingactuallydonethework,bytypingitintoyourIDE,youwillhavelearnedmorethanyoumayrealize:

Wemanagedtomakeiteasiertoamendtheenvironmentlocation.Weabstractedthechangeawayfromthe@Testmethodssothatourabstractioncodecanchangewithoutrequiringanyothercodechangesinthetestbranch.Wenowknowhowtocreatestaticmethods.Wenowknowhowtocreatestaticconstantfields.Wenowknowalittlerefactoring.WeknowalittleStringconcatenation.

Page 56: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Weknowtokeepourabstractionsinsrc\main\javaandour@Testmethodsinsrc\test\java.Weknowthatwecanuseclassesfromotherpackages.Weknowthatwecanorganizeour@Testmethodcodedifferentlyfromourabstractioncode.

OurnextfewchaptersaregoingtoconcentrateonlearningsomeoftheJavaConceptsandlibrariesthatweneedtounderstandtohelpuswriteautomationcode.

Page 57: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterSix-JavaClassesRevisited:Constructors,Fields,Getter&SetterMethods

ChapterSummaryInthischapteryouwilllearnhowto:

UnderstandwhataConstructorisCreateadefaultconstructorCreateaconstructorwithparametersCalloneconstructorfromanotherCreategetterandsettermethods

Thefirstfewchaptershavebeen‘throwinthedeepend’and‘tutorials’.

NowwearegoingtostepthroughJavaconceptsinmoredetail.

Wecandothatbecauseyoualreadyknowhowto:

createclasses,createmethods,annotatedmethodswith@TesttorunthemasJUnittests

ContextWhenmodelingapplicationsoneoftheDomainEntitiesIoftenendupcreatingisUser.Typicallysomeonewithanaccountonthesystemwhocanloginwitha‘username’and‘password’.Itmayhaveafewotherdetailsaswell.

FortheexamplesinthischapterweshouldimaginethatwewanttobuildaUserobjectforuseinourJUnittests.

Weneedtofollowthenormalprocesstogetusstarted:

createapackage'com.javafortesters.domainentities'createitundersrc.main.javasinceitisanabstraction,notaJUnittestclassinthepackagecreateaclassUser

1packagecom.javafortesters.domainentities;

2

3publicclassUser{

4}

NextcreateaJUnittestclasstoallowustoconstructtheclassusingTDD.

createapackage'com.javafortesters.chap006domainentities.examples'remembertocreateitundersrc.test.javainthepackagecreateaclassUserTest

Page 58: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

1packagecom.javafortesters.chap006domainentities.examples;

2

3publicclassUserTest{

4}

Constructor

WhatisaConstructor?Aconstructorisaspecialmethodthatiscalledwhenaclassisinstantiatedwiththenewkeyword.

Writean@Testmethodwhichinstantiatesanewuser:@Test

publicvoidcanConstructANewUser(){

Useruser=newUser();

}

Hopefullynosyntaxerrors-remembertoimportorg.junit.Test.

YouwouldalsohavetoimporttheUserclass.

SharingthesamepackageIftheUserclassandtheUserTestclasswereinthesamepackagethenyouwouldbeabletousetheUserclasswithoutimportingit.

Theclasseswouldbeindifferentfolderstructures,butiftheywereinthesamepackagethenyoucoulduseanypublicclassesinthesamepackagewithoutimportingthem.

ExperimentwiththepackagestructureMovetheUserTesttoadifferentpackage,eitheraboveorinasiblingto.domainentities.CanyouusetheUserclasswithoutimportingit?

Watchout-dependingonhowyoumovedit,yourIDEmighthaveaddedtheimportforyouautomatically.

PackageScopingIfyoudeclareafieldormethodwithnomodifieri.e.missoutthepublic,thenonlyclassesinthesamepackagecanuseit,noteveryclassthatimportsit.

DefaultConstructorIfyourunthe@Testmethod-whatdoesitdo?

Well,nothingreally.

Page 59: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ItcreatesanewinstanceoftheclassUserandstoresitinthevariableuser.ButwedidnotcreateaconstructorontheUserclass,thereforenocodeintheUserclassisexecutedwhentheobjectisinstantiated.

Nowweshalladdsomecodethatexecuteswhentheclassisinstantiated,bywritingaconstructor,intheUserclass,thatdoesn’ttakeanyarguments,knownasano-argumentconstructor.

DefaultConstructorIfyoudon’twriteaconstructor,thenJavaautomaticallycreatesonewhichsetsallyourfieldstotheirdefaultvaluesandcallsthedefaultconstructorforanysuperclass.(wehaven’tcoveredsuperclassyet,sothiswillmakesenselater)

No-argumentConstructorIfwehaveparticulardefaultsinmindforfieldsontheclassthenagoodplacetoinitializethemisinano-argumentconstructor.

Iwanttohaveausernamefieldandapasswordfieldandhavethemdefaultto"username"and"password".

IcouldjustgointotheUserclassandcreatecodetosetthisup,butIwanttogetinthehabitofcreating@Testmethodsfirst.

Tohelpmemaintainthathabit,I’mgoingtocreatean@TestmethodwhichcreatesaUserobjectandthengetstheusernameandpasswordandassertstheyhavebeensettomydesireddefaultvalues.

Idothisbycreatingan@Testmethodwhichlookslikethis:@Test

publicvoiduserHasDefaultUsernameAndPassword(){

Useruser=newUser();

assertEquals("defaultusernameexpected",

"username",

user.getUsername());

assertEquals("defaultpasswordexpected",

"password",

user.getPassword());

}

ThegetUsernameandgetPasswordmethodsdon’texistsoIhavetocreatethem.

MyIDEcancreatethebasicmethodsforme,butIdon’thaveanyusernameorpasswordtoreturn.WhichmeansitisnowtimetoaddusernameandpasswordasfieldsinmyUserclass.

IcreateaconstructorinUserthattakesnoarguments.Andassigndefaultvaluestothefieldsusernameandpassword.Demonstratedbythefollowingcode:

Page 60: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

privateStringusername;

privateStringpassword;

publicUser(){

username="username";

password="password";

}

Inthecodesnippet,youcanseethatIcreatedaStringvariableusernameandaStringvariablepassword.Becausethesevariablesaredeclaredinthebodyoftheclass,ratherthaninamethod,theyareknownasfieldsorfieldvariables.

IhavedeclaredthemprivatesothattheyareonlyaccessibletomethodsintheUserclassitself,andnotfromanyclassesthatimporttheUserclass.

TheconstructorIhavewrittentakesnoarguments.Youknowitisaconstructorbecauseitdoesnothaveareturntypeinthedeclarationandthenameisexactlythesameasthatoftheclass,completewithuppercaseletter.

Iassigndefaultvaluestotheusernameandpasswordinthebodyoftheconstructor.Anymethodinaclasscanamend,andaccess,thefieldvariablesdeclaredinthatclass.

Icanthenwritethemethodsthatreturntheusernameandpassword,[email protected](){

returnusername;

}

publicStringgetPassword(){

returnpassword;

}

Thecodeshouldpassnow.Writethecode,andrunthe@Testmethodtoseethisforyourself.

AfewnotesontheUserclass

ThegetUsernameandgetPasswordmethodsareknownasaccessororgettermethodsbecausetheyallowusto‘access’,or‘get’thevalueofafield.Theytakenoparameters,andreturnthevaluesofthefieldvariables.

Thecombinationofthefieldusername,andthegettermethodgetUsername,issometimesknownasa‘property’.

Becausewedeclaredthefieldvariablesasprivate,weneedtocreatemethodswhichallowotherclassestoaccessthevaluesofthosevariables.

Icouldhavemadethefieldvariablespublic,andthenIwouldnothaveneededtocreateanaccessormethod,butthenIreducetheamountofcontrolthatwehaveoverthevaluesbecauseotherclassescouldamendthevaluesofthosefieldsatanypoint.

Page 61: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ExperimentwithprivateandpublicfieldsTryitforyourself.Makethefieldspublicandinan@Testmethod,setusernameandpasswordtoanewvalue,andgetthevaluejustbyaccessingthefield.

e.g.Userauser=newUser();auser.username="bob";assertEquals("notdefaultusername","bob",auser.username);

AConstructorwithargumentsAtthemomentwehavenowayofchangingtheusernameandpasswordonaUser.SowewillwriteaconstructorwhichallowsustocreateaUserobjectandsettheusernameandpasswordatthesametime.

Asdemonstratedinthefollowingcode,youcanseethatIcreateaUserwithausernameof"admin"andapasswordof"pA55w0rD":@Test

publicvoidcanConstructWithUsernameAndPassword(){

Useruser=newUser("admin","pA55w0rD");

assertEquals("givenusernameexpected",

"admin",

user.getUsername());

assertEquals("givenpasswordexpected",

"pA55w0rD",

user.getPassword());

}

Tomakethis@Testmethodpass,wehavetocreateanewconstructorinUser,thistimeaconstructorwhichtakestwoparameters,theusernameandpasswordwewanttoassigntotheUser.Thisconstructorisshownbelow:publicUser(Stringusername,Stringpassword){

this.username=username;

this.password=password;

}

Notethattheconstructornowhastwoparameters:StringusernameandStringpassword.

Becausetheseparametershavethesamenameasthefields,Ihavetousethethiskeywordinthemethod,whenIwanttoaccesstheusernameandpasswordfieldonthecurrentobject.IfIdidnotaddthis.thenJavawouldnotbeabletodistinguishbetweenthefieldandtheparameter.

IcouldhaverenamedtheparametersaUsernameandaPasswordtoavoidanamingclash.ButIwanttominimizethedocumentationIhavetoproduce,andkeepingtheparameternamesself-documentinghelpslongtermmaintenance.Alsothisgivesustheopportunitytointroduceyoutothethiskeyword.

Page 62: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ExperimentwiththefieldandparameternamesWritetheconstructorcode,asshowninthetextwhichusesthethiskeyword.

Removethethis.fromtheconstructor,andwhathappens?

Changetheconstructorparameternamessothatthe@Testmethodpassesandyoudonotusethethiskeyword.Whenwouldyoudothis?

this

Thethiskeywordreferstothecurrentobject.

Youcanuseanymethodorfieldintheobjectwiththethiskeyword.

Thethiskeywordhelpsyoudistinguishbetweenlocalvariableswiththesamenameasfields.

Youcanalsousethethiskeywordtocallmethodsorconstructors.

ExplicitConstructorInvocationIfyoufollowedtheprevioussectionsthenyouwillnoticethatyouhaveduplicatedcodeintheUserclass,sincetheno-argumentconstructorhascodetoassignvaluestothefields,asdoestheconstructorwhichdoestakearguments.publicclassUser{

privateStringusername;

privateStringpassword;

publicUser(){

username="username";

password="password";

}

publicUser(Stringusername,Stringpassword){

this.username=username;

this.password=password;

}

Wecancalloneconstructorfromanother

Usingthethiskeywordwecancalltheargumentconstructorfromtheno-argumentconstructor,e.g:publicUser(){

this("username","password");

}

Byrefactoringtothiscode,we:

onlyhaveoneplacewheretheusernameandpasswordfieldsareassignedvalues,stillretaintheabilitytocallthedefaultconstructorandassigndefaultstothefields.

i.e.

Page 63: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

publicUser(){

this("username","password");

}

publicUser(Stringusername,Stringpassword){

this.username=username;

this.password=password;

}

GettersandSetters

GettersYouhavealreadyseentwogetter(oraccessor)methodsintheUserclassi.e.getUsernameandgetPassword.publicStringgetUsername(){

returnusername;

}

publicStringgetPassword(){

returnpassword;

}

SettersWealsowanttheabilitytoamendorsetfieldvaluesinaclass.Wedothisthroughsettermethods.

Forourcodewewanttohavetheabilitytoamendthepasswordbutnottheusername.

Onceourusernamehasbeensetviaaconstructorinvocation,weneverwanttoallowanycallingclassestoamendtheusername,butwedowanttoallowamendingthepassword.

Toamendthepasswordwewillwriteasettermethod(setPassword),whichweuseasspecifiedinthiscode:@Test

publicvoidcanSetPasswordAfterConstructed(){

Useruser=newUser();

user.setPassword("PaZZwor6");

assertEquals("setterpasswordexpected",

"PaZZwor6",

user.getPassword());

}

AndtheactualsettermethodintheUserclasslookslikethis:publicvoidsetPassword(Stringpassword){

this.password=password;

}

AgainyoucanseetheuseofthethiskeywordtodistinguishbetweenthefieldandthelocalvariabledefinedbytheStringpasswordparameter.

Writethecode,andrunthe@Testmethodstomakesureallourassertionsstillpass.

Page 64: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

WhySettersandGetters?Bycreatingasettermethodwegaintheabilitytocontrolthevaluesthatareassignedtothefieldse.g.

wecouldaddcodeforvalidationandmakesurewecan’tassignincorrectpasswordsifapasswordhadtobeminimumlengthwecouldwritecodetopadittothecorrectlengthifweneededto

Wecanusegettermethodstohidetheimplementation,e.g.wemight‘calculate’thereturnvalue,ratherthanalwaysreturnsomethingwhichhasbeenset.

Thereareoccasionallytimeswherewewanttoloosenupcontrolovertheobjectfieldsandmakethempublic,sopeoplecanamendthemandaccessthemwhenever,andhowevertheywant.Butwearemuchmorelikelytousesetterandgettermethodstocontrolaccessandallowustheflexibilityinthefuturetochangeimplementationdetails.

SummaryYoushouldnowknowhowto:

createano-argumentconstructorbycreatingapublicscopemethodwithnoreturntypewhichhasthesamenameastheclasscreateaconstructorthattakesparametershaveparametersnamedthesameasfields,andusetheminthesamemethodbodycallaconstructorfromanotherconstructorcreategettermethodswhichreturnvaluescreatesettermethodstoamendfieldvariablesusethethiskeywordtodistinguishbetweenobjectfieldsandmethodparameters

Andyoushouldalsounderstand:

thebasicsoffieldandmethodscopingpublic,privateandwithnoexplicitscope(package).

UserclasscodeForyourreferenceandcomparison,wecreatedthefollowingUserclass,inthischapter:packagecom.javafortesters.domainentities;

publicclassUser{

privateStringusername;

privateStringpassword;

publicUser(){

this("username","password");

}

publicUser(Stringusername,Stringpassword){

this.username=username;

Page 65: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

this.password=password;

}

publicStringgetUsername(){

returnusername;

}

publicStringgetPassword(){

returnpassword;

}

publicvoidsetPassword(Stringpassword){

this.password=password;

}

}

ReferencesandRecommendedReading

AccessControldocs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

DefaultConstructordocs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9

Constructorsdocs.oracle.com/javase/tutorial/java/javaOO/constructors.html

Java‘this’keyworddocs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

Page 66: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterSeven-BasicsofJavaRevisited

ChapterSummaryInthischapteryouwillreceiveanoverviewof:

JavaCommentsJavanamingconventionsWorkingwithpackagesScopeoffields,methodsandclassesthefinalkeywordDataTypes:boolean,integer,floatingpoint,characterandtheirwrapperclassesBigDecimal

Operators:Arithmetic,Assignment,Boolean,Conditional,TernaryandBitwiseOperatorPrecedenceStringconcatenationandstaticmethods

Thischapterwillquicklyreinforcethetopicscoveredintheprevioustutorialchapters.Youwillalsoseereferencetoconceptsyouhavenotyetcoverede.g.BigDecimal,wementionthesebecauseitmakessenseincontext,butwewillcoverthedetailslater.

Therearenospecificexercisesinthischapter,althoughyoushouldreadthroughtheexamplecodetomakesureyouunderstandit.Ialsorecommendthatyouwrite@Testmethodstoexperimentwithyourownexamplesandverifythestatementsmadeinthischapter.

Youcanusethisasareferencechapterforlaterstudy.Restassuredthatwecontinuetobuildonthisinformationinlaterchapters,sodon’tworryifyoudon’tabsorbitallonfirstreading.

CommentsCommentsarenon-executablestatementsinthecode.

Thereare3typesofcomments:

commentsthatruntotheendoftheline//commentsthatmarkoutblocksstarting/*andending*/JavaDoccommentsstartingwith/**andending*/

Whenwewantsmallcommentswecanaddthemafterstatementsandanythingafter//willbetreatedasacomment.Thesecommentsareusefulforquickexplanations.assertTrue(truthy);//commenttillendofline

Tocommentoutablockofcode,orhavealargerdescriptivetextweuseablockcommentwhichstartswith/*andendswith*/.Thesecommentscanspanlinesandstartandendinthemiddleoflines.

Page 67: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

/*

Thiscodechecksthatthetrue

valuethattruthywassetto

istrue.Prettyobviousreally.

*/

booleantruthy=true;

assertTrue(truthy);

BlockCommentsdonotnestYoucannotnestblockcomments,i.e.ifyoutryandcommentoutablockoftextwhichalreadycontainsablockcommentthenyouwillgetasyntaxerror.

Youcancommentoutablockcommentbyputting//atthestartofeachline.

JavaDoccommentshelpwithcommunicationbecauseyoucanusetheIDEtoshowyoutheJavaDoconmethodsandclassesi.e.ifIpressctrl+q(ctrl+jonMac)ontheaddTwoNumbersmethodcallinaJavaDocCommentIwillseetheJavaDocdocumentationfromthecomment.

Thisisaveryusefulcommentingstyletouseonabstractionlayerclassesandmethods.e.g.@Test

publicvoidaJavaDocComment(){

assertTrue(addTwoNumbers(4,3)==7);

}

/**

*Addtwointegersandreturnanint.

*

*Thereisariskofoverflowsincetwobig

*integerswouldmaxoutthereturnint.

*

*@paramaisthefirstnumbertoadd

*@parambisthesecondnumbertoadd

*@returna+basanint

*/

publicintaddTwoNumbers(inta,intb){

returna+b;

}

Wewon’tcoverJavaDocindetailinthisbook,butyoucanreadthereferencestofindoutmore.

StatementAJavastatementisthesmallestchunkofexecutableJavacode.WeendaJavastatementwith;e.g.assertEquals(4,2+2);

Javastatementscanspanlines.Thisisusefultomakeyourcodemorereadableandlineupargumentsonmethodcalls.e.g.

Page 68: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals("2+2always=4",

4,

2+2);

PackagesJavaallowsustogroupourClassesintopackages.Eachclasshastobeuniquelynamedwithinapackage.Wecanhavemultipleclasseswiththesamename,providedtheyareallindifferentpackages.packagecom.javafortesters.chap007basicsofjavarevisited.examples;

Toaddaclasstoapackageyouwriteapackagedeclarationstatementliketheabove,veryoftenthefirstlineintheclass,andcertainlybeforethecodethatdeclarestheclass.

JavaClassesAllofourJavacodewillinvolveclassesinsomeform.Eitherusingclassesthatothershavewritten,writingabstractionlayersasclasses,orcreatingJUnittests(whichareactuallymethodsinaclassannotatedwith@Test).publicclassAnEmptyClass{

}

Thisexampleclassshowsmanyfeaturesofaclass:packagecom.javafortesters.chap007basicsofjavarevisited.examples;

publicclassClassExample{

publicstaticfinalStringCONSTANT="aconstantstring";

publicstaticStringaClassField="aclassfield";

protectedstaticStringproField="aclassfield";

publicStringpubField="apublicfield";

privateStringprivField="aprivatefield";

privateStringname;

publicClassExample(Stringname){

this.name=name;

}

publicStringgetName(){

returnthis.name;

}

publicvoidsetName(Stringname){

this.name=name;

}

}

Thefirstlineoftheclasshasthepackagedeclaration.Thisdoesn’tneedtobethefirstline,itjustneedstocomebeforetheclassdeclaration.packagecom.javafortesters.chap007basicsofjavarevisited.examples;

Here,theclassisdeclaredwiththenameClassExampleanddeclaredaspublic.publicclassClassExample{

Page 69: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Becausetheclassispublic,itcanbeusedbyanotherclass,solongastheyimportit,oriftheyareinthesamepackage.IfIdidn’taddthepublicthentheclasswouldhavepackagescopeandonlybeavailabletootherclassesinthesamepackage.

StaticmethodsandfieldsAclasscanexposestaticmethodsandfields,whichallowyoutousethemwithoutinstantiatinganewinstanceobjectoftheclass.

YouhaveseenthiswhenusinganyoftheassertsinJUnit,theseareallstaticmethodsontheAssertclass.

InstantiatingClassesMostclassesneedtobeinstantiatedbeforetheycanbeused.ClassExampleinstance=newClassExample("bob");

Whenweinstantiateaclass,weusethenewkeyword,andcalloneoftheclass’sconstructors.

FieldandMethodScopeThescopeofafieldormethodisdefinedbypublic,protected,privateorpackage-private(nomodifier).

publicaccessibletoanyclassthatimportstheparentclassprotectedaccessibletoanyclassinthesamepackage,oranysubclassprivateaccessibletomethodsintheclasspackage-private-whennomodifierisusedthenthefieldormethodisaccessibletotheclassandanyclassinthesamepackage(thisisthedefault)

Additionalfieldandmethodmodifiers:

static-thefieldormethodexistsattheclasslevel,nottheinstancelevel,soissharedbyallinstancesandcanbeaccessedwithoutneedingtohaveaninstantiatedclassvariable.

Fields&VariablesFieldsarevariablesthatareaccessiblebyanymethodintheclassand,dependingonthescope,possiblytootherclasses.

Fieldtypicallyreferstovariablesdeclaredattheclasslevelandlocalvariablereferstovariablescreatedinamethod.

Additionalfieldmodifiersare:

final-oncethefieldhasavalueitcannotbechanged

Examplesofcombinationsandnuancesofscopeandmodifiersareexplainedbelow.

Naming

Page 70: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Afieldorvariablenamemustbeginwithaletter,whichisanyUnicodecharacterthatrepresentsaletter:toplayitsafe,andkeepcodereadable,wenormallystickto‘A’to‘Z’,‘a’to‘z’,althoughsomepeoplealsousethesymbols‘_’and‘$’(andeven£).

Afterthisfirstletter,thevariablenamecancontainanyoftheletters,ordigits.

CaseissignificantsoaMountisnotthesameasAmount.

Namestendtousecamelcaseandstartwithalowercaseletter.Constantstendtobealluppercase,with‘_’todelimitwords.

Avariablenamecanbeverylong,andyoucanuseawiderangeofcharactersinthename,butdotryandkeepthenamesreadable,andcapableofbeingreadaloud.@Test

publicvoidvariableNaming(){

String$aString="bob";

float£owed=10F;

intaMount=4;

longAmount=5;

StringA0123456789bCd$f="ugh";

assertEquals(4,aMount);

assertEquals(5,Amount);

assertEquals(10.0F,£owed,0);

assertEquals("bob",$aString);

assertEquals("ugh",A0123456789bCd$f);

}

PublicStaticFinal

publicstaticfinalfieldsareoftenknownasconstants,becauseonceassignedavalue,thevaluecannotbechanged.Thismakesthemusefulforexposingconstantvaluestootherclasses.publicstaticfinalStringCONSTANT="aconstantstring";

Typicallyyouwillseethevalueassignmentinthedeclarationasaconstant,asshownintheexampleabove,butitcouldalsobesetfromamethodcall,whichallowsyoutoreadconstantsfromfilesorpropertyvalues.

FinalNotethatfinaldoesnothavetohavepublicstaticscope.Anyofthescopingkeywordscanbeusedwithfinale.g.privatefinal

finalsimplymeansthatonceassignedavalue,itcan’tbechanged.ButitissooftenusedaspublicstaticfinalthatIincludeditinthissection.

PublicStaticpublicstaticStringaClassField="aclassfield";

ApublicstaticfieldisavailabletoanyclasswhichimportstheClassExampleclass.Andbecauseitisstatic,thefieldisavailablewithouthavingtoinstantiatetheclassintoaninstancevariable.staticfieldsareoftenknownasclassfieldse.g.

Page 71: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals(ClassExample.aClassField,

"aclassfield");

Youcanaccessclassfieldsfrominstanceobjects,buttheIDEmaywarnyou,orthefieldmaynotshowupincodecompletion.instance.aClassField="changed";

Unlikeconstantsthesefieldscanhavetheirvalueschangedbyotherclasses.Thiscanmakeyourcodeerrorprone-sobecarefulifyoudothis.

PublicpublicStringpubField="apublicfield";

Apublicfieldisaccessibletoallclasseswhichinstantiateanewinstancevariableoftheclass.assertEquals(instance.pubField,"apublicfield");

instance.pubField="amendedpublicfield";

assertEquals(instance.pubField,"amendedpublicfield");

Becausethesefieldscanbechangedbyotherclasses,youshouldconsiderifyouneedtomakethempublic,orifitshouldbeaprivatefield,andtheclassshouldoffersetterandgettermethodsinstead.

Protected

protectedmeansthatthefieldcanbeusedbyanyclassinthesamepackage,oranyclasswhichextendsthisclass.(Youwilllearnaboutextendslaterinthisbook)

Package-Private(default)

Whennomodifierisaddedtothefielddefinitionthenitisonlyaccessiblebymethodsintheclassoranyclassesinthesamepackage.

ImportingClassesAclasscanuseanyclassesinthesamepackage.Andanyclassdeclaredaspublicinotherpackages,whenweimportthatclass.

Wecanimportspecificclassesbyspecifyingtheclassnameinthetheimportstatement.importcom.javafortesters.domainentities.User;

Wecanalsousewildcardtoimportalltheclassesfromapackagee.g.importcom.javafortesters.chap001basicsofjava.examples.classes.*;

Notethatyoudon’thavetoimport.Youcanuseclasseswithoutimportingthem,byprefixingtheclassnamewiththepackagepath.Butyourcodequicklybecomesverboseandhardertomaintain.e.g.@org.junit.Test

publicvoidnonImportTest(){

org.junit.Assert.assertEquals(3,2+1);

}

Thiscanbehelpfulifyouaretryingtousetwoclasseswiththesamenameinyourcode.Iftheyareindifferentpackagesthenprefixtheclass’snamewiththefullpackagewhen

Page 72: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

youdeclareandinitialiseit.

StaticImportsYoucanimportspecificmethodsandfields,aswellasclasses.YouhavealreadyseenthiswiththeJUnitimports.e.g.importorg.junit.Assert;

importstaticorg.junit.Assert.assertEquals;

Aboveyoucanseetwoimports.AstaticimportfortheassertEqualsmethodandanimportfortheAssertclass.

WhenIusethestaticimportofassertEquals,IcanusetheassertEqualsmethoddirectlyinmycodee.g.assertEquals(6,3+3);

WhenIdonotusethestaticimport,Ihavetoaccessthestaticmethodfromtheclassitselfe.g.Assert.assertEquals(5,3+2);

DataTypesEveryvariableinJavamusthaveatypedeclared,eitherasaprimitive,oranobjectclass.

BooleanTypeAbooleanhastwoconstantstrueandfalse.

ThereisalsoanassociatedBooleanobject.@Test

publicvoidBooleanType(){

booleantruthy=true;

booleanfalsey=false;

assertTrue(truthy);

assertFalse(falsey);

truthy=Boolean.TRUE;

falsey=Boolean.FALSE;

assertTrue(truthy);

assertFalse(falsey);

}

IntegerTypes

byterange:-128to127shortrange:-32768to32767intrange:-2147483648to2147483647longrange:-9223372036854775808to9223372036854775807

Page 73: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

EachprimitivehasanassociatedClasse.g.Byte,Short,Integer,Long.Thesecanbeusedforconversionsandhaveothersupportmethods.TheyalsohavetheMIN_VALUEandMAX_VALUEconstantsforeachprimitive.

VariousJavasyntaxexistsforrepresentingliteralsasspecificprimitives:

representanintegerliteralasalongbyaddingthesuffixLrepresentahexvaluewiththeprefix0x(zerox)representanoctalvaluewiththeprefix0(zero)representabinaryvaluewiththeprefix0b(zerob)(Java1.7)makenumbersreadablebyadding_e.g.9_000_000(underscore)(Java1.7)

Examplesoftheabove,canbeseenbelow:@Test

publicvoidIntegerTypes(){

byteaByteHas1Byte;

shortaShortHas2Bytes;

intanIntHas4Bytes;

longaLongHas8Bytes;

System.out.println(

"*`byte`range:"+

Byte.MIN_VALUE+"to"+

Byte.MAX_VALUE);

System.out.println("*`short`range:"+

Short.MIN_VALUE+"to"+

Short.MAX_VALUE);

System.out.println("*`int`range:"+

Integer.MIN_VALUE+"to"+

Integer.MAX_VALUE);

System.out.println("*`long`range:"+

Long.MIN_VALUE+"to"+

Long.MAX_VALUE);

aLongHas8Bytes=0L;//addsuffixLforlong

assertEquals(0,aLongHas8Bytes);

aByteHas1Byte=0xA;//addprefix0xforHex

assertEquals(10,aByteHas1Byte);

anIntHas4Bytes=010;//add'zero'prefixforOctal

assertEquals(8,anIntHas4Bytes);

aByteHas1Byte=0b0010;//Java1.7added0b'zerob'forbinary

assertEquals(aByteHas1Byte,2);

//Java1.7allowsunderscoresforreadability

aLongHas8Bytes=9_000_000_000L;//9000million

assertEquals(9000000000L,aLongHas8Bytes);

}

Floating-pointTypes

Page 74: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Floatingpointtypeshavetwodifferentprecisions,whichcontrolsthesizeofvaluetheycanstore:

float:singleprecision32bitnumberdouble:doubleprecision64bitnumber

Ranges:

floatrange:1.4E-45to3.4028235E38doublerange:4.9E-324to1.7976931348623157E308

Suffixes:

representafloatwiththesuffixFrepresentadoublewiththesuffixD,orifyouuseadecimalpointe.g.20.0thenthennumberwithdefaulttoadouble

Theofficialdocumentsrecommendtheusethejava.math.BigDecimalclassifyouwantprecisevaluese.g.currency.BigDecimalhelpsavoidroundingerrors.

TheseprimitivetypesalsohaveanassociatedClasse.g.FloatandDouble@Test

publicvoidFloatingPointType(){

floatsinglePrecision32bit;

doubledoublePrecision64bit;

System.out.println("*`float`range:"+

Float.MIN_VALUE+"to"+

Float.MAX_VALUE);

System.out.println("*`double`range:"+

Double.MIN_VALUE+"to"+

Double.MAX_VALUE);

singlePrecision32bit=10.0F;//suffixFtogetafloat

assertEquals(10F,singlePrecision32bit,0);

doublePrecision64bit=20.0;//defaulttodouble

assertEquals(20D,doublePrecision64bit,0);

}

CharacterTypeThechardatatypeisusedtorepresentanindividualcharactere.g.'a',itisa16bitUnicodecharacter.

AcharisnotaString.

Youcanrepresentaunicodecharacteras\u0026i.e.\ufollowedbythe4characterhexvalueoftheUnicodecharacter.\u0026is&

Javaalsohassomespecialcharactersrepresentedbyescapesequencese.g.

\t-atabcharacter

Page 75: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

\b-backspace\n-anewline\r-acarriagereturn\'-asinglequote\"-adoublequote\\-abackslash

AllofthesespecialcharactersarealsoavailableforuseinString.

JavaalsohasanassociatedCharacterclasswithstaticmethodstohelpwhenworkingwithcharvariables.@Test

publicvoidCharacterType(){

charaChar='\u0026';

assertEquals(aChar,'&');

}

Operators

TraditionalJavahasthetraditionalarithmeticoperatorsthatyouwouldexpect:

+foraddition-forsubtraction*formultiplication/fordivision

AlloftheabovecanbeusedforIntegerandFloatingpointnumbers.AlthoughyoumaynotgettheresultyouexpectwithFloatingpointnumbers(duetorounding)-whichiswhyBigDecimalisoftenrecommended.

+canalsobeusedforStringconcatenation%forintegerremaindercalculations(i.e.modulus)e.g.9%2returns1

@Test

publicvoidtraditionalOperatorsExplored(){

assertEquals(4,2+2);

assertEquals(5L,10L-5L);

assertEquals(25.0F,12.5F*2F,0);

assertEquals(30.2D,120.8D/4D,0);

assertEquals("abcd","ab"+"cd");

assertEquals(1,9%2);

}

AssignmentOperatorsarealsousedforassignment,asyouhaveseenwhenyouinstantiateavariable.

=toassignthevaluetothevariable

Page 76: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thetraditionaloperatorscanalsobeusedduringassignment:

+=toincrementthevariablebyvaluee.g.+=2wouldaddtwo-=todecrementthevariablebyvaluee.g.-=2wouldsubtracttwo*=tomultiplythevariablebyvaluee.g.*=2wouldmultiplybytwo/=todividethevariablebyvaluee.g./=2woulddividebytwo%=tocalculateandassignthemodulusbyvaluee.g.%=3wouldassignthevariablemodulusthevalue

@Test

publicvoidassignmentOperatorsExplored(){

Stringab="ab";

assertEquals("ab",ab);

intnum=10;

assertEquals(10,num);

num+=2;

assertEquals("+=incrementsby",12,num);

num-=4;

assertEquals("-=decrementsby",8,num);

num*=2;

assertEquals("*=multipliesby",16,num);

num/=4;

assertEquals("*=multipliesby",4,num);

num%=3;

assertEquals("%=modulusof",1,num);

}

IncrementandDecrementYoucanincrementanddecrementavariableusing++and--e.g.++numwouldreturnnumincrementedby1

Youcanput++and--beforeorafterthevariable.

Putting++or--beforethevariablemeansthatyouwanttoamenditafterusingit.(prefix)Putting++or--afterthevariablemeansthatyouwanttouseitandthenincrementit.(postfix)

e.g.@Test

publicvoidincrementDecrementOperatorsExplored(){

intnum=10;

assertEquals(11,++num);

assertEquals(10,--num);

assertEquals(10,num++);

assertEquals(11,num);

assertEquals(11,num--);

Page 77: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals(10,num);

}

BooleanOperatorsJavahasarangeofoperatorswhich,comparetwooperandsto,returntrueorfalse.

==testforequality!=testforinequality>greaterthan<lessthan<=lessthanorequalto>=greaterthanorequalto

Youcanalsonegateabooleanwith!(knownaslogicalcomplement);@Test

publicvoidbooleanOperatorsExplored(){

assertTrue(4==4);

assertTrue(4!=5);

assertTrue(3<4);

assertTrue(5>4);

assertTrue(6>=6);

assertTrue(7>=6);

assertTrue(8<=8);

assertTrue(8<=9);

assertTrue(!false);

booleantruthy=true;

assertFalse(!truthy);

}

ConditionalOperatorsYoucancreatecomplexbooleanstatementsbyusing&&and||

&&alogicaland||alogicalor

e.g.@Test

publicvoidconditionalOperatorsExplored(){

assertTrue(true&&true);

assertTrue(true||false);

assertTrue(false||true);

assertFalse(false||false);

assertFalse(false&&true);

}

Notethattheselogicalconditionaloperatorsshortcut,sotheyonlyevaluatethesecondoperandifrequired.e.g.true||falsewouldonlyneedtocheckthefirsttruevalue,butfalse||truewouldhavetoevaluateboth.

Page 78: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

TernaryOperatorJavasupportsaternaryoperatorwhichperformsacheckonaconditionand:

iftrue,returnsthevalueofthefirstoperand,andiffalse,returnsthevalueofthesecondoperand.

condition?operand1:operand2;

Notethatyouonlyneedthe;ontheend,iftheternaryoperatorisontherightofastatement,ifitisevaluatedwithinastatementthenyoudon’taddthe;

e.g.@Test

publicvoidternaryOperatorsExplored(){

intx;

x=4>3?2:1;

assertEquals(2,x);

assertTrue(5>=4?true:false);

}

BitwiseOperatorsYoucanperformbinarybasedbitwiseoperationsonIntegerdatatypes.

&and|or^xor~bitwisetwo’scomplement(invertthebits)

@Test

publicvoidbitwiseOperatorsExplored(){

assertEquals(0b0001,

0b1001&0b0101);

assertEquals(0b1101,

0b1001|0b0101);

assertEquals(0b1100,

0b1001^0b0101);

intx=0b0001;

assertEquals("11111111111111111111111111111110",

Integer.toBinaryString(~x));

}

Thebitwiseoperatorscanalsobeusedduringanassignment.@Test

publicvoidbitwiseAssignmentOperatorsExplored(){

bytex=0b0001;

x&=0b1011;

assertEquals(0b0001,x);

Page 79: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

x|=0b1001;

assertEquals(0b1001,x);

x^=0b1110;

assertEquals(0b0111,x);

}

BitShiftOperatorsYoucanperformbinaryarithmeticandshiftoperationsonIntegerdatatypes.

<<shifttothelefte.g.<<3shift3totheleft>>signedshifttotheright>>>unsignedrightshift(shiftazerointoleftmostposition)

Theshiftoperatorscanalsobeusedonassignment.@Test

publicvoidbitwiseShiftOperatorsExplored(){

intx=56;

assertEquals(x*2,x<<1);

assertEquals(x*4,x<<2);

assertEquals(x*8,x<<3);

x<<=3;

assertEquals(56*8,x);

x=Integer.MAX_VALUE;

assertEquals(Integer.MAX_VALUE/2,x>>1);

assertEquals(Integer.MAX_VALUE/4,x>>2);

assertEquals(Integer.MAX_VALUE/8,x>>3);

x=Integer.MIN_VALUE;//-ve

assertEquals((Integer.MAX_VALUE/2)+1,x>>>1);

}

OperatorprecedenceTheoperatorprecedenceislistedontheJavadocumentationpage:

docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Whileitisworthunderstandingtheprecedenceorder,itisgenerallyeasiertoreadtheintentbehindacomplexstatementiftheorderofprecedenceismadeclearbyusingparenthesis,()sincenestedoperationsareexecutedfirst.

e.g.comparetheasserts:@Test

publicvoidoperatorPrecedence(){

assertEquals(8,4+2*6/3);

assertEquals(12,(((4+2)*6)/3));

}

Thereforetryanduseparenthesis,(),tocontroltheorderofprecedence,asitwillmakethecodeeasiertoreadandmaintain.

Page 80: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thebasicrulesforprecedenceare:

Theoperatorswithhighestprecedenceareevaluatedfirst.OperatorswithequalprecedenceareevaluatedinlefttorightorderAssignmentoperatorsareevaluatedrighttoleft

Inthetablebelow,operatorsarelistedinprecedenceorder,andwheremorethanoneoperatorisonthesamerow,theyareofequalprecedence.

Operatorx++x--++x--x+x-x~!*/%+-<<>>>>><><=>===!=&

^

|

&&

||

?:

=+=-=*=/=%=&=^=|=<<=>>=>>>=

StringsAStringisaclassinjava.langsoyoudon’tneedtoimportittouseit.

Stringsareimmutablesotheycan’tchange.Allcommandsthatlookliketheychangethevaluesofstrings,actuallyreturnanewStringwithalltheamendments.

StringConcatenationStringscanbeconcatenatedusingthe+operator.@Test

publicvoidstringsConcatenated(){

assertEquals("123456","12"+"34"+"56");

}

StringmethodsTheStringclassprovidesstaticmethodsthatcanbeusedwithoutinstantiatingaStringobjectvariable:

lengththenumberofcharactersinthestringcharAtreturnsthecharacterataspecificindexcontainsreturnstrueifasubstringiscontainedetc.

Page 81: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Test

publicvoidsomeStringMethods(){

StringaString="abcdef";

assertEquals(6,aString.length());

assertTrue(aString.compareToIgnoreCase("ABCDEF")==0);

assertTrue(aString.contains("bcde"));

assertTrue(aString.startsWith("abc"));

//stringindexingstartsat0

assertEquals('c',aString.charAt(2));

assertEquals("ef",aString.substring(4));

}

Formethodswhichuseindexese.g.substringorcharAttheindexstartsat0sothefirstcharacterisatindex0

Stringswillbeexploredinmoredetaillaterinthebook.

SummaryThiswasintendedtobeafairlyheavychapter,butIintersperseditwithalotofcodeexamples.

Makesureyouworkthroughtheexamplesandunderstandthem.

Recreatetheminyourowncodeandexperimentwiththem,ifyouwanttodeepenyourknowledge.

Don’tworryifyoudidn’tunderstanditall.Wewillcoversomeofthetopicsinthischapterinmoredetaillater,sincethisisthefirsttimeyouhaveseensomeofthetopicshere.

ReferencesandRecommendedReading

JavaDocCommentsDocumentationoracle.com/technetwork/java/javase/documentation/index-137868.html

WikipediaJavaDocen.wikipedia.org/wiki/Javadoc

MethodScope:public,private,protected,packagedocs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

JavaPrimitiveDataTypesdocs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Unicodecharactersen.wikipedia.org/wiki/List_of_Unicode_characters

Javacharactersdocs.oracle.com/javase/tutorial/java/data/characters.html

Two’sComplementen.wikipedia.org/wiki/Two%27s_complement

OperatorsandPrecedencedocs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Page 82: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterEight-SelectionsandDecisions

ChapterSummaryInthischapteryouwilllearn,howtouseselectionsandconditionsinyourcode:

Howtousetheternaryoperatorif/elsestatementsTheswitchstatement

WhenIwaslearningtoprogram,alongtimeago.Iwastaughtthatprogrammingwasmadeupof:

SequenceSelectionIteration

Sequence,iswhatwe’vebeendoing:onestatement,followinganotherstatement.

Selection,ismakingdecisions,andchoosingtodoonething,oranother,dependingonaparticularcondition.

Iteration,wherewerepeatactionsuntilwehavedonewhatweneeded.

ThischapterisgoingtolookatSelection.OrConditionalStatements

TernaryOperatorsYouhavealreadyseentheTernaryoperator.x=4>3?2:1;

xissetto2,if4isgreaterthan3,otherwisexissetto1

Intheternaryoperator,theconditionisevaluatedand:

iftheconditionistrue,thevalueofthefirstoperandisreturned,iftheconditionisfalsethevalueofthesecondoperandisreturned.

e.g.@Test

publicvoidmoreTernary(){

Stringurl="www.eviltester.com";

url=url.startsWith("http")?url:addHttp(url);

assertTrue(url.startsWith("http://"));

assertEquals("http://www.eviltester.com",url);

}

Page 83: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

privateStringaddHttp(Stringurl){

return"http://"+url;

}

Peopleoftenusethisforsimple,in-line,decisionmakingorquickchecks.Ipersonallyfindithardertoread,sowhenIcodeIgenerallywriteifstatements.

Exercise:CatorCats?TernaryOperatorWritean@Testmethodthatusesaternaryoperatortoreturn"cat"ifanumberOfCatsequals1.Andreturn"cats"ifthenumberOfCatsisnot1

Rewriteyourcodesothattheternaryoperatorisusedinamethodwhichreturns"cat"or"cats"dependingonthenumberOfCatsparameteritiscalledwith.e.g.

assertEquals("2==cats","cats",catOrCats(2));

ifstatementTheifstatementtakestheforms:

if(condition)statement;

or

if(condition){statement1;statement2;}

Whenonlyonestatementisusedintheifthenyoudon’tneedtoaddthe{}blockdelimiters.Whenmultiplestatementsareusedthenyouneedtoaddthestatementsinthecodeblockdelimitedwith{}.

Thestatementsareonlyexecutedwhentheconditionevaluatestotrue

CodingStyle

Itendtoadd{}regardlessofthenumberofstatements.

Ithinkitmakesthecodeeasiertoread.AndI’mlesslikelytoforgettoaddtheblockdelimitersinlater,whenIaddmorestatementstotheifclause.

Butthesearepersonalstyleissuesandarelikelytobedictatedbyyourpersonalstyle,orthestyleofcodingenforcedinyourworkplace.

Example:@Test

publicvoidifAddHttp(){

Stringurl="www.seleniumsimplified.com";

if(!url.startsWith("http")){

url=addHttp(url);

}

Page 84: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertTrue(url.startsWith("http://"));

assertEquals("http://www.seleniumsimplified.com",url);

}

Exercise:AssertTrueiftrueGivenavariable:booleantruthy=true;

Writean@Testmethodthatusesanifstatementwithoutasetofbraces{}toassertTrueontruthy,iftruthyistrue.

Writean@Testmethodthatusesanifstatementthatwhentruthyistrue,assertsTrueontruthy,andassertsFalseon!truthy

elsestatementSincethestatementblockaftertheifonlyexecuteswhentheconditionevaluatestotrue,wealsoneedtheabilitytoexecutecodeiftheconditionevaluatestofalse.

Andthisiswheretheelsekeywordcomesin.

if(condition)statement;else

statement;

or

if(condition){statement1;statement2;}else{

statement3;statement4;}

Againyoucanseethatwhenthereisnodelimitedblockthentheelseexecutesasinglestatement,butwhentheelsehasadelimitedblockthenallthestatementsinthatblockwillexecute.

Example:@Test

publicvoidifElseAddHttp(){

Stringurl="www.seleniumsimplified.com";

if(url.startsWith("http")){

//donothingtheurlisfine

}else{

url=addHttp(url);

}

assertTrue(url.startsWith("http://"));

assertEquals("http://www.seleniumsimplified.com",url);

}

Page 85: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

CompoundStatement

Asetofstatementsinablockisoftencalleda‘compoundstatement’.

Andasinglestatementreferredtoasa‘simple’statement.

Exercise:AssertTrueelseAssertFalseGivenavariable:booleantruthy=true;

Writean@Testmethodthatusesanifstatementwithoutasetofbraces{}toassertTrueontruthy,iftruthyistrue,otherwiseitusesassertFalseontruthy.

Writean@Testmethodthatusesanifstatementthatiftruthyistrue,assertsTrueontruthy,andassertsFalseon!truthy,otherwiseitusesassertFalseontruthy

Makesureyourunthemethodswithtruthy=false,soyouseetheeffectwithbothvalues.

NestedifelseBecauseifandelsearestatementstheycanbenestedintheifandelsestatementblocklikeanyotherstatement.

e.g.@Test

publicvoidifElseNestedAddHttp(){

Stringurl="seleniumsimplified.com";

if(url.startsWith("http")){

//donothingtheurlisfine

}else{

if(!url.startsWith("www")){

url="www."+url;

}

url=addHttp(url);

}

assertTrue(url.startsWith("http://"));

assertEquals("http://www.seleniumsimplified.com",url);

}

Codeformattingbecomesveryimportantwhenusingnestedifandelse:

indentyourcodelineupstatementslineupbraces{}

AlsonotethatthecodingstyleIadopthastheopeningbrace{attheendoftheiforelsestatementonthesameline,otherpeopleprefertoputtheopeningbraceundertheiforelsebutinlinewithit.

e.g.if(url.startsWith("http"))

{

//donothingtheurlisfine

}else

Page 86: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

{

if(!url.startsWith("www"))

{

url="www."+url;

}

url=addHttp(url);

}

Ipersonallythinkthattheabovestyletakesuptoomuchspace,andthattheopeningbrace{addsnoinformation,buttheclosingbrace}doesaddinformationaboutscopewhenIreadthecode.

Experimentanddecideonastylethatsuitsyou.Lookatthecodeinuseinyourorganizationandadopttheinhousestyle.

Exercise:NestedIfElseHorrorWritethefollowingpseudocodeasJavainan@Testmethod:

Givenavariabletruthywhichissettotrueandavariablefalseywhichissettofalse:

IftruthythenIf!falseythen

Iftruthyand!falseythenIffalseyortruthythen….asserttruthyistrue,and….assertfalseyisfalse

Elseasserttruthyistrueassertfalseyistrue

ElseIf!truthythen

iffalseythenassertfalseyistrueasserttruthyisfalse

elseassertfalseyisfalseasserttruthyisfalse

Tryitwithdifferentcombinationsofvaluesontruthyandfalseytomakesureyouhavecoveredallpaths.

switchstatementWhenyourcodehasalotofifelsestatementsthenitmightbeappropriatetouseaswitchstatementinstead.

Theswitchstatementallowsyoutohaveanumberofcasesforasingleconditioncheck.@Test

publicvoidswitchExample(){

assertEquals("M",likelyGenderIs("sir"));

assertEquals("M",likelyGenderIs("mr"));

assertEquals("M",likelyGenderIs("master"));

assertEquals("F",likelyGenderIs("miss"));

assertEquals("F",likelyGenderIs("mrs"));

Page 87: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals("F",likelyGenderIs("ms"));

assertEquals("F",likelyGenderIs("lady"));

assertEquals("F",likelyGenderIs("madam"));

}

publicStringlikelyGenderIs(Stringtitle){

StringlikelyGender;

switch(title.toLowerCase()){

case"sir":

likelyGender="M";

break;

case"mr":

likelyGender="M";

break;

case"master":

likelyGender="M";

break;

default:

likelyGender="F";

break;

}

returnlikelyGender;

}

Theswitchstatementtakesanexpressiontocheck.Theswitchblockhasaseriesofcasestatements.Thebreakstatementisimportanttoendeachcase.Thelastcaseshouldbeadefaultwhichisexecutedifnoothercasematches.defaultdoesnotrequireabreak,butIusuallyaddone

Note:youneedtouseJava1.7oraboveifyouwanttohavestringliteralsinyourcasestatements.

BeCareful.Ifyouforgetthebreakthenthecasewillfallthroughtothenextone.e.g.

Icouldhavewrittentheswitchlikethis:switch(title.toLowerCase()){

case"sir":

case"mr":

case"master":

likelyGender="M";

break;

default:

likelyGender="F";

break;

}

Whenwrittendeliberately,thefallthroughcanmakecodeeasytoread.Bewarehoweverthatitisasimplemistaketomakeandforgetthebreakstatementanditcaneasilyintroducebugsintoyourcode.

Page 88: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:SwitchonShortCodeCreateamethodwhichusesaswitchstatementtoreturnaStringdependingontheshortCodepassedinasaparametertothemethod:

given“UK”return“UnitedKingdom”given“US”return“UnitedStates”given“USA”return“UnitedStates”given“FR”return“France”given“SE”return“Sweden”givenanyothervalue,return“RestOfWorld”

Forbonuspoints,maketheshortcodecaseinsensitivei.e.“uK”,“UK”,“Uk”,“uk”shouldallreturn“UnitedKingdom”

Exercise:SwitchonintCreateamethodwhichusesaswitchstatementtoreturnaStringrepresentingtheintpassedinasaparametertothemethod:

given1return"One"given2return"Two"given3return"Three"given4return"Four"givenaninteger>4,return"Toobig"givenaninteger<1,return"Toosmall"

Asanexperiment,alsowritethemethodsuchthateverycaseintheswitchisimplementedasareturnsonovariablesorbreakstatementsareused.

SummaryYouhaveseenthatyoucanwritecodewithoutallthe{}andbreakstatements.ButIfindthataddingthemallthetime,makesmycodemorereadableandmaintainable.

Itendnottouseternaryoperatorsverymuch,butsomepeopleusethemallthetime.Soitisimportanttobeabletoreadthem.

Eventhoughthiswasashortchapter.Youdoneedtomasterconditionalflowsinyourcodeandmakedecisionsaboutwhichconditionaloperatoryouuse.

ReferencesandRecommendedReading

if-then-elseJavatutorialdocs.oracle.com/javase/tutorial/java/nutsandbolts/if.html

switchJavatutorialdocs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

Page 89: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterNine-ArraysandForLoopIteration

ChapterSummaryInthischapteryouwilllearn,asimplewayofcollectingthings,accessingthem,andloopingoverthemusing:

Arrays-afixedsizecollectionof‘things’Arrayindexing-accessindividualitemsinanarrayForEachLoop-iterateovereachindividualiteminthearrayForLoop-iteratethroughaloopusingindexesArraysofArrays-ArrayscancontainotherarraysRaggedArrays-Anarrayofarrayswithdifferentsizesjava.utils.Arrays-AutilityclassforworkingwithArrayse.g.fill,sort,copy

Inpreviouschaptersyouhaveseenhowtocreateindividualvariablestostoreobjectsandstrings.

IfyouwantedtocreateacollectionofDomainObjectsatthemoment,thenyouwouldhavetocreateanindividualvariableforeachone:e.g.user1,user2,user3,etc.

Ideally,wewantsomesortofobjectthatcollectsallthesetogetherforusandallowsustoaccesseachitemindividually.Wealsowanttoloopthroughthemtoprocesseachindifferentways.

Arrays,provideuswithasimplewayofdoingexactlythis.

ArraysArraysarethefirstcollectiondatatypewearegoingtolearn.

Anarrayrepresentsacollectionofitems,allofthesametype.

Arraysarefixedsize.Infuturechapterswewilllearnaboutcollectionsthatcanadjusttheirsizedynamicallyasweaddmoreitems.But,becausearraysareafixedsize,itmakesthemsimpletounderstand.

Asaquickexample:@Test

publicvoidsimpleArrayExample(){

String[]numbers0123={"zero","one","two","three"};

for(StringnumberText:numbers0123){

System.out.println(numberText);

}

assertEquals("zero",numbers0123[0]);

assertEquals("three",numbers0123[3]);

}

Theabovecode:

Page 90: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

createsanarraycallednumbers0123whichwillholdStringobjectscreatesthearraywithfourstrings"zero","one","two",and"three"iteratesoverthearrayprintingouteachstringinthearraysotheconsolewoulddisplay

zero

one

two

three

assertsthatthefirstvalueinthearrayequals"zero"assertsthatthelastvalueinthearrayequals"three"

Therestofthischapterwillexplainarraysinmoredetailandyouwillwriteyourowncodeusingarrays.

CreateanArrayThereareanumberofwaystocreateanewarray:

DeclareandcreateanarrayoffixedsizeDeclareandcreatearraywithactualvaluesDeclareanemptyarrayDeclareanarrayforlaterinitialization

DeclareandCreateanArrayofFixedSizeYoucandeclareanarrayofafixedsize:int[]integers=newint[10];

int[]moreInts=newint[10];

intevenMore[]=newint[10];

Youcanseethetypedeclaration(int),whichmeansthatthisarraycanonlystoreintvalues.Youcanalsoseethatthe[]canbebeforeorafterthevariablename.

Iprefertoputthe[]afterthetypedeclaration,asinthefirstintexampleabove.Ithinkitisfastertoreadthedeclarationandseethatitisanarray.

Icreatethearraywiththecode:

newint[10]

Thiscreatesanintarrayofsize10,soitcanstore10intvalues.

Icancreateanddeclareanarrayofdifferenttypes,sothefollowingcodeshowsthecreationofaStringarrayofsize10,tohold10Stringvalues.Stringstrings[]=newString[10];

DeclareandCreateanArraywithActualValues

Youcanalsodeclareanarraywiththevaluesinthedeclaration:int[]ints1to10={1,2,3,4,5,6,7,8,9,10};

Page 91: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

DeclareanEmptyArray

Youcandeclareanarrayofzerolength,usingthesyntaxpresentedbelow:int[]zeroLength={};

int[]moreZeroLength=newint[0];

DeclareanArrayforLaterInitialization

Ifyouwantto,youcandeclareanarrayandinitializeitlater.Forexample,thiscodedeclaresanarraybutdoesnotinitializeit.int[]uninitializedArray;

Iprefertoinitializeitatdeclaration,orinitializeitasanemptyarray.

Ifyouwanttoallocateanewarraytoanexistingarrayvariablethenyoucanusethesyntaxyousawinthedeclarationi.e.uninitializedArray=newint[10];

Oryoucanalsousethefollowingsyntax,whichcreatesananonymousarrayandallocatesittoanexistingvariable:uninitializedArray=newint[]{100,200,300};

AccessitemsinanarrayYoucanaccesstheitemsinanarraybyusingthe[i]notation,whereiistheindexyouwanttoaccess.

Arraysareindexedstartingat0sothefirstiteminanarrayisat[0].String[]workdays={"Monday","Tuesday","Wednesday",

"Thursday","Friday"};

assertEquals("Monday",workdays[0]);

assertEquals("Friday",workdays[4]);

Exercise:CreateanArrayofUsersUsingtheUserdomainobjectthatyoucreatedpreviously.

Createanarraycontaining3Userobjects.

IteratethroughanarrayWecaniteratethroughanarraywithaforeachloopandaforloop.

Theiterationexamplesbelow,allusethefollowingworkdaysarray:String[]workdays={"Monday","Tuesday","Wednesday",

"Thursday","Friday"};

ForEachloop

Aforeachloop,iteratesthrougheachiteminthearray.for(variable:collection){

//dosomething

}

Page 92: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thevariableisautomaticallyassignedthenextitemfromthecollection,anditeratesovereachiteminthearrayautomatically.

e.g.Stringdays="";

for(Stringworkday:workdays){

days=days+"|"+workday;

}

assertEquals("|Monday|Tuesday|Wednesday|Thursday|Friday",days);

for-createaforloopwithavariabledeclaration:arrayinthiscasethevariableisaStringcalledworkdaythecollectionisthearrayworkdays

thecodeiteratesthroughthearray,andeachiteminthearrayisassignedtothevariableworkdaysothefirsttimethroughtheloopthevariableworkdayisassignedthe[0]indexedvaluefromthearrayworkdayswhichis"Monday"thesecondtimethroughtheloopthevariableworkdayisassignedthe[1]indexedvaluefromthearrayworkdayswhichis"Tuesday",etc.theloopiteratesovereveryiteminthearraytheloopstopswhentherearenomoreitemsinthearraytoiterateover

Thisloopingconstructmeansthatwecaniterateovereveryiteminthearrayandnotmissany.Therebyavoidingtheoffbyoneerrorsthattraditionalboundaryvalueanalysisissofondoftryingtodetect.

Exercise:IterateovertheArrayofUsersUsingyourarrayofthreeUserobjectscreatedinthepreviousexercise.

IterateoverthearrayandSystem.out.printlnthenameofeachUser.

Forloop

Theforloopgivesusmorecontroloverthelooping.Wesetuptheinitialvariablewewanttouseforlooping,thenhaveaconditionwhichdecidesifweendtheforloop,thenwehaveastatementwhichsetsupthenextiterationoftheloop.for(variable;loop_condition;iterator){

//dosomething

}

e.g.thetraditionaluseofaforloopStringdays="";

for(inti=0;i<5;i++){

days=days+"|"+workdays[i];

}

assertEquals("|Monday|Tuesday|Wednesday|Thursday|Friday",days);

Page 93: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

forcreatesaforloopinti=0declaresanindexvariablewithaninitialvalueof0i<5theloopwillcontinuewhiletheloopconditionismet,inthiscasewhilewearestillaccessinganiteminthearray-thereare5itemsinthearray.Rememberarrayindexesstartat0sothelastitemis4.Index5wouldbeoutofbounds,soweuse<5.i++incrementthevalueoftheindex

Themoregenericexplanationofaforloopisactually:

for(initializestatementexecutedonce;loopcondition;executedaftereachloop){//dosomething}

SoIcouldhavewrittentheloop:inti=0;

for(;i<5;i++){

days=days+"|"+workdays[i];

}

Wherethevariableisinitializedoutsidetheloopandmyinitializestatementisempty.

Also:inti=0;

for(;i<5;){

days=days+"|"+workdays[i];

i++;

}

Andeven:inti=0;

for(;;){

days=days+"|"+workdays[i];

i++;

if(i>=5)break;

}

IntheabovecodeI’musingthebreakstatementwhichwesawintheswitchsection,tobreakoutoftheloop.

breakbreakisagenerickeywordtoendcontrolstatementexecution.breakcanexitanif,switch,forandlateriterationconstructswhile,do…while

Generally,keepingtothetraditionalexampleshownatthestartofthissectionmakesyourcodemorereadableandmaintainable.e.g.for(inti=0;i<5;i++){

days=days+"|"+workdays[i];

}

Youcanseefromeachofthevariantsthatevenwhenoneofthestatementsinthefor(...)aremissing,youstillneedtohavethe;inplace.

Page 94: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Usingfortoiteratethroughanarray,canleaveyouopentooffbyoneerrors,sobecareful.Butitdoesmeanthatyouhaveanindexcounteasilyavailabletouseintheloop.

e.g.inthefollowingexampleIaddtheloopindextotheoutputString@Test

publicvoidforLoopUsingIndexFixedCondition(){

Stringdays="";

for(inti=0;i<5;i++){

days=days+"|"+i+"-"+workdays[i];

}

assertEquals(

"|0-Monday|1-Tuesday|2-Wednesday|3-Thursday|4-Friday",

days);

}

Indexinaforeachloop

Ifyouwantanindexinsideaforeachloopthenyoucandoiteasilyenoughbycreatingavariableoutsidetheloop,andincrementingthevariablevaluewithintheloop.e.g.inthefollowingexampleIusedayindexastheindexvariable:intdayindex=0;

for(Stringworkday:workdays){

days=days+"|"+workday;

System.out.println("found"+workday+

"atposition"+dayindex);

dayindex++;

}

Whichwouldoutput:1foundMondayatposition0

2foundTuesdayatposition1

3foundWednesdayatposition2

4foundThursdayatposition3

5foundFridayatposition4

Exercise:Createanarrayof100usersCreateanarraywhichcanhold100Userobjects.UseaforlooptofillthearraywithUserobjectshavingthefollowingusername,passwordcombinations:

user1,password1user2,password2etc.

Findawaytocheckthearraywascreated.

Forbonuspoints,writesomecodetoassertthatthearraywasfilledproperly.

CalculateSizeofanArraywiththelengthmethod

length-returnsthelengthofthearray

Page 95: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Oncedeclared,youcanfindthesizeofanarrayusingthelengthmethod:assertEquals(5,workdays.length);

Thetypicaluseforthelengthmethodisinaforloopconditione.g.for(inti=0;i<workdays.length;i++){

days=days+"|"+workdays[i];

}

Sincethelengthofanarrayisalwaystheindexofthenextitemtoaddinthearray,wemakesurethatweuse<array.lengthintheloopcondition.

UsefulmethodsintheArraysclassJavaprovidesanArraysclassinjava.utils.

InordertouseArrays,youneedtoimportit.importjava.util.Arrays;

TheArraysclassprovidesanumberofusefulstaticmethods.

Wewillcoverasubsetofthemethodshere.Youcanseethefullrangeofmethodsintheofficialdocumentation.

copyOf-createacopyofanarray,andresizeifdesiredcopyOfRange-createacopyofpartofthearrayfill-fillthearray,orpartofthearraywithasinglevaluesort-sortthearray

Thesectionsbelowrefertotheworkdaysarray:String[]workdays={"Monday","Tuesday","Wednesday",

"Thursday","Friday"};

UsecopyOftocopyandresizeanArrayString[]weekDays;

weekDays=Arrays.copyOf(workdays,7);

UsingthestaticmethodcopyOfonArraywecancreateacopyofanarray,andoptionallyresizeit.

ThecopyOfmethodtakestwoarguments:

Arrays.copyOf(arrayToCopy,length);

Thisistypicallyusedtocreateacopyandincreasethesize.Whenweincreasethesize,thevaluesinthearray,whichwerenotintheoriginalarray,aresettothedefaultvalueforthatdatatypee.g.0forintegerandnullforString.

Inourexampleifwecreateacopyofworkdaysandresizeitfrom5to7thenthelasttwoindexeswillcontainnull.assertEquals(null,weekDays[5]);

assertEquals(null,weekDays[6]);

Thereforeweshouldsetthevaluesonthenewarrayifwewanttocontrolthecontents.

Page 96: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

weekDays[5]="Saturday";

weekDays[6]="Sunday";

WecanalsousecopyOftotruncatethearrayandmakeitshorter:String[]weekDays;

weekDays=Arrays.copyOf(workdays,3);

assertEquals(3,weekDays.length);

assertEquals("Monday",weekDays[0]);

assertEquals("Tuesday",weekDays[1]);

assertEquals("Wednesday",weekDays[2]);

UsecopyOfRangetocopyasubsetofanArray

ThecopyOfRangecopiesasubsetofanarrayintoanewarrayofthesizeofthesubset.

Assert.copyOfRange(arrayToCopy,startIndex,endItemCount);

ThestartIndexisthefirstiteminthearraythatyouwanttocopy.

TheendItemCountistheindex+1thatyouwanttocopy.

e.g.ifIwanttocopyitems3to5inclusive(“Wednesday”,“Thursday”,“Friday”),thenIwouldstartthecopyfrom2(theindexofthethirditem),andendthecopyon5(eventhoughtheindexofthefifthitemis4).

Examplecodemighthelp:String[]weekDays=Arrays.copyOfRange(workdays,2,5);

assertEquals(3,weekDays.length);

assertEquals("Wednesday",weekDays[0]);

assertEquals("Thursday",weekDays[1]);

assertEquals("Friday",weekDays[2]);

assertEquals(weekDays[0],workdays[2]);

assertEquals(weekDays[1],workdays[3]);

assertEquals(weekDays[2],workdays[4]);

WecanalsousecopyOfRangetoincreasethesizeofthearray,muchlikewedidwithcopyOf.TodothiswejustuseanendItemCountgreaterthanthearraysize.e.g.String[]weekDays=Arrays.copyOfRange(workdays,2,7);

assertEquals(5,weekDays.length);

assertEquals("Wednesday",weekDays[0]);

assertEquals("Thursday",weekDays[1]);

assertEquals("Friday",weekDays[2]);

assertEquals(null,weekDays[3]);

assertEquals(null,weekDays[4]);

UsefilltopopulateanArraywithdata

Arraysprovidesastaticmethodcalledfillwhichwecanusetofillanarraywithaspecificvalue,orfillarangeofindexesinthearray.

Tofilleveryiteminthearraywiththesamevaluewemakeasimplecalltofill

Arrays.fill(array,value);

e.g.tofillanarrayofintegerswiththevalueminusone(-1),Icandothefollowing:

Page 97: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

int[]minusOne=newint[30];

Arrays.fill(minusOne,-1);

Imightchoosetofillpartofanarray-possiblyifIhavejustdoneacopy,orcopyOfandresizedthearraylarger.

Arrays.fill(array,startIndex,endItemCount,value);

Again,thestartoftherangeistheindexnumberoftheitemwewanttostartat,andtheendoftherangeistheindex+1e.g.ifwewantedtostoponthe10thiteminanarray,whichisatindex‘9’wewouldusethevalue‘10’:int[]tenItems={0,0,0,0,0,1,1,1,1,1};

//fillcells5-9with'2'

Arrays.fill(tenItems,5,10,2);

//0-4areuntouched

assertEquals(0,tenItems[0]);

assertEquals(0,tenItems[4]);

//5-9nowequal2

assertEquals(2,tenItems[5]);

assertEquals(2,tenItems[6]);

assertEquals(2,tenItems[7]);

assertEquals(2,tenItems[8]);

assertEquals(2,tenItems[9]);

UsesorttoQuickSortanArray

JavaprovidesanimplementationofQuickSort.Toquicklysortanarray.

Arrays.sort(array);

e.g.IfIhaveanarrayofintegersinthewrongorder,thenIcanquicklysortthem.int[]outOfOrder={2,4,3,1,5,0};

Arrays.sort(outOfOrder);

assertEquals(0,outOfOrder[0]);

assertEquals(1,outOfOrder[1]);

assertEquals(2,outOfOrder[2]);

assertEquals(3,outOfOrder[3]);

assertEquals(4,outOfOrder[4]);

assertEquals(5,outOfOrder[5]);

YoucanalsosortString,orotherobjects.AlthoughwithstringsrememberthatuppercaselettershavelowerUnicodevaluesthanlowercaseletters,soyoumightwanttomakethestringsconsistentwithcaseusagebeforeyousortthem.

Page 98: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:SortWorkdaysArrayandAssertResultCreatean@Testmethodwhichinstantiatesaworkdaysarray,asshownintheexamplespreviously.String[]workdays={"Monday","Tuesday","Wednesday","Thursday","Friday"};

ThensortitusingArrays.sort

Assertthattheorderofvaluesinthearrayareasyouexpect.

Createanother@Testmethodsothattheworkdayshavemixedcase,andasserttheresulti.e.{"monday","Tuesday","Wednesday","thursday","Friday"}

ArraysofArraysRegularMultidimensionalArrays

Amultidimensionalarrayisanarrayofarrays.

Aregularmultidimensionalarrayhasallthenestedarraysofequallength.

SoIcoulddefinea2dimensionalintmultidimensionalarrayas:int[][]multi=newint[4][4];

Thiscreatesamultidimensionalarraycalledmulti.Whichis4by4,andsinceIhaven’tinitializedit,allthevaluesaredefaultof0.0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0,

Whereeachiteminmultiisanarrayoflength4.e.g.multi[0]assertEquals(4,multi[0].length);

AndIcanaccessthevaluesinthatarraybyaddinganotherindexe.g.accessthefirstvalueinmulti[0]withmulti[0][0]assertEquals(0,multi[0][1]);

Aswiththeonedimensionalarrays,Icandeclareandinitializeanarrayinasinglestatement:int[][]multi={{1,2,3,4},

{5,6,7,8},

{9,10,11,12},

{13,14,15,16}};

Theabovearraywouldbepopulatedasfollows:1,2,3,4,

5,6,7,8,

9,10,11,12,

13,14,15,16,

Andwewouldaccessthevalueswiththe[0][0]multiindexnotation:assertEquals(1,multi[0][0]);

assertEquals(7,multi[1][2]);

Page 99: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals(12,multi[2][3]);

assertEquals(14,multi[3][1]);

IcouldcreateadditionaldimensionsifIwantede.g.a3dimensionalarrayof3by4by5int[][][]multi3d=newint[3][4][5];

Wheremulti3disanarrayoflength3,andeachitemisanarrayoflength4,

whereeachitemisanarrayoflength5whereeachitemisanint

assertEquals(3,multi3d.length);

assertEquals(4,multi3d[0].length);

assertEquals(4,multi3d[1].length);

assertEquals(4,multi3d[2].length);

assertEquals(5,multi3d[0][1].length);

assertEquals(5,multi3d[0][2].length);

assertEquals(5,multi3d[1][3].length);

Andwecanaccessindividualintitemsusingthefull[0][0][0]multiindexnotation:assertEquals(0,multi3d[0][0][0]);

RaggedArrays

Sinceweknowthatamultidimensionalarrayisactuallyanarray,ofarrays,of…

Wecanseehoweasyitistocreateraggedarrays,whereeacharrayhasdifferentlengths:int[][]ragged2d={{1,2,3,4},

{5,6},

{7,8,9}

};

Whichwouldcreatethefollowingarray:1,2,3,4,

5,6,

7,8,9,

Eachofthearrayshasadifferentlength:assertEquals(4,ragged2d[0].length);

assertEquals(2,ragged2d[1].length);

assertEquals(3,ragged2d[2].length);

Andwewouldaccessthearrayvaluesusingthenormalnotation:assertEquals(4,ragged2d[0][3]);

assertEquals(6,ragged2d[1][1]);

assertEquals(7,ragged2d[2][0]);

Wecandefineraggedarraysdynamically,byleavingtheraggeddimensionsblankwhenwecreateit:int[][]ragged2d=newint[10][];

Theabovecodecreatesa2dimensionalarrayof10xundefined,wherewehaven’tdefinedthelengthofeachofthe10arrays,wewoulddothatwhenweinitializetheme.g.

Page 100: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ragged2d[0]=newint[10];

ragged2d[1]=newint[3];

Theabovecodeinitializesthefirst2itemsinragged2dasanarraywith10items,andanarraywith3items,alltheremainingitemsinragged2dwillremainontheirdefaultofnull.e.g.0,0,0,0,0,0,0,0,0,0,

0,0,0,

null

null

null

null

null

null

null

null

Exercises

Understandhowprint2DIntArraymethodworksIusedThefollowingcodewhenwritingthebooktoprintoutthe2Darraysyou’veseeninthischapter.

Havealookthroughthecodeandmakesureyouunderstandit.

publicvoidprint2DIntArray(int[][]multi){

for(int[]outer:multi){

if(outer==null){

System.out.print("null");

}else{

for(intinner:outer){

System.out.print(inner+",");

}

}

System.out.println("");

}

}

CreateaTriangleCreatearaggedarray,suchthatwhenyoupassthearraytoprint2DIntArrayasanargumentyououtputatriangletotheconsolethatlookslikethefollowing:

0,

0,1,

0,1,2,

0,1,2,3,

0,1,2,3,4,

0,1,2,3,4,5,

0,1,2,3,4,5,6,

0,1,2,3,4,5,6,7,

0,1,2,3,4,5,6,7,8,

0,1,2,3,4,5,6,7,8,9,

0,1,2,3,4,5,6,7,8,9,10,

Page 101: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

0,1,2,3,4,5,6,7,8,9,10,11,

0,1,2,3,4,5,6,7,8,9,10,11,12,

0,1,2,3,4,5,6,7,8,9,10,11,12,13,

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,

SummaryArraysareafastandeasywayofcollectingobjects.

Theyrequirealittleworktodefinethesizeofthearrayinadvance,butyou’veseenthatyoucanusethecopyutilitymethodsinjava.util.Arraytohelpresizeanarray.

Remembertobecarefulwheniteratingthrougharrayssothatyoudon’tintroduceoffbyoneerrors.Ifyouareinanydoubtthenusingtheforeachformofaforloopcanhelpavoidintroducingthiserror.

ReferencesandRecommendedReading

JavaForLoopdocs.oracle.com/javase/tutorial/java/nutsandbolts/for.html

Branchstatementdocs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html

JavaArraysdocs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

Java1.7Arraysdocumentationdocs.oracle.com/javase/7/docs/api/java/util/Arrays.html

Page 102: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTen-IntroducingCollections

WehavealreadyseenthebasiccollectionconceptinactionwithArrays.IpresentedArraysfirstsothatyouwouldunderstandtheconceptandthebasicsofiteratingoveracollection.

Collectionsareagoodplacetoconsiderotherloopingconstructslikewhile,dowhile.AndwewillalsointroducetheconceptofInterfaces.

ChapterSummaryInthischapteryouwilllearnthemaincollectionclasses.Theseoffermoreflexibilityandpowertoyouinyourdevelopmentwork.

ForEachLoop-iterateovereachindividualelementinacollectionConversion-convertingcollectionstoarraysandarraystocollectionswhileanddo…while-additionalloopingconstructsyoucanuseInterfaces-CollectionsareorganizedbyinterfacesandeachinterfacehasmultipleimplementationsGenerics-youwilllearnthebasicsofGenericstohelpyoudeclarecollectionsCoreCollections-Corecollectioninterfaces:List,Set,MapCoreImplementations-Corecollectionimplementations:ArrayList,HashSet,HashMap

Thisisoneofthelongestchaptersinthisbook.AndIknowitcanseemoverwhelming.SoIwillstartthechapterwithasimpleintroduction,comparingarraystoaspecifictypeofcollectioncalledaList,thencoverloopingovercollections,andthenthedifferentinterfacesandimplementationsforcollections.

ASimpleIntroductionTointroducecollections,IwillshowyouasimpleexamplecomparinguseofaCollectiontouseofanArray.@Test

publicvoidsimpleArrayExample(){

String[]numbers0123={"zero","one","two","three"};

for(StringnumberText:numbers0123){

System.out.println(numberText);

}

assertEquals("zero",numbers0123[0]);

assertEquals("three",numbers0123[3]);

}

Theaboveisarraycodeyouhaveseenbefore.

Thefollowingistheabovecode,rewrittentouseaCollection.@Test

publicvoidsimpleCollectionExample(){

String[]numbers0123Array={"zero","one","two","three"};

List<String>numbers0123=Arrays.asList(numbers0123Array);

Page 103: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

for(StringnumberText:numbers0123){

System.out.println(numberText);

}

assertEquals("zero",numbers0123.get(0));

assertEquals("three",numbers0123.get(3));

}

IntheabovecodeyoucanseethatIconvertedthearraytoaListusingtheasListmethodonthejava.util.Arraysclass.

IiterateovertheListinthesamewaythatIiterateoverthearray.

IaccessspecificelementsintheListusingthesameindexnumberingschemeasanarray,i.e.0isthefirstelementintheList,3isthefourthelementintheList.

IdeclaretheListusingadifferentsyntax.i.e.List<String>.Thisuses‘Generics’notation,whichIwillexplaininthischapter,butessentiallyI’msaying“aListofStrings”.

CollectionsaredynamicOneadvantagecollectionshave,overarrays,isthattheyaredynamic,sowedon’thavetodeclaretheirsizeinadvance.

IcanrewritetheexampleyouhaveseensuchthatIbuildtheListdynamically.@Test

publicvoidsimpleDynamicCollectionExample(){

List<String>numbers0123=newArrayList<String>();

numbers0123.add("zero");

numbers0123.add("one");

numbers0123.add("two");

numbers0123.add("three");

for(StringnumberText:numbers0123){

System.out.println(numberText);

}

assertEquals("zero",numbers0123.get(0));

assertEquals("three",numbers0123.get(3));

}

Intheaboveexample,youcanseethatIhaveanewdeclarationsyntax.AndIaddtheStringvaluesintotheListwithoutworryingaboutthesizeoftheListbecauseIknowthattheListwillresize.List<String>numbers0123=newArrayList<String>();

IntheabovedeclarationListisaninterfacewhichdeclaresthetypeofCollectionIamusing.

ArrayLististhespecificimplementationofListthatIamusing.

Iwillexplaininterfaceinmoredetailinthischapter.Butforthemoment,aninterfaceisatypeofclasswhichspecifiesthemethodsthatanobjectwillimplement.SowhenIdeclare

Page 104: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

mynumbers0123tobeaListIknowthatIhaveaccesstothegetmethod,andthattheelementsintheListwillbeaddedinorder.

SoaListisequivalenttothebehaviourofanarray,butisdynamic.IndeedanArrayListisatypeofListwhichisimplementedusinganArray.

Iteratingwithwhileanddo…whileInadditiontotheforloop,Javaalsoprovidesthewhileloop.Thisallowsustoloop‘while’aparticularconditionismet.

Itendtousetheforloopforiteratingaroundacollection.Butsometimeswedon’twanttoprocesseveryelementorwanttoiterateuntilaparticularconditionismet.

Therearetwoforms:

while(condition){...}

do{...}while(condition)

Withawhileloop,thebodyoftheloopmightneverbeexecuted,becausetheconditionmaynotbesatisfied.

Withado…whileloop,thebodyoftheloopisalwaysexecutedatleastonce.

AsanexamplecomparisonIwillcreateasimplelistofdays.String[]someDays={"Tuesday","Thursday",

"Wednesday","Monday",

"Saturday","Sunday",

"Friday"};

List<String>days=Arrays.asList(someDays);

Iwillwritesomesimplecodeusingeachoftheloopconstructs:

foreach

for

dowhile

while

AndwewillseethedifferentapproachesItakeforfindingthepositionof"Monday"intheList.

Withtheforeachloop,IcaniterateovereveryelementintheListandwhenIfind"Monday"Iwillhavetobreakoutoftheloop.intforCount=0;

for(Stringday:days){

if(day.equals("Monday")){

break;

}

forCount++;

}

assertEquals("Mondayisatposition3",3,forCount);

Withtheforloop,IwilliterateoverthesizeoftheListandbreakwhenIfind"Monday":

Page 105: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

intloopCount;

for(loopCount=0;loopCount<=days.size();loopCount++){

if(days.get(loopCount).equals("Monday")){

break;

}

}

assertEquals("Mondayisatposition3",3,loopCount);

Withthewhileloop,Icanmakethecheckfor"Monday"theloopexitcondition,soIonly‘do’thebodyoftheloop,‘while’Ihavenotfound"Monday":intcount=0;

while(!days.get(count).equals("Monday")){

count++;

}

assertEquals("Mondayisatposition3",3,count);

Withthedo…whileloop,IneedtosettheindexoutsidethevalidboundaryofthelistbecauseIincrementitinthebodyoftheloop,andagainIonly‘do’thebodyoftheloop‘while’Ihavenotfound"Monday":intdocount=-1;

do{

docount++;

}while(!days.get(docount).equals("Monday"));

assertEquals("Mondayisatposition3",3,docount);

Theforeachloopisanexcellentchoicewhenyouwanttolooparoundeveryelementinacollection.Youdon’thavetoworryaboutoffbyoneindexerrorsoroutofboundsexceptions.Butyouhavetobreaktofinishtheloopearly.

Theforloop,isaverypowerfulconstruct,butcanbecomehardtoreadiftheconditionislong,orthesetuporendofloopactionsarecomplicated.

Thewhileanddo…whileloopareanexcellentchoiceiftheloopneedstoterminatebasedonanarbitraryorcomplexcondition.Choosingbetweenwhileanddo…whileisdoneonthebasisof:

usedo…whileifyouwantthelooptorun1ormoretimesusewhileifyouwantthelooptorun0ormoretimes

Exercise:UseaforloopinsteadofawhileloopUsethecodeabovetocreatethedaysoftheweekArray,convertittoalist,anditerateoveritwithawhileloop.Thenconvertthewhileloopintoaforloop.Hint:Usetheconditioninthewhileloopasaforloopconditionstatementanddemonstratethattheforloopcanbeusedasawhileloop.

e.g.for(…;addwhileconditionhere;…)

InterfacesArraysareasimplecollectionmechanismbuttheydon’tofferthesameinterfaceascollections.

Page 106: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Javahasaconceptofaninterface.Byinterface,ImeanthemethodstheyexposeandtheAPIthatweusetoworkwiththeclasses,i.e.aninterfacedefineswhatyoucando.

Aclasscanimplementanumberofinterfaces,inwhichcaseitmustimplementthemethodsthataredefinedinallofthoseinterfaces.

Javaprovidesanumberofinterfacesforcollections:

Collection-agenericcollectionthatyoucanaddobjectstoSet-acollectionthatdoesnotallowduplicatesList-acollectionyoucanaccessandaddelementsatspecificindexpositionsMap-a“key,value”pairwhereyoustoreanobjectinthecollection,butcanaccessitwithauniquekey

TheCollectioninterfacesareallinjava.util

ImportantInterfacesIhaveonlylistedabove,whatIconsiderthemostimportantinterfacesabove,i.e.theonesthatIusemostoften.

Thisdemonstratesmybiases,andtheneedsofthecodeIwrite.

Overtimeyouwillidentifytheinterfaces,andimplementationthatyouusealot.Learnthoseindetailsothatyouunderstandthemwell.Butmakesurethatyoulearnthecapabilitiesoftheotherinterfacesandimplementationssothatyouknowwhentousethem,anddon’ttryanduseasinglecollectiontype,whenanotherwouldfityourneedsbetter.

DeclareasInterfaces,InstantiateImplementationsAnInterfaceonitsowncannotbeusedtodoanything.Otherclassesimplementinterfacesandsowedeclarevariablesastheinterfacebuthavetoinstantiatethemwithimplementations.e.g.Collectionworkdays;

workdays=newArrayList();

HereIhavedeclaredavariablecalledworkdaysasaCollectionbecauseIonlyneedtousethemethodsthattheCollectioninterfaceprovides.ButIhavetoinstantiateitasanArrayListwhichisaclassthatimplementstheCollectioninterface.

TheArrayListclassexposesmanymoremethodsthantheCollectioninterface.HadIdeclaredthevariableworkdaysasanArrayListIwouldgainaccesstomethodslikeindexOf,trimToSize,andget.

WhenIonlyneedaccesstothemethodsonCollectionthenIshoulddeclaremyvariablesattheminimumleveloffunctionalityneeded.

Bycodingtointerfaceslikethis,wehavetheabilitytoswapinandouttheimplementationclass;ifwediscoverthatoneimplementationisfasterthananother,ortakeslessmemory.Butwedon’thavetochangethebodyofthemethodcodewhenweswapadifferentonein.

Page 107: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

e.g.IcoulduseArrayListorLinkedListorHashSetasmyimplementationforCollectionbecauseeachimplementtheCollectioninterface.ButIneedtounderstandtheimplementationincaseoneofthemimposesconstraintsonmycodethatIdon’twant,forexampleaHashSetdoesnotallowduplicateelements,butanArrayListdoes.

Thismaynotmakesenseyet,butitisanimportantconceptandIwilltrytoillustrateitthroughalltheexamplesinthischapter.

CoreCollectionInterfacesTheofficialdocumentationliststhefollowingastheCoreCollectioninterfaces:

Collection

List

Set

SortedSet

Queue

Deque

Map

SortedMap

InthischapterwewillcoverList,SetandMapandleavetheothercollectionsuntillaterinthebook.

InheritanceHierarchyThisisaninheritancehierarchy;soaSetisaCollection,aListisaCollection,butbothSetandListhavenuancesthatmakethemunique.

Therearetwomaincollectionconcepts:CollectionandMap

Collectionprovidesawayofgroupingobjects.Mapprovidesawayofassociatingobjectswitha‘key’forlaterretrievalandaccessing.

ThefollowingtableprovidesasummaryofthemainmethodsontheInterfaces:

Page 108: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Collection List Set Map

add(e) get(i)AllinCollection

put(k,v)

remove(e) remove(i) remove(k)

removeAll(c) add(i,e) entrySet

retainAll(c) addAll(i,c) get(k)

clear indexOf(e) clear

contains(e) lastIndexOf(e) containsKey(k)

containsAll(c) set(i,e) containsValue(v)

size subList(i1,i2) size

isEmpty isEmpty

toArray AllinCollection values

toArray(a) keySet

addAll(c) putAll(m)

where:e==element,c==collection,a==array,i==index,k==key,v==value,m==map

CollectionInterfaceACollectionisagroupofobjects.Whereeachobjectisreferredtoasanelement.TheCollectioninterfaceprovidesthebasicsupersetofmethods.

add-toaddanelementtoacollectionremove-toremoveanelementfromacollectionsize-toreturnthenumberofelementsinthecollectionisEmpty-checkifacollectionisemptyaddAll-toaddeveryelementofanothercollectionintothecollectionremoveAll-removeeveryelementofanothercollectionfromthecollectionretainAll-removeeveryelementinthecollectionwhichisnotinanothercollectionclear-toremovealltheelementsfromthecollectioncontains-tocheckifanobjectisinthecollectioncontainsAll-tocheckthatonecollectioncontainsalltheelementsofanothertoArray-toconvertacollectiontoanarray

Instantiatingacollection

WecannotinstantiateaCollectionbecauseaCollectionisaninterface.Thereareclasseswhichimplementtheinterface,e.g.ArrayList.SowedeclareourvariablesasCollectionandinstantiatethemasclasswhichimplementstheinterface.Collectionworkdays;

workdays=newArrayList();

Intheabovecodewehaveausablevariablecalledworkdays.Butacollectioncancontainanyobject,andsincewedidn’tspecifywhatthecollectionwillcontainitdefaultstoobject.ThiswillbecomeanannoyancelaterwhenwetryanditeratethroughthecollectionandhavetocasttheelementsfromobjecttoString.

Page 109: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Asarecommendation,whenyouworkwithacollection,andtheobjectstobestoredinthecollectionareallofthesametypethendeclarethecollectionasacollectionoftypee.g.Collection<String>weekendDays=new<String>ArrayList();

Collection<String>daysOfWeek=new<String>ArrayList();

IntheabovecodeIdeclaretheCollectionasacollectionof<String>.WhichIinstantiatewithanArrayListthatwillonlycontain<String>.

Thisprovidesanumberofbenefits:

ItmakesthecodeclearastothecontentsofthecollectionItmakesthecollectionsstronglytypedwhichhelpswithcodecompletionlater

Trytogetinthehabitofdeclaringthetypeofthecontentsofthecollectionwhenyouknowthatthecollectionwillonlycontainonetypeofelement.

GenericsThe<String>notation,isausageofJavaGenericswhichisawayofdeclaringclassestouseaparticulartypeofobject,butonlydefiningthetypeatcompiletime.

Afulldiscussionofgenericsisbeyondthescopeofthisbook,butitisimportanttorecognizetheusageofit,andknowhowtotakeadvantageofitwiththeclassesyouuse.AtthemomentyouhaveonlyseenGenericsinthecontextofcollections.

Readthereferencesongenericsifyouwanttoself-studygenericsinmoredetail.

Fornow,understandthat<String>declaresthetypeofelementsintheCollectionandimplementationClass.

GenericSyntaxInmostoftheexamplesinthisbookIwillusethesyntaxlikethefollowing:Collection<String>weekendDays=new<String>ArrayList();

Itisalsopossibletoleaveoutthe<String>ontheArrayListanduse<>andtheJavacompilerwillusetheGenericvaluefromtheinterfacedeclaratione.g.Collection<String>weekendDays=newArrayList<>();

ThenewersyntaxisshorterandsometimesyourIDEwillcodecompleteintheaboveformatforyou.

ThereasonIdon’tuseit,issimplybecauseI’mnotusedtousingit,IthinkitonlyarrivedinJava1.7

ThefollowingsyntaxforusingGenericsareequivalent:Collection<String>cola=newArrayList<String>();

Collection<String>colb=new<String>ArrayList();

Collection<String>colc=newArrayList<>();

addingelementstoacollection:add,addAll,size,containsAll

Wecanaddelementstoacollectionwiththeaddmethod.

Page 110: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

workdays.add("Monday");

workdays.add("Tuesday");

workdays.add("Wednesday");

workdays.add("Thursday");

workdays.add("Friday");

assertEquals(5,workdays.size());

WecanusethesizemethodtocountthenumberofelementsintheCollection.

AndwecanusetheaddAllmethodtoaddalltheelementsfromoneCollectionintoanother:daysOfWeek.addAll(workdays);

assertEquals(workdays.size(),daysOfWeek.size());

assertTrue(daysOfWeek.containsAll(workdays));

IntheabovecodeweaddalltheelementsinworkdaystoanemptycollectiondaysOfWeek.

ThecontainsAllmethodcanhelpuscheckifaCollectioncontainsalltheelementsofanothercollection.TheCollectionthatwecallthecontainsAllmethodon(i.e.daysOfWeek)cancontainmoreelementsthantheargumentCollection(i.e.workdays),butinorderforcontainsAlltoreturntrue,alloftheelementsoftheargumentcollection,mustbepresent.

removingindividualelements:remove,contains

IfIaddsomeelementstoweekendDays.weekendDays.add("Saturday");

weekendDays.add("Funday");

ThenyoucanseethatImadeamistakebyspellingSundayincorrectlyasFunday.

IcanfixthaterrorbyremovingFundaywiththeremovemethod:weekendDays.remove("Funday");

IcanusethecontainsmethodtocheckifaCollectioncontainsaspecificelement.IfIcheckforFundaycontainsshouldreturnfalse:assertFalse(weekendDays.contains("Funday"));

OfcourseIcanaddthecorrectvalueintotheCollection,andcheckitspresence.weekendDays.add("Sunday");

assertEquals(2,weekendDays.size());

assertTrue("BugFixed,Sundayisinthecollectionnow",

weekendDays.contains("Sunday"));

Iterateoveracollection

ACollectionactuallyimplementstheIterableinterface.Whichformsthebackboneoftheforeachfunctionalitythatwesawearlier.

So,assumingthatIhaveaddedalltheworkdaysandweekendDaysintodaysOfWeek,Icaniterateoveritwiththeforeachconstruct.for(StringdayOfWeek:daysOfWeek){

System.out.println(dayOfWeek);

Page 111: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

}

Togeneratethefollowingoutputtotheconsole:Monday

Tuesday

Wednesday

Thursday

Friday

Saturday

Sunday

IteratingovertheCollectionprovidesagoodillustrationofwhywewanttodeclarethetypeofelementthatthecollectionholds.Forthedeclarationofworkdaysthatwepresentedearlier:Collectionworkdays;

workdays=newArrayList();

WhenIiterateoverthis,IgetanObjectratherthanaspecifictype:for(Objectworkday:workdays){

StringoutputDay=(String)workday;

System.out.println(outputDay);

}

IntheabovecodeIhadtodeclareworkdayasanObjectandwhenIuseditwithintheloop,IhadtocastittoStringusingthe(String)notation.

Whenwewanttorefinethetypeofanobjectthenwecancastittoaspecifictype.Wecandothatwhentheobjectsupportstheinterfaceforthattype,orisofthattype.

WeusedtohavetocastobjectsalotinJava,butnowthatthecollectionssupportGenericswecanspecifythetypeinthedeclarationandavoidcastinglater.

EmptyaCollection:clear,isEmpty

Theclearmethodallowsustoemptyacollection.Collection<String>daysOfWeek=new<String>ArrayList();

daysOfWeek.addAll(workdays);

daysOfWeek.addAll(weekendDays);

assertEquals(7,daysOfWeek.size());

daysOfWeek.clear();

assertEquals(0,daysOfWeek.size());

assertTrue(daysOfWeek.isEmpty());

WecanusesizeandisEmptytoverifythatithasnoelements.

RemovingAllofonecollectionfromanother:removeAll

AssumingthatmydaysOfWeekCollectioncontainsalltheweekendDaysandworkdays.

IcanremovethecontentsoftheweekendDaysCollectionfromdaysOfWeekwiththeremoveAllmethod:Collection<String>daysOfWeek=new<String>ArrayList();

Page 112: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

daysOfWeek.addAll(workdays);

daysOfWeek.addAll(weekendDays);

assertEquals(7,daysOfWeek.size());

daysOfWeek.removeAll(weekendDays);

assertTrue(daysOfWeek.containsAll(workdays));

assertEquals(5,daysOfWeek.size());

assertFalse(daysOfWeek.containsAll(weekendDays));

IcanusethecontainsAllmethodtocheckthattheremovaltookplace.

Removeallbutonecollectionfromanother:retainAll

SotoretainonlytheweekendDaysindaysOfWeekIwoulddothefollowing:daysOfWeek.retainAll(weekendDays);

UsetheretainAllmethodtoremoveallbutonecollectionfromanother.Orinotherwords,retainonlytheelementsfromtheargumentcollection,inthecollectionIcallthemethodon.Collection<String>daysOfWeek=new<String>ArrayList();

daysOfWeek.addAll(workdays);

daysOfWeek.addAll(weekendDays);

assertTrue(daysOfWeek.containsAll(workdays));

assertTrue(daysOfWeek.containsAll(weekendDays));

daysOfWeek.retainAll(weekendDays);

assertEquals("onlyweekenddaysnow",2,daysOfWeek.size());

assertTrue(daysOfWeek.containsAll(weekendDays));

assertFalse(daysOfWeek.containsAll(workdays));

Convertacollectiontoanarray

UsethetoArraymethodtoconvertaCollectiontoanarray.

Thismethodcanbeusedintwoforms.

toArray()

toArray(anArray)

WhenwecalltoArraywithoutanargument,itwillreturnanarrayofObjectObject[]daysOfWeekArray=daysOfWeek.toArray();

assertEquals(7,daysOfWeekArray.length);

IfwesubsequentlywantedtouseelementsfromthearraywewouldhavetocastthemasString.i.e.(String):assertEquals("Monday".length(),

((String)daysOfWeekArray[0]).length());

ThetoArray(anArray)call,wherewepassasargumentaninitializedarray,avoidstheseproblems:

Page 113: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

String[]anotherArray=newString[daysOfWeek.size()];

daysOfWeek.toArray(anotherArray);

assertEquals("Monday".length(),

anotherArray[0].length());

IntheabovecodeIdeclareaStringarray,andinitializethearrayatthecorrectsizetoholdthecollectioncontents.ThencallthetoArraymethodwiththatarrayastheargument.

CollectionDocumentation

YoucanfindthedetailsofCollectionontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/collection.html

Implementations:

docs.oracle.com/javase/tutorial/collections/implementations

ItypicallyuseaListimplementationwhenIwantjustagenericCollection,butwewillcoverotherimplementationslaterinthischapter.

Exercise:CreateandmanipulateaCollectionofUsersCreateaCollectionofUsersAssertthatthesize()==0andisEmpty()==trueCreatetwoUserobjectsAddtheUserobjectstothecollectionAssertthatthesize()==2andisEmpty()==falseCreateasecondcollectionwithtwodifferentusersaddAllthesecondcollectiontothefirstcollectioncheckthatthefirstcollectionnowcontainsobjectsfromthesecondcollectionremoveAlltheUserobjectsfromthesecondcollectionclearthefirstcollection

Ensureyouassertaftereachstep

ListAListbuildsontheCollection,soallCollectionmethodsareavailable.

AList:

allowsstoringofduplicateelements,retainselementsintheorderadded.allowsaddingelementsinspecificplacesinthelist

ItendtouseaListinpreferencetoanArray.Arraysareclearlyatalowerlevelandfaster.ButIonlyuseanArraywhenI’mworkingwithafixedsetofobjectsthatIknowarenevergoingtochange.

Page 114: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IfmycodeneedstobeparticularlyfastthenImightoptimizedowntoanArray.ButifI’mworkingonanycodedynamically,thenaListwilloftenbemyfirstchoiceasitisaverysimplecollection.

AListoffersallthemethodsfromCollectionandadds:

get(i)toretrieveanelementfromaspecificindexremove(i)toremovetheelementatanindexadd(i,e)toaddataspecificindex,anelementaddAll(i,c)toadd,ataspecificindex,allelementsinacollectionindexOf(e)toreturntheindexofanelementlastIndexOf(e)toreturnthelastindexofanelementset(i,e)tosettheelementataparticularindexsubList(i1,i2)toreturnasublistfromindex1toindex2

InalloftheexamplesIwilldeclareaListthatwillcontainString,andwillinstantiateasanArrayList,whichyoualsosawintheCollection@Testmethods.ItendtodefaulttoArrayListforbothCollectionandList.e.g.List<String>days=newArrayList<String>();

getanelementatindex

AListexposesanarraystyleinterfacewhereeachelementinthelisthasapositionalindex,whichlikeanarraystartsat0.@Test

publicvoidgetAnElementAtAnIndex(){

List<String>days=newArrayList<String>();

days.add("Monday");

days.add("Tuesday");

days.add("Wednesday");

assertEquals("Monday",days.get(0));

assertEquals("Tuesday",days.get(1));

assertEquals("Wednesday",days.get(2));

}

Intheabovecode,theListguaranteesthattheelementsIaddwillbeaccessibleintheorderthatIaddthemsothatthefirstelementaddedcanbeaccessedwithindex0,thesecondelementaddedcanbeaccessedwithindex1etc.

removeanelementatindex

Inadditiontohavingtheabilitytoremoveanelement,wecanalsoremoveelementsbasedontheirindex.@Test

publicvoidremoveAnElementAtAnIndex(){

List<String>days=newArrayList<String>();

days.add("Monday");

days.add("Tuesday");

days.add("Wednesday");

Page 115: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

days.remove(1);

assertEquals(2,days.size());

assertEquals("Monday",days.get(0));

assertEquals("Wednesday",days.get(1));

}

WhenIremoveanelementbasedonitsindex,thelistresizesandelementsaftertheoneremovedhavetheirindexesadjusted.SoifIremovetheelementatindex1,theelementthatwasatindex2cannowbefoundatindex1.

addanelementataspecificindex

WithaCollectionwecanaddelements,buttheyarejustinthecollection,theycouldbeanywhere,wedon’tcare.

Withanarray,wehavetoresizethearrayifwewanttoaddnewelements.

WithaListwecanaddelementsatspecificpointsintheList.

Inthisexample,Istartwithapartiallistofdays.List<String>days=newArrayList<String>();

days.add("Tuesday");

days.add("Thursday");

days.add("Saturday");

Ineedtoaddafewdaystothislist:days.add(0,"Monday");

days.add(2,"Wednesday");

days.add(4,"Friday");

days.add(6,"Sunday");

Iadd“Monday”tothestartofthelist,then“Wednesday”and“Friday”intothemiddleofthelist,and“Sunday”attheendofthelist.

YoucanseethatwhenIaddanelementinthemiddleorthestart,thatitdoesn’toverwritetheelementthatisalreadythere,itinsertstheelementandmoveseverythingelseinthelisttoanewindex.

AddingtotheendWhenaddingtotheendoftheListyoucanonlyaddtotheend,youcan’taddwaybeyondthesizeoftheListandexpectittoresize.

i.e.ifIhave3elementsinmyListthenIcanaddanotheroneatindex3.Index3doesn’texistuntilIaddit(Ican’tget(3)),butIcanincreasethesizeofthelistbyaddingtotheend.Icannotaddanelementtoindex20,JavawouldthrowanIndexOutOfBoundsException.

Icouldalsousetheadd(e)method,becauseaddinganelementtoaListaddsittotheendoftheList.

addAllelementsinacollectionataspecificindex

WithaCollectiontheaddAlladdstheelementssomewhereinthecollection.WithaListwecancontrolexactlywhereweinserttheelementsinthecollection.

Forexample,ifIcreatedaListfordays:

Page 116: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

days.add("Monday");

days.add("Friday");

IcouldcreateanothercollectionwiththemissingDaysandinsertthem,intothemiddleofthedayscollection.days.addAll(1,missingDays);

Thiswouldinsertthecollectionatindex1,andmove“Friday”toposition4.Itwouldnotoverwritetheelementexistingatindex1,theaddAllatanindexperformsaninsertList<String>days=newArrayList<String>();

List<String>missingDays=newArrayList<String>();

days.add("Monday");

days.add("Friday");

missingDays.add("Tuesday");

missingDays.add("Wednesday");

missingDays.add("Thursday");

days.addAll(1,missingDays);

assertEquals(5,days.size());

assertEquals("Monday",days.get(0));

assertEquals("Tuesday",days.get(1));

assertEquals("Wednesday",days.get(2));

assertEquals("Thursday",days.get(3));

assertEquals("Friday",days.get(4));

CanInsertatStartandEndAswithaddtheaddAll(i,c)methodcaninsertthecollectionatthestartoftheListbyusingindex0,orattheendoftheListbyusingthe‘nextindex’orthe‘size’.

AddingtotheendoftheListwithanindexisequivalenttousingtheaddoraddAllmethodwithoutanindex.SincetheaddmethodsonaListaddtotheendoftheList.

indexOffindtheindexofanelement

WhenwehaveaListandwedon’tknowtheindexoftheelementinthelistthenwecanusetheindexOfmethodtotelluswhereintheListtheelementcanbefound.List<String>days=newArrayList<String>();

days.add("Tuesday");

days.add("Thursday");

days.add("Saturday");

assertEquals(1,days.indexOf("Thursday"));

IfindexOfisusedonaListwithduplicatesthenitwillreturnthefirstindexoftheelement.

lastIndexOfthethelastindexofanelement

AListallowsduplicateelements,sowemaywanttofindthepositionofthelastoftheduplicates.InwhichcasewewouldusethelastIndexOfmethodtodothis.

Page 117: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

List<String>days=newArrayList<String>();

days.add("Tuesday");

days.add("Thursday");

days.add("Saturday");

days.add("Thursday");

days.add("Thursday");

days.add("Sunday");

assertEquals(4,days.lastIndexOf("Thursday"));

IflastIndexOfisusedonaListwithnoduplicatesthenitreturnsthesameasindexOf.

settheelementatanindex

Whenusinganarray,thearray[1]="NewElement"wouldoverwritetheexistingcontentsatindex1.Wecandothesamethingwithsetwhichallowsustosetthevalueofaparticularindex.

Forexample:List<String>days=newArrayList<String>();

days.add("Monday");

days.add("Thursday");

days.add("Wednesday");

days.set(1,"Tuesday");

assertEquals("Tuesday",days.get(1));

Intheabovecode,Ioriginallyadd"Thursday"intoindex1,butthenoverwriteitto"Tuesday"withthesetmethod.days.set(1,"Tuesday");

Andbecausesetperformsanoverwrite,thesizeoftheListdoesnotchangeandnore-orderingtakesplace.assertEquals(3,days.size());

assertEquals("Monday",days.get(0));

assertEquals("Tuesday",days.get(1));

assertEquals("Wednesday",days.get(2));

subListtocreateaportionofthelist

TocreateanewListwithaselectionofelementsfromaparentListweusethesubListmethod.

subListtakestwoarguments,thefromIndex,andthetoIndex.ThetoIndexis1morethantheindexyouwant.

Forexample,ifIcreatealistofdaysandwantasubListofjusttheworkdays"Monday"through"Friday"."Monday"willbeatindex0,and"Friday"isatindex4,butifIwanttoinclude"Friday"inthenewsub-listthenIhavetouse5asmytoIndex:List<String>days=newArrayList<String>();

days.add("Monday");

days.add("Tuesday");

Page 118: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

days.add("Wednesday");

days.add("Thursday");

days.add("Friday");

days.add("Saturday");

days.add("Sunday");

List<String>workdays=days.subList(0,5);

assertEquals(5,workdays.size());

assertEquals("Monday",workdays.get(0));

assertEquals("Tuesday",workdays.get(1));

assertEquals("Wednesday",workdays.get(2));

assertEquals("Thursday",workdays.get(3));

assertEquals("Friday",workdays.get(4));

ListDocumentation

YoucanfindthedetailsofListontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/list.html

Implementation:

docs.oracle.com/javase/tutorial/collections/implementations/list.html

Exercise:CreateandmanipulateaListofUsersWritean@Testannotatedmethod,andcreateaListofUserobjects.

CreatetheListCreatetwoUserobjectsAddaUsertothelistAddaUsertothefrontofthelistAssertontheindexOfpositionsoftheUserobjectsremovethefirstUserobject

RemembertoassertaftereachactionontheList

SetASetbuildsontheCollection,soallCollectionmethodsareavailable.

ASet:

doesnotallowstoringduplicates,soaddingaduplicateisignored.orderingisnotguaranteed,soifyouiteratethroughasetitmaynotbringbacktheelementsintheorderyouexpect

@Test

publicvoidsetDoesNotAllowDuplicateElements(){

Setworkdays=newHashSet();

workdays.add("Monday");

Page 119: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

workdays.add("Monday");

workdays.add("Monday");

workdays.add("Monday");

workdays.add("Monday");

assertEquals(1,workdays.size());

}

ItendtouseaHashSetfromjava.utilasmydefaultSetimplementation.

SetsofCustomObjectsBecarefulifyouwanttocreateaSetofyourownobjectsandhaveJavaidentifytheduplicatedelements.TheduplicationcheckisbasedonahashandyouneedtoimplementyourownhashCodemethodwhichgeneratesauniquehashforeachuniqueobject.

Youshouldalsoimplementyourownequalsmethod.

IhavedecidedtomakethisoutofscopeforthisbookbecauseIthinkmostofyouareunlikelytoexperiencethis.I’massumingthatyouaremainlylikelytocreateaSetcontainingbuiltinclasses.

Iveryoftenavoidthisproblembycreatingsetsof‘keys’forobjectsstoredinaMapandthekeystendtobeString.

HoweverifyoudoneedtocreateaSetofcustomobjectsthenthereferencesinthe“NextSteps”chapter,orattheendofthischapter,shouldhelp.

SetDocumentation

YoucanfindthedetailsofSetontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/set.html

Implementation:

docs.oracle.com/javase/tutorial/collections/implementations/set.html

Exercise:CreateandmanipulateaSetofUsersWritean@Testannotatedmethod,andcreateaSetofUserobjects.

CreateaUserAddtheUsertotheSetAddtheUsertotheSetagainCheckthattheUserhasonlybeenaddedtotheSetonce

MapAMapisacollectionwhereeachelementisavalue,anditisstoredwithanassociatedkey.

TheMapisacollectionofkeyvaluepairs.

Eachkeymustbeunique.Andeachkeymapstoonlyonevalue

Page 120: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MaphassomemethodsincommonwithCollection:

sizeclearisEmpty

Whichmeansyoualreadyknowwhatthosemethodsdo.

Andsomemethodsthathaveaverysimilarcounterpart:containsKeyandcontainsValuearesimilartotheCollectionmethodcontains.

put(k,v)toadd“key,value”pairstothemapremove(k)toremovetheelementwiththatkeyentrySettoreturnaSetofallelementsasMap.Entryobjectsget(k)toreturntheelementbasedonthekeycontainsKey(k)returnstrueifthekeyisintheMapcontainsValue(v)returnstrueifthevalueisintheMapvaluesreturnsaCollectionofallthevalueskeySetreturnsaSetofallthekeysputAll(m)addsaMap(m)totheMapobject

ItendtouseHashMapasmydefaultimplementation.Andbelowyoucanseeexamplesofthedeclarationandinitializationcode:Map<String,User>mapa=newHashMap<>();

Map<String,User>mapb=newHashMap<String,User>();

Map<String,User>mapc=new<String,User>HashMap();

IntheabovecodeyoucanseethataMapisdeclaredwithtwovaluesMap<Key,Value>sointheabovecodeIdeclaretheMapvariablesashavingaStringkey,andaUservalue.SoIwouldusetheMaptostoreUserobjects.put(k,v)

Add“key,value”pairstoaMapwiththeputmethod.Map<String,String>map=newHashMap<>();

map.put("key1","value1");

map.put("key2","value2");

map.put("key3","value3");

assertEquals(3,map.size());

Thekeycanbeanobject,ascanthevalue.ThedeclarationoftheMapdetermineswhatobjectswecanputintotheMap.

IfIputa“key,value”pair,wherethekeyalreadyexistsintheMapthentheoldvaluewillbeoverwrittenwiththenewvalue:map.put("key1","newvalue1");

assertEquals("newvalue1",map.get("key1"));

get(k)toretrieveavaluefromtheMap

IcangetvaluesfromtheMapusingthekeythatIputthevalueintotheMapwith.

Page 121: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals("value1",map.get("key1"));

assertEquals("value2",map.get("key2"));

assertEquals("value3",map.get("key3"));

IfIattempttogetavaluewithakeythatdoesnotexistthennullwillbereturned.assertEquals(null,map.get("key4"));

remove(k)toremovea“key,value”pair

IcanremoveavaluefromaMapbycallingtheremovemethodwithanexistingkey.map.remove("key1");

assertEquals(2,map.size());

IfthekeydoesnotexistthennoexceptionisthrownandnothinghappenstotheMap,themethodcallhasnoimpact.

EmptyaMapwithclear,checkwithsize,isEmpty

JustaswecouldwiththeCollection,wecanemptytheMapbycallingtheclearmethod.map.clear();

assertEquals(0,map.size());

assertTrue(map.isEmpty());

IcancheckthattheMapisemptyusingthesizeandtheisEmptymethods.

CheckcontentsofMapwithcontainsKey(k)andcontainsValue(v)

ThecontainsKeymethodreturnstrueorfalse.truewhensomethingwiththekeyhasbeenputintheMapandfalsewhennothingusingthatkeyhasbeenputintheMapMap<String,String>map=newHashMap<>();

map.put("key1","value1");

map.put("key2","value2");

map.put("key3","value3");

assertTrue(map.containsKey("key1"));

assertFalse(map.containsKey("key23"));

assertTrue(map.containsValue("value2"));

assertFalse(map.containsValue("value23"));

putAll(m)toaddaMaptotheMap

IcanputoneMapinsideanotherMapwiththeputAllmethod:map.putAll(mapToAdd);

IfItryandaddaMapthatcontainsakeyduplicatinganexistingkey,thenthevaluefromthenewMapwillbeused:e.g.inthefollowingcodethekey“key1”isduplicatedacrossbothMapobjects:map.put("key1","value1");

map.put("key2","value2");

map.put("key3","value3");

mapToAdd.put("key1","keyvalue1");

mapToAdd.put("key4","value4");

Page 122: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

WhenIputmapToAddintomap:map.putAll(mapToAdd);

Theexistingvaluefor“key1”isoverwrittenwiththevaluefrommapToAdd:assertEquals(4,map.size());

assertEquals("keyvalue1",map.get("key1"));

values

valuesreturnsaCollectioncontainingallthevaluesintheMap:Collection<String>values=map.values();

EachvaluewillbeofthetypedeclaredfortheMapkeySet

keySetreturnsaSetwhereeachelementisakeyfromtheMap:Set<String>keys=map.keySet();

entrySettoworkwith“key,value”pairs

entrySetreturnstheSetofEntryobjectsfromjava.util.Map.

AnEntryisthe“key,value”pair.

Entryexposesthemethods:

getValuetoreturnthevaluegetKeytoreturnthekeysetValuetosetthevalue

ThefollowingcodeiteratesthroughtheentriesintheMapandsetsallthevaluesto"bob":Set<Map.Entry<String,String>>entries=map.entrySet();

for(Map.Entry<String,String>entry:entries){

entry.setValue("bob");

}

MapDocumentationYoucanfindthedetailsofMapontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/map.html

Implementation:

docs.oracle.com/javase/tutorial/collections/implementations/map.html

Page 123: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:CreateandmanipulateaMapofUserobjectsWritean@Testannotatedmethod,andcreateaMapofUserobjects.

CreateaMapofUserobjectsCreatetwoUserobjectsAddbothUserobjectstothemapusingthesamekeyCheckthatonlyoneUserobjecthasbeenadded

SummaryInthischapteryoulearnedthebasicsofCollections.

ACollectionisthemostgenericcollectioninterfacewhichsupportsadding,removinganditeratingoveracollectionofobjects.

CollectionsusetheGenericssyntaxtodefinethetypeofobjectinthecollectione.g.List<String>tocreateaListofStringobjects.

ThebasicCollectioninterfacesare:

Collection-abasiccontainerList-toallowaccessingbyindexSet-toavoidduplicatesMap-tostore“key,value”pairs

Eachinterfacecanhavemultipleimplementations,theimplementationsweusedinthischapterwere:

Collection&List:ArrayList

Set:HashSet

Map:HashMap

Collectionsofferustheabilitytocreatedynamicandre-sizablecontainers,ratherthanfixedsizearraycontainers.

ReferencesandRecommendedReading

Programtoaninterface,notanimplementationartima.com/lejava/articles/designprinciplesP.html

JavaInterfaceTutorialdocs.oracle.com/javase/tutorial/java/concepts/interface.html

JavaCollectionsTutorialsdocs.oracle.com/javase/tutorial/collections

JavaCollectionInterfaces

Page 124: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

docs.oracle.com/javase/tutorial/collections/interfaces/index.htmlJavaGenerics

docs.oracle.com/javase/tutorial/java/genericsJavaCollectionImplementations

docs.oracle.com/javase/tutorial/collections/implementationsHashCode

docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29List

Interfacedocs.oracle.com/javase/tutorial/collections/interfaces/list.html

Implementationsdocs.oracle.com/javase/tutorial/collections/implementations/list.html

SetInterface

docs.oracle.com/javase/tutorial/collections/interfaces/set.htmlImplementations

docs.oracle.com/javase/tutorial/collections/implementations/set.htmlMap

Interfacedocs.oracle.com/javase/tutorial/collections/interfaces/map.html

Implementationsdocs.oracle.com/javase/tutorial/collections/implementations/map.html

Page 125: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterEleven-IntroducingExceptions

ChapterSummaryInthischapteryouwilllearnaboutexceptions:

anexceptionisanunexpectedeventwhichcaninterruptourcodeexecutionunderstandthestacktraceonanexceptionhowtohandleanexceptionusingtryandcatchandfinallytriggeraNullPointerExceptionandhowtocatchthemthrowingexceptionsfromyourowncodeusingmethodsontheexceptione.g.getMessage,getStackTracecatchingmultipleexceptionsJUnit’sexpectedparameteron@Test

Anexceptionissomethingthathappenstoyouwhenyouleastexpectit.Oftenbecauseyouhavewrittencodewhichcompiles,buthasanerroratruntimee.g.youtrytoaccessafilethatdoesnotexist,oraccessavariablethathasnotbeenset.Andsometimesbecausesomethinguntowardhappenedonthemachineyourcodewasexecutinge.g.thesystemrunsoutofmemory.

Averyimportantpartoflearningtowriteautomationinvolveshandlingandprocessingexceptions.

WhatisAnexception?Anexceptionisanobjectraisedwhichinterruptstheflowofexecutioninanapplication.

Becauseweareusingautomationtosupportourtesting,weshouldexpectourautomationcodetotriggeranomalousandexceptionalbehaviour.Ourautomationcodewillencounterbugsandunexpectedsituationsandwehavetobeabletohandlethem.

Wealsouseexceptionsinourabstractionstoletthecallingautomationcodeknowthatsomethingunexpectedhashappened.

Automationcodeisverydifferentfromapplicationcodeinthatweoftenwantexceptionstoshowthemselvesandcauseour@Testmethodstofail.

Inapplicationcodewerarelywantexceptionstomanifestbecausetheyslowthewholesystemdownandcreateapooruserexperience.

Whatisanexception?NormallyJavacodeproceedsfromonestatementtothenexte.g.StringageAsString=age.toString();

Page 126: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

StringyourAge=

"Youare"+ageAsString+"yearsold";

IntheabovecodeJavawould:

callthemethodtoStringontheagevariableassignthereturnvaluefromtoStringtotheageAsStringvariablebuildaStringfromtheconstant"Youare",thevariableageAsString,andtheconstant"yearsold"assignthatStringtotheyourAgevariable

Alloftheabovecodewouldexecutioninsequence.

Anexceptionisawayofinterruptingthenormalflowofexecutionwhensomethinggoeswrong.

Whenanexceptionoccursthecurrentstatementisterminatedandtheexecutionflowstops.Ifthereisnoprogramcodetocatchandhandletheexceptionanywhereinthesequenceofcallingcodethentheexceptionwillterminatetheprogram.

Whatdoesanexceptionlooklike?Thesimplestwayofunderstandinganexceptionistoseeoneinaction.

Ihavecreatedapackageinsrc\test\javacalled:packagecom.javafortesters.chap011exceptions.examples;

AndaddedaJUnittestclasscalledExceptionsExampleTest.

Iwilladdallmy@Testannotatedmethodsintothisclass.

Thefollowingcode,whenannotatedwith@Test,willcauseaNullPointerExceptiontobethrown.

Runitandsee:publicvoidthrowANullPointerException(){

Integerage=null;

StringageAsString=age.toString();

StringyourAge=

"Youare"+ageAsString+"yearsold";

assertEquals("Youare18yearsold",yourAge);

}

Intheabovecode,youcanseethatIforgottoassignavaluetotheIntegerage,anditissettonull.SowhenItrytocallthetoString()methodonage,JavathrowsaNullPointerException.

Inthiscasethethrownexceptionisgoodforus,becauseweseethatwemadeamistakeinourcoding,andwecanfixitbyassigningavalue,i.e.18,totheagevariable.

Theexceptionreportiswrittentotheconsole:

Page 127: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

1java.lang.NullPointerException

2atcom.javafortesters.exceptions.ExceptionsExampleTest.

3throwANullPointerException(ExceptionsExampleTest.java:15)

4atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)

5...

6atorg.junit.runners.ParentRunner.run(ParentRunner.java:309)

7atorg.junit.runner.JUnitCore.run(JUnitCore.java:160)

8atcom.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs

9(JUnit4IdeaTestRunner.java:77)

10atcom.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart

11(JUnitStarter.java:195)

12atcom.intellij.rt.execution.junit.JUnitStarter.main

13(JUnitStarter.java:63)

14atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)

15atsun.reflect.NativeMethodAccessorImpl.invoke

16(NativeMethodAccessorImpl.java:57)

17atcom.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Intheaboveexceptionmessageyoucanseethecallstacktrace.Iremovedafewlinestoavoidclutteringthepage(representedby...inthelisting).

Eachoftheatlinesrepresentsacallandisanestedstepintheexecutionofthecode.Themostrecentcallisatthetop(lines2and3inthelisting).TheselinestellusthataNullPointerExceptionwasthrownonline15ofExceptionsExampleTest.java.throwANullPointerException(ExceptionsExampleTest.java:15)

Theneachoftheloweratlinesisanotherlevelwherethecodewasexecuted.BecauseweareusingJUnitandIranthecodefromtheIDE,therearealotofstepsinvolved.

Workingfromthebottomupyoucanseethat:

line17:anapplicationmainmethodwascalledfromIntelliJAppMain.java:120

lines14-16:variousreflectionmethodswerecalledtostartthecodeNativeMethodAccessorImpl.java:57

lines10-13:JUnitwascalledJUnitStarter.java:63

lines8&9:JUnitstartedaJUnitrunnertorunthe@TestmethodJUnit4IdeaTestRunner.java:77

lines5-9:thentherewereabunchoflinesallrelatedtostartingandexecutingthemethodlines1-3:beforeourcodefailedonline15

ExceptionsExampleTest.java:15

Tobehonest,Idon’tfullyunderstandallthelinesinthatstacktrace.ButIcanlookatthemandmakearoughguesswhatishappeningandIcanseethemostimportantparts.

Thestacktraceisusefulbecauseitshowsthelinenumbersthatwereinvolvedincallingthecode,andforusthemostimportantisline3inthelisting.Wheretheline(15)inExceptionsExampleTest.javaisdescribedasthesourceoftheexception.Thishelpsusdebugthecodewhenanexceptionisthrown.

Page 128: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:FixtheNullPointerExceptioninthecodeAmendthecodetoassign18totheageandcheckthecoderunssuccessfullywithoutthrowinganexception.

CatchingExceptionsTherearesituationswhereweknowinadvancethatanexceptionmighthappen,andwewanttocatchtheexceptionandtakeactiontohandletheexception.e.g.wetrytoopenafile,butitdoesn’texist,sowecatchtheexceptionandthencreatethefile.

ThisiswherethetryandcatchkeywordsinJavahelpus.Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(NullPointerExceptione){

age=18;

ageAsString=age.toString();

}

Imadeafewchangestothecodetousethetrycatch:

declareStringageAsString;beforethetrydeclarethetypeofexceptiontocatch,inthiscaseaNullPointerException.takeactiontohandletheexceptioninthecatchblock.i.e.IassignedavaluetotheIntegerage.

IhavetodeclareStringageAsString;beforethetry.Youcanseethattryhasacodeblockdelimitedwith{and}.IfIdeclaredageAsStringwithinthatcodeblockitwouldonlybeaccessibleforcodewithinthetrycodeblock’s{and},andnotavailabletocodeinthecatchblockorafterthetryandcatchblocks.

InthecatchIhavetodeclarewhattypeofexceptionIwillcatch.InthiscaseIonlywanttocatchNullPointerExceptionssodeclareavariableeasaNullPointerException.

Inthecatchblock,IassumethatIhavereachedthiscodebecauseagewasnull,soIassignitavalueandrepeattheIntegertoStringconversion.SoIusethecatchblocktofixthecauseoftheexceptionandtakeactiontoallowtherestofthecodetoruntocompletion.

trycatchNotesCodeinthetryblockwillalwaysrun.Thecatchblockwillexecuteonlyifthedeclaredexceptionisthrown.Exceptionsthatarethrowninthecatchblockwillpropagateupthestacki.e.tocallingmethods.

Page 129: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thecodeinthetryblockwillalwaysberun.

Ifanexceptionisthrown,anditisofthetypedeclaredbythecatchblockthenthecodeinthecatchblockwillberun.

Ifanexceptionisthrownwithinthecatchblock.Thenitwon’tbere-caughtbecausethereisnotrycatchstatementsurroundingit.

IfadifferentexceptionisthrownthenitwillnotbecaughtbecauseIhavespecifiedthatonlyNullPointerExceptionwillbecaught.

Myfullcodelookslikethis:@Test

publicvoidcatchANullPointerException(){

Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(NullPointerExceptione){

age=18;

ageAsString=age.toString();

}

StringyourAge=

"Youare"+age.toString()+"yearsold";

assertEquals("Youare18yearsold",yourAge);

}

Exercise:UseadifferentexceptioninsteadofNullPointerExceptionReplaceNullPointerExceptionwithArithmeticException.

Whathappens?

Exercise:Don’tfixthecauseoftheexceptionRemovetheage=18;statementfromwithinthecatchblock.

Runthe@Testmethodandseewhathappens.

Exercise:CatchaCheckedExceptionUseNoSuchMethodExceptioninsteadofNullPointerException.

Whathappens?

AnExceptionisanobject}catch(NullPointerExceptione){

age=18;

Page 130: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ageAsString=age.toString();

}

YoucanseeinmycatchblockthatIdeclaredaparametereasaNullPointerException.

ThismeansthatwithinthecatchblockIhaveaccesstoalocalvariablee.Youcouldcallthisvariablewhateveryouwant,alotofpeoplestickwitheasaconvention.

eisanobjectoftypeNoSuchMethodExceptionsoIhaveaccesstoavarietyofmethodsonthisexception.Afewusefulmethodsare:

getMessage-showsmetheerrormessageassociatedwiththeexceptionsoIcanlogitgetStackTrace-anArrayofStackTraceElementobjectwithmethodcallsthatrevealthelinesofcodewhichleduptothethrowingoftheexception,whichcanhelpwithdebuggingprintStackTrace-whichprintsthestacktracetotheerroroutputstream-typicallyyourconsoleorcommandline

Exercise:UseExceptionasanobjectAddthefollowingcodeinyourcatchblock,runthe@Testmethod,andseewhatinformationyougetfromtheexceptionitself.

ThegetStackTracemethodreturnsanarrayofStackTraceElementobjects,investigatewhatthemethodsonthisobjectreveal.

System.out.println("getMessage-"+

e.getMessage());

System.out.println("getStacktrace-"+

e.getStackTrace());

System.out.println("printStackTrace");

e.printStackTrace();

CatchmorethanoneexceptionInthetrycatchcodeabove,Ionlycheckedforasingletypeofexception.

Thecatchblockcanberepeatedtowritecodethatcatchesmultipleexceptions.Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(NullPointerExceptione){

age=18;

ageAsString=age.toString();

}catch(IllegalArgumentExceptione){

System.out.println("IllegalArgument:"+

e.getMessage());

}

Page 131: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Intheabovecodesnippet,thecatchblockswillhandleeitheraNullPointerExceptionoranIllegalArgumentException.

JUnitandExceptionsJUnithasahandyfeaturetoallowustocheckforthrownexceptions.@Test(expected=NullPointerException.class)

Wecantellthe@Testannotationtoexpectanexceptionofaparticularclasstobethrown.

TheabovecodetellsJUnittoexpecttohaveanexceptionoftypeNullPointerExceptionthrownduringtheexecution.

IfnoNullPointerExceptionisthrownthenthemethodwillfail.

IfaNullPointerExceptionisthrownthenthemethodwillpass.

Forexample,thefollowingmethodpassesbecauseaNullPointerExceptionisthrown:@Test(expected=NullPointerException.class)

publicvoidnullPointerExceptionExpected(){

Integerage=null;

age.toString();

}

Becarefulwiththisparameterastheexceptioncouldbethrownanywhereinthemethodcodeandyourmethodwouldstillpass,sowhenyouusethisparametermakesurethatyourcodeisassmallaspossibletotriggertheexceptionandyouhaveother@Testmethodswhichensurethatthesetupcodeworks.Afterall,ifyoursetupcodethrewaNullPointerExceptionthenthemethodwouldpass,butwouldnothavecheckedwhatyouwanted.

ThrowinganExceptionWearenotlimitedtocatchingtheexceptionsfromcodethatotherpeoplehavewritten.Wecanalsothrowexceptionswhenweneedto.

AsanexampleofthisIwillrevisittheabstractionlayerwehaveforusers,wherewewereabletoconstructauserbypassingintheusernameandpassword.

Iwillamendthissothatthepasswordischeckedandtheconstructorwillthrowanexceptionifthepasswordislessthan7charactersinlength.

I’llre-usethesetPasswordmethodintheconstructorwithparameterssothatIonlyhavetoaddthevalidationrulecheckinginthesetPasswordmethod.publicUser(Stringusername,Stringpassword){

this.username=username;

setPassword(password);

}

ThenfinallyIwritecodetoimplementthepasswordvalidationlengthchecking.publicvoidsetPassword(Stringpassword){

if(password.length()<7){

thrownewIllegalArgumentException("Passwordmustbe>6chars");

Page 132: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

}

this.password=password;

}

Toexplainthisinmoredetailwewilllookatthepasswordlengthcheck.if(password.length()<7){

thrownewIllegalArgumentException("Passwordmustbe>6chars");

}

TovalidatethelengthofthepasswordIcheckthelengthoftheString.Ifthelengthis<7(lessthanseven).thrownewIllegalArgumentException("Passwordmustbe>6chars");

Sinceanexceptionisanobject,IhavetocreateanewinstanceofanIllegalArgumentException.Andthethrowkeywordisimportantbecausethisiswhatcausestheexceptiontointerrupttheflowofexecution.

AlsonotethatwhenIcreatethenewexceptionIaddanexplanatorymessage.Thisaddsadditionalinformationtothestacktracetohelpanyonedebugthecode.Theerroroutputforthisexception,ifitwasnotcaughtandhandledlooksasfollows:java.lang.IllegalArgumentException:Passwordmustbe>6chars

atcom.javafortesters.domainentities.interim.exceptions.User.setPassword

(User.java:29)

atcom.javafortesters.domainentities.interim.exceptions.User.<init>

(User.java:19)

atcom.javafortesters.exceptions.UserPasswordExceptionsTest.

passwordMustBeGreaterThan6Chars(UserPasswordExceptionsTest.java:22)

...

YoucanseefromtheaboveerrormessageoutputthatthefirstthinginthestacktraceistheexplanatorytextthatIaddedwhenIthrewtheexception.

Throwingexceptionsinyourabstractionlayersisausefulwaytokeepthecodesimpleandclean,andhelpavoidmakingsimpleerrorsinyour@Testmethods.

finally

Sometimeswewanttotryanddosomething,catchandhandleanyexceptions,andthenfinally,alwaysexecutesomecode.try{

//tryanddosomething

}catch(NullPointerExceptione){

//handletheexceptionhere

}finally{

//performthecodehere

//regardlessofwhetheran

//exceptionwasthrownornot

}

Inthefollowingcode,thefinallyblockisusedtoassignavaluetotheyourAgevariable:@Test

publicvoidtryCatchFinallyANullPointerException(){

Page 133: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Integerage=null;

StringageAsString;

StringyourAge="";

try{

ageAsString=age.toString();

}catch(NullPointerExceptione){

age=18;

ageAsString=age.toString();

}finally{

yourAge="Youare"+age.toString()+"yearsold";

}

assertEquals("Youare18yearsold",yourAge);

}

Thefinallyblockismainlyusedwhenwewanttore-throwanexception,butbeforewelosecontroloverthecodeexecutionwewanttotidyupresources.

Inthefollowingcode,insteadoffixingtheage,Ire-throwtheNullPointerExceptionasanIllegalArgumentException.

IfIdidnotaddthefinallyblock,assoonasIthrowtheIllegalArgumentException,nomorecodeinthismethodwouldbeexecuted.BecauseIaddedthefinallyblock,theIllegalArgumentExceptionisthrown,butbeforecontrolispasseddownthecallstack,thecodeinthefinallyblockisexecuted:@Test(expected=IllegalArgumentException.class)

publicvoidexampleTryCatchFinally(){

Integerage=null;

try{

System.out.println("1.generateanullpointerexception");

System.out.println(age.toString());

}catch(NullPointerExceptione){

System.out.println("2.handlenullpointerexception");

thrownewIllegalArgumentException

("NullpointerbecameIllegal",e);

}finally{

System.out.println("3.runcodeinfinallysection");

}

}

Whichgeneratesthefollowingoutput:11.generateanullpointerexception

22.handlenullpointerexception

33.runcodeinfinallysection

4

5java.lang.IllegalArgumentException:NullpointerbecameIllegal

6atcom.javafortesters.exceptions.ExceptionsExampleTest.

7exampleTryCatchFinally(ExceptionsExampleTest.java:144)

8atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)

9...26more

Page 134: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Youcanseefromtheabovethat:

thetryblockexecuteswecatchtheNullPointerExceptionwethrowanIllegalArgumentExceptionsinceweareabouttolosecontroloftheexecutionduetotheIllegalArgumentException,thefinallyblockexecutestheIllegalArgumentExceptionistriggeredandtheflowofexecutionisinterrupted.

SummaryYouwillhavetohandleexceptionswhenyouwriteautomationcodebecausemanyofthelibrariesyouusewillthrowexceptionstoalertyouofunexpectedevents.

Wewillrevisitexceptionsinafuturechaptersoyoulearnhowtocreateyourownexceptions.

WhenwritingabstractionlayersforautomationItrynottoputassertsinmyabstractionlayers,ratherIthrowexceptionssothatthe@Testannotatedmethodcaneitherpropagatethem,orcatchandhandlethem.

ReferencesandRecommendedReading

Exceptionsdocs.oracle.com/javase/tutorial/essential/exceptions

OfficialDefinitionofanExceptiondocs.oracle.com/javase/tutorial/essential/exceptions/definition.html

StackTraceElementdocs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html

Page 135: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTwelve-IntroducingInheritance

ChapterSummaryInthischapteryouwilllearnabriefoverviewofInheritance:

AnObjectcaninheritfromanotherObjectstoreusecodeAnObjectcanre-implementinheritedmethodsYoucanre-usecodethroughcomposition,aswellasinheritanceusethekeywordextendsinJavatoinheritfromaClass

BeforeweprovidemoreinformationaboutExceptionswehavetoprovideanoverviewofInheritanceandhowyouuseJavatoextendotherclasses.

InheritanceInheritanceisanObject-orientedDesignconcept.Javaprovidesanimplementationofsomeinheritancefeatures.Inthischapteryouwillreceiveaverybriefoverviewofinheritance,mainlysothatyouunderstandsomeofthemechanismsthatJavaprovides,andtohelpyouunderstandsomeofthemoreadvancedsectionsasweworkthroughthebook.

Ihavecoveredinheritancelateinthebookbecauseyoudon’treallyneeditfortheearlypartsofthisbook.Thebookstartedbyhavingyou‘use’Java.Youdidn’treallyneedtoextendanyclasses.

WhenwestartcreatingourownExceptionclasses,thenwewillneedtoextendotherclasses,soweneedtounderstandtheJavaconceptofInheritance.

YouhaveseenthatJavaClasseshavemethodsandfields.Andthatthosemethodsandfieldscouldbemadepublicorprivate.

Inheritanceprovidesonewayofallowingustore-usethosemethodsinotherclasses.

Wemakeoneobjectinheritfromanotherbyuseoftheextendskeyword.importcom.javafortesters.domainentities.User;

publicclassEmptyUserextendsUser{

}

Intheaboveexample,theEmptyUserobjectinheritsfromtheUserobject.

AnypublicmethodsontheUserobject,are‘inherited’bytheEmptyUserobject,soyou,asaprogrammer,donothavetowritethosemethods.

IfyouwanttheEmptyUsertohaveadifferentimplementationofanyofthosemethodsthenyoucanimplementthemethodinEmptyUserandoverridethemethodinheritedfromUser.

Page 136: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

YoucanseefromthepreviouscodethatEmptyUserhasnocodeinthebodyoftheclass,butIcanuseitinan@Testmethod,becauseit‘inherits’themethodsfromtheUserobject.@Test

publicvoidemptyUserExampleTest(){

EmptyUserenu=newEmptyUser();

assertEquals("username",enu.getUsername());

assertEquals("password",enu.getPassword());

}

AtthispointtheEmptyUseroffersthesamefunctionalityastheUser.

InheritanceorCompositionInheritanceisanObject-orientedDesigntechnique,andrepresentsan‘isa’relationship.Sowhenweextendanobjectwearereallysayingthatthenewobject‘isa’typeofobjectthatweareextending.

CompositionisanObject-orientedDesigntechnique,andrepresentsa‘hasa’relationship,sooneobject‘has’someotherobject(s)e.g.abottlehasatop.

Object-orientedDesignisbeyondthescopeofthisbook(seethereferencessectionformoredetail).ButitisimportanttounderstandthatsomeofJavafunctionality,implementsObject-orientedconcepts.

Inheritance

InheritanceisanObject-orientedDesigntechnique,andrepresentsan‘isa’relationship.Whenweextendanobjectwearereallysayingthatthenewobject‘isa’typeofobjectthatweareextending.

e.g.SuperWidget‘isa’Widget,EmptyUser‘isa’User

Ifweuseinheritanceonlybecausewewanttore-usecodethenweruntheriskthatwemakeourcodehardertore-use,maintainandunderstand,becauseJavasupportssingleinheritancei.e.youcanonlyextendoneobject.Ifyoulaterwantto‘change’thesuperclass(theclassweextend)thenthiscanbehardtodowithoutextensivechangesinyourcode.

Note,thefollowingexampleisaterribleexample,nevereverdosomethinglikethefollowinginyourcode.WhileitisfunctionallypossibletoextendprettymuchanyotherClass,thatdoesnotmeanweshoulddoso.Seethelatersectionsinthischapterforguidance.Butjusttoreiterate-neverdothefollowing:

Forexample:ImaydecidethatIwanttheUsertobeabletoreturntheURLthattheyareusing,currentlyIhavethisintheTestAppEnvobject.Icouldre-usethecodeinTestAppEnvbyhavingtheUserobjectextendtheTestAppEnv.ThentheUserobjectinheritsagetUrlmethod.

UnfortunatelyaUserisnotaTestApplicationEnvironment,sowhilethismightseemlikeausefulshortcuttore-usesomecode,Idonotconsideritagoodideainpractice.

BecauseaUserisnotaTestAppEnv,extendingTestAppEnvtore-usecodewillleadtocodewhichreliesonunrelatedObjects,andifyoudothisthroughoutyourcodebase,it

Page 137: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

willeventuallybecomeunmaintainable,andunreadable,andchangesinoneareaofthecodewillhaveunexpectedconsequencesinotherareasofthecode.

Composition

VeryoftenIdon’tuseInheritanceinmycode.Icodeusing‘composition’and‘interfaces’.Thisbasicallymeans,implementinginterfaces,andembeddingotherobjectswithinmycodeandgainingre-usebyusingtheirmethods.

Forexample,:IfIdidwantagetUrlmethodinmyUserthenImightfindawaytore-useaTestAppEnvobjectinmyUserobject.IftheTestAppEnvobjectrequiredinstantiationthenIwouldinstantiateitintheUserconstructor.ThenIwouldaddagetUrlmethodtomyUser,butthemethodactuallycallsthegetUrlontheTestAppEnv.

Exercise:CreateaUserthatiscomposedofTestAppEnvTryandimplementtheaboveUserobject,sothattheUser‘isa’Userobject,whichalsohasagetUrlmethod,wheretheimplementationofthatmethodisachievedbydelegatingtoaTestAppEnvobject.

UsingInheritanceAbetterexamplefortheuseofinheritance,givenourcurrentsmallnumberofdomainabstractionobjects,mightbetocreateanAdminUser.

Assumingthatthesystemundertesthasdifferenttypesofusers,andthatAdminusershavedifferentpermissionsfromanormalUser.IcouldaddagetPermissionleveltotheUser.

Thefollowingcodewouldcheckforthis:@Test

publicvoidaUserHasNormalPermissions(){

UseraUser=newUser();

assertEquals("Normal",aUser.getPermission());

}

ThenIcouldimplementthegetPermissionmethodonUser.publicStringgetPermission(){

return"Normal";

}

TocreatetheAdminUserIwoulddeclaretheAdminUserclassasaclasswhichextendsUser.publicclassAdminUserextendsUser{

Andre-implementthegetPermissionmethodinAdminUser,toreturnadifferentvalue.publicStringgetPermission(){

return"Elevated";

}

IalsohavetocreatetheconstructorsformyAdminUser:publicAdminUser(){

this("adminuser","password");

Page 138: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

}

publicAdminUser(Stringusername,Stringpassword){

super(username,password);

}

NotethatIcallthesuperconstructor,whichcallstheconstructoronUser(thesuperclass)

IcouldchecktheAdminUserasfollows:@Test

publicvoidanAdminUserDefaultConstructor(){

AdminUseradminUser=newAdminUser();

assertEquals("adminuser",adminUser.getUsername());

assertEquals("password",adminUser.getPassword());

assertEquals("Elevated",adminUser.getPermission());

}

@Test

publicvoidanAdminUserHasElevatedPermissions(){

AdminUseradminUser=newAdminUser("admin","Passw0rd");

assertEquals("admin",adminUser.getUsername());

assertEquals("Passw0rd",adminUser.getPassword());

assertEquals("Elevated",adminUser.getPermission());

}

Inalloftheabovenotethat,Ididn’thavetorewritethegetUsernameorgetPasswordmethods,sinceweinheritedthosefromUserwhenweextendedit.

Onelastthingtonote.Ishouldreallyaddthe@OverrideannotationtothegetPermissionmethod.ThistellsthecompilertocheckthatthegetPermissionmethodisreallyontheUserobjectandisstillthesamedeclaration.Thishelpsfindanysimpleerrorsatcompiletime,ratherthanruntime.

SomyfinalAdminUserclasslooksasfollows:publicclassAdminUserextendsUser{

publicAdminUser(){

this("adminuser","password");

}

publicAdminUser(Stringusername,Stringpassword){

super(username,password);

}

@Override

publicStringgetPermission(){

return"Elevated";

}

}

Exercise:CreateaReadOnlyUserCreateaReadOnlyUserwhichhasthepermissionReadOnly,withthesamedefault“username”and“password”fromUser.

Page 139: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

InheritfromInterfacesandAbstractClassesInproductionJavacode,acommonrecommendationistocodetoInterfaces.RatherthanInheritance.

Wehaven’treallycoveredInterfacesindetailinthisbook,becauseI’mtryingtogetyouupandrunningfast.

ButyousawthisconceptwhenusingCollections.

Collectionsarebasedaroundinterfaces.

TheCollectionsthemselvesimplementinterfaces,andextendAbstractClasses.

Sinceyoudon’treallyneedtoworryaboutthisuntilyouhavealargercodebase,andhavemorefamiliaritywithJava,Ihavedelegateddiscussionofthisintothe“AdvancingConcepts”chaptertowardstheendofthebook.

SummaryInheritancecanbeusedasa‘codere-use’tool,butitisbetterusedtoconstructobjectswhichhavean‘isa’relationship.

Whenwere-implementamethodfromthe‘super’classthatweextendthenweannotatethemethodwith@Overridetomakeitcleartootherpeoplewhatwehavedone,andwegainsomecompiletimecheckingofouractions.

Wecanaddnewmethodsintotheclasswhichisinheritingandthesewillnotbeaddedtothesuperclass.

Anynewmethodsinthesuperclasswillautomaticallybemadeavailabletotheextendingclass.

Privatemethodsandfieldsarenotaccessiblethroughinheritance,onlythesuperclass’sprotectedandpublicfieldsandmethodsareaccessiblethroughinheritance.

ReferencesandRecommendedReading

ObjectOrientedDesignConceptsdocs.oracle.com/javase/tutorial/java/concepts

InheritanceorCompositionDiscussionen.wikipedia.org/wiki/Composition_over_inheritance

ObjectOrientedProgrammingConceptsen.wikipedia.org/wiki/Object-oriented_programming

Page 140: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterThirteen-MoreAboutExceptions

ChapterSummaryInthischapteryouwilllearnmoreaboutexceptions:

UncheckedExceptionCheckedExceptionTheExceptionInheritancehierarchyHowtocreateyourownException

Afterthischapteryouwillbeabletousecodethatotherpeoplehavewrittenwhichthrowexceptionsandcreateyourownexceptionstoaddintoyourownabstractionlayers.

UncheckedandCheckedExceptionsAlltheexamplesyouhaveseensofarinthebookhavebeenuncheckedexceptions.

AnUncheckedexceptionisonethatcanbethrown,byamethod,withouthavingtodeclarethattheexceptionwillbethrown.Acheckedexception,hastobedeclared,andgenerallyrepresentsaparticularusecasethat,while‘exceptional’stillhastobeexplicitlyhandled,ordeliberatelyignoredbythecallingcode.

UncheckedExceptionsUncheckedexceptionscanbitewithoutyouknowingtheywilloccur.YousawanexampleofthisintheearlierchapterswiththeNullPointerException.

AnUncheckedExceptionisalsoknownasaRuntimeException,asyouareonlymadeawareofthematruntime.

IfyouwanttocreateanUncheckedexceptionyouextendRuntimeExceptionoranyoftheclasseswhichalreadyextendit.

e.g.

IllegalArgumentException

ArithmeticException

NoSuchElementException

etc.

Idon’tthinkIhaveevercreatedacustomexceptionthatextendedanUncheckedexception.GenerallywhenIcreatecustomexceptionsIwantpeopletobeawareofthemandhandlethemintheircode.

Page 141: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IfIdowanttothrowanuncheckedexceptionIwillfirstofalltryanduseoneofthestandardjava.languncheckedexceptions.

Forexampleyousawtheuseofajava.languncheckedexceptionwhenweaddedtheexceptiontothepasswordvalidationinUserIusedtheIllegalArgumentExceptionbecauseIwasvalidatingaparametertoamethod.

ItmightbeappropriatetocreatemyownuncheckedexceptionsifIwanttoallowcodetodistinguishbetweenexceptionsthattheabstractionlayerhasthrownatruntime,andthoseexceptionsthrownbytheJavaruntime.

CheckedExceptionsYouwillbeinformedabouttheneedtohandlecheckedexceptionsatcompiletimebecauseacheckedexceptionwillbedeclaredasbeingthrownbythemethoddeclaration.

Forexample,IcoulddeclarethesetPasswordmethodonUserasthrowinganInvalidPasswordexception(assumingthatInvalidPasswordexceptionexisted,whichitdoesn’t,butitwillwhenwecometothe‘CreateyourownExceptionclass’sectionlaterinthischapter):publicvoidsetPassword(Stringpassword)throwsInvalidPassword{

Then,anywhereinthecodethatIusethesetPasswordmethodIeitherhaveto:

handletheexception,aswesawbeforeinatrycatchblock,orignoretheexceptionandallowittopropagateupwards

IgnoringCheckedExceptions

Thewaythatweallowanexceptiontopropagateupwardsistodeclarethemethodthatweare‘ignoring’themethodin,asthrowingthatparticularexception.

Forexample,sincetheUserconstructorcallssetPassword,Ieitherhavetohandletheexceptionor,asshownbelow,allowittopropagateupwards:publicUser(Stringusername,Stringpassword)throwsInvalidPassword{

this.username=username;

setPassword(password);

}

Handlingcheckedexceptionsindefaultconstructor

IfIcallaconstructorfromanotherconstructore.g.this("username","password");

Thenthefirststatementintheconstructorhastobethethiscall.WhichmeansthatIcannotwrapthatcallwithatrycatch.

Ihavetofindadifferentwayofdelegatingtheconstructioncall.InthiscodeIchosetochangethedefaultconstructorsothatitcallsaprivateconstructor.publicUser(){

this("username","password",false);

}

privateUser(Stringusername,Stringpassword,booleanb){

Page 142: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

//onlycallthisbecausewedon'twanttothrowtheexception

this.username=username;

try{

setPassword(password);

}catch(InvalidPassworde){

thrownewIllegalArgumentException(

"Defaultpasswordincorrect",e);

}

}

ThiswayIensurethatanyoneusingtheno-argumentconstructordoesn’thavetohandleanInvalidPasswordexceptionforahardcodedpassword.@Test

publicvoidcanCreateDefaultUserWithoutHandlingException(){

UseraUser=newUser();

assertEquals("username",aUser.getUsername());

assertEquals("password",aUser.getPassword());

}

Buttheystillhavetohandletheexceptioniftheyusetheconstructorwheretheusernameandpasswordarepassedinbytheprogrammer.@Test

publicvoidhaveToCatchIllegalPasswordForParamConstructor(){

try{

UseraUser=newUser("me","wrong");

fail("Anexceptionshouldhavebeenthrown");

}catch(InvalidPasswordinvalidPassword){

assertTrue("Theexceptionwasthrown",true);

}

}

NotethatintheabovecodeIusedfailfromJUnittocausethe@Testmethodtofailifwedidnotthrowanassertionaftercreatingtheuser.Withoutthefailcall,themethodwouldhavepassedifanexceptionhadnotbeenthrown,eventhoughthemethodhadactuallyfailed.Beverycarefulwhenworkingwithexceptionsasyouneedtomakesurethatyoudon’thave‘falsepositives’i.e.an@Testmethodpassing,whenitshouldhavefailed.

DifferencebetweenException,ErrorandThrowableJavahasanExceptionhierarchy:

Throwable

Error

Exception

RuntimeException

TherootobjectisThrowable,andbothErrorandExceptionextendthis.

ErrorisreservedforseriousJavaplatformerrors.ThegeneralguidanceprovidedtoJavaprogrammersis“nevercatchaJavaError”,whichalsomeansweshouldnevercatchaThrowable.

IfwewanttocatchagenericruntimeexceptionthenweshouldcatchRuntimeExceptionbecauseanyruntimeexceptionsweraisewillderivefromRuntimeException.

Page 143: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MostofourExceptionswillderivefromeitherExceptionoraclassthatalreadyextendsException.WewillrarelyderivefromThrowableandneverderivefromError

CreateyourownExceptionclassThroughoutthischapteryouhaveseenreferencetoacustomexceptioncalledInvalidPassword.

ThereisnomagicaroundthisclassanditisaverysmallpieceofcodewhichimplementsaclassthatextendsException.publicclassInvalidPasswordextendsException{

publicInvalidPassword(Stringmessage){

super(message);

}

}

CreatingyourownexceptionallowsyoutoaggregatemultipleJavaexceptionsintoasinglecontextspecificexception.

Forexample,IcouldcatchIllegalArgumentException,NullPointerException,etc.andthrowanIllegalPasswordexceptionsothatcodeusingmyabstractionlayeronlyhastohandleasmallsetofexceptions.

Exercise:CreateanInvalidPasswordexceptionTohelppeopleusetheUserdomainobject:

createtheInvalidPasswordexceptionmaketheInvalidPasswordexceptiondescribethevalidationrulesaroundpasswordi.e.“Passwordmustbe>6chars”write@Testmethodsthatcheck:

theInvalidPasswordexceptionisthrownonsetPasswordtheInvalidPasswordexceptionisthrownintheconstructortheInvalidPasswordexceptionisnotthrowninthedefaultconstructortheerrormessagethrownbytheexceptioncontainsthetext“Passwordmustbe>6chars”

SummaryInthischapteryousawhowtocreateandthrowacustomexception.Customexceptionsareusefulwhencreatingabstractionlayersbecausewedonotneedtocreatealotofreturncodes,wecanthrowtheexceptionsinstead.

Customexceptions‘help’peopleusingourclasses,toalertthemtovalidationandexceptionsthattheymightencounterusingtheclass.Wecandothisthroughdocumentation,andwecandothisthroughcustomCheckedexceptions.

Bycreatingacustomcheckedexceptionwealertpeopleastheywritethecode,tothevalidationandusagerulesofourclass.IfwecreateacustomRuntimeExceptionthenweneedtorelyondocumentationtoalerttheuser.

Thefailmethodisveryusefulwhenwritingchecksforcustomexceptionsbecauseweneedtomakesurethatchecksdonotpassbecausetheexceptionwasnotthrowninour

Page 144: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Testmethod.

ReferencesandRecommendedReading

JavaExceptionsdocs.oracle.com/javase/tutorial/essential/exceptions

AlistofUncheckedExceptionsinJavalist4everything.com/list-of-unchecked-exceptions-in-java.html

Page 145: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterFourteen-JUnitExplored

ChapterSummaryInthischapteryouwilllearnmoreaboutJUnitfeatures:

@Test-annotateamethodasaJUnitTestassertEquals-assertthattwovaluesareequal@Test(expected=...)-expectaspecificexceptionclassthrownfail-forceamethodtofail@RuleforExpectedExceptiontocheckforexceptions@BeforeClass-runonce,beforeany@Testmethodsarerun@AfterClass-runonce,afterall@Testmethodshaverun@Before-runbeforeeach@Testmethod@After-runaftereach@Testmethod@Ignore-preventan@TestmethodfromrunningMoreJUnitassertions:

assertEquals-checkexpectedandactualareequalassertFalse-checkactualisfalseassertTrue-checkactualistrueassertArrayEquals-checkexpectedandactualarraysareequalassertNotNull-checkactualisnotnullassertNotSame-checkexpectedandactualaredifferentassertNull-checkactualisnullassertSame-checkexpectedandactualarethesame

Hamcrestmatchersforliterateassertions:assertThat-literateassertionusingHamcrestMatcheris-truewhenassertThat(x,is(y))equalTo-truewhenassertThat(x,equalTo(y))not-truewhenassertThat(x,is(not(y))containsString-truewhenassertThat(x,containsString(y))endsWith-truewhenassertThat(x,endsWith(y))startsWith-truewhenassertThat(x,startsWith(y))nullValue-truewhenassertThat(x,is(nullValue()))

WiththenewJUnitfeaturesyouwilllearninthischapteryouwillgaintheabilitytorefactorandremovecodeduplication,anduseagreaterrangeofassertionmethods.

@Test

WehavealreadyseenthatinorderforamethodtoberecognizedasaJUnittest,ithastobeannotatedwith@Test.@Test

publicvoidthisTestWillNeverFail(){

}

Amethodwillfailifanassertionfails,oranexceptionisthrowninthebodyofthemethodcode.

Youdonotneedtoadd‘test’intothenameofthemethod.UsuallyIdon’t,since‘Test’issomewhereintheclassname,andthisgivesmetheabilitytomakemymethodnamesas

Page 146: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

expressiveaspossible.

CheckingforExceptionsBecauseamethodwillfailifanexceptionisthrown.JUnitgivesustheabilitytocheckforexceptions,andmakean@Testmethodpass,onlywhentheexceptionisthrown.@Test(expected=...)

IfIwanttocheckthataparticularexceptionisthrownthenIcandeclareitintheexpectedparameter.@Test(expected=InvalidPassword.class)

publicvoidexpectInvalidPasswordException()throwsInvalidPassword{

Useruser=newUser("username","<6");

}

Notethatyour@Testmethodwillpassifanexceptionmatchingtheexpectedclassisthrownanywhereduringtheexecution.

WecanusetheExpectedExceptionruletobemorespecificabouttheexceptionswecountasapass.

ExpectedExceptionrule

JUnithastheconceptof‘rules’toextendandenhanceJUnit.Wewon’tcovermanyoftherulesavailableinthisbook.

TheExpectedExceptionruleallowsyoutobemorespecificabouttheexceptionandonlycountaparticularexceptionasapasswhen:

aparticularclassofexceptionisthrownanexceptionhasaparticularmessageanexceptionhasaparticularcauseanycombinationoftheabove

Thefollowingcodewouldhavethesameeffectasaboveannotatingwiththeparameterexpected:@Rule

publicExpectedExceptionexpected=ExpectedException.none();

@Test

publicvoidinvalidPasswordThrown()

throwsInvalidPassword{

expected.expect(InvalidPassword.class);

Useruser=newUser("username","<6");

}

YoucanseethatIaddan@Ruleasafieldintheclass,instantiatedwiththestaticnonemethodonExpectedException.@Rule

publicExpectedExceptionexpected=ExpectedException.none();

Page 147: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Inthe@TestmethoditselfIconfiguretheruletoexpectanInvalidPassword.class,bycallingtheexpectmethodontheExpectedExceptionobject.expected.expect(InvalidPassword.class);

Icanmakethecheckmorespecificbyspecifyingasubstringoftheexpectedmessage.Bydoingthis,mymethodwon’tpassifanInvalidPasswordexceptionisthrown,butwithadifferentmessage.expected.expect(InvalidPassword.class);

expected.expectMessage(">6chars");

Useruser=newUser("username","<6");

Thesubstring,canalsobeaHamcrestmatcher:expected.expectMessage(containsString(">6chars"));

Before&AfterJUnitprovidesannotationsforexecutingcodebeforeandafteranytestsarerun,andbeforeandaftereachtest.Thisallowsforsetupandcleanupofdataorenvironmentconditions.

@BeforeClass-runonce,beforeany@Testmethods@AfterClass-runonce,afterall@Testmethods@Before-runbeforeeach@Testmethod@After-runaftereach@Testmethod

Anymethodannotatedwith@BeforeClassor@AfterClasshastobedeclaredasastaticmethod:@BeforeClass

publicstaticvoidrunOncePerClassBeforeAnyTests(){

System.out.println("@BeforeClassmethod");

}

Methodsannotatedwith@Beforeand@Afterdonotneedtobestatic:@Before

publicvoidrunBeforeEveryTestMethod(){

System.out.println("@Beforeeachmethod");

}

Allmethodsneedtobepublic.

@Afterand@AfterClassarerun,regardlessofwhethertheprecedingmethodpassedorfailed.

@Ignore

Wecanannotatemethodswith@Ignoreandthe@Testannotatedmethodwillnotberun.@Ignore

@Test

publicvoidthisTestIsIgnored(){

No@Beforeor@Aftermethodwillbecalledfor@Ignoreannotatedmethods.

Page 148: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Wecanalsoaddatextparametertothe@Ignoretoprovideareasonforitsignoredstate.@Ignore("Becauseitisnotfinishedyet")

Whenyou@Ignoreamethod,Irecommendyouaddatextparametertodescribewhy,otherwisepeoplewillforget,andthemethodislikelytobedeleted.

JUnitAssertionsJUnithasitsownassertionsbuiltin:importstaticorg.junit.Assert.*;

JUnitassertionsmostlytaketheformofamethodname,withaparameterfortheexpectedresultandthenaparameterfortheactualresult,someonlytakeanactualvalueastheexpectedisinthenameoftheasserte.g.assertNull:assertEquals(6,3+3);

WithJUnitassertsyoucanalsoaddanoptionalmessagetodescribetheassertion:assertEquals("3+3=6",6,3+3);

Iftheassertionfailsthenthemessageiswrittenaspartofthemessagetomakeiteasiertoidentifytheprobleme.g.java.lang.AssertionError:3+3=6expected:<7>butwas:<6>

JUnitprovidesthefollowingassertions:

assertEquals-checkexpectedandactualareequalassertFalse-checkactualisfalseassertTrue-checkactualistrueassertArrayEquals-checkexpectedandactualarraysareequalassertNotNull-checkactualisnotnullassertNotSame-checkexpectedandactualaredifferentassertNull-checkactualisnullassertSame-checkexpectedandactualarethesame

IfIuseJUnitassertsinmyautomationcode,ImainlyuseassertEquals,assertFalseandassertTrue.

Exercise:Createan@TestmethodwhichusesalloftheassertsExperimentwiththeJUnitassertsbycreatingan@Testannotatedmethodwhichpasses,withalloftheaboveassertsinit.

JUnitalsoprovidesanassertThatassertionforusewithmatchers.

AssertingwithHamcrestMatchersandassertThatYoucanusetheassertThatmethodinconjunctionwithmatchers,e.g.fromHamcrest,tomakeyourcodemorereadable.

Page 149: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat

assertThat(3+3,is(6));

WhenanassertThatwithoutareasonfails,thentheoutputlookslikethefollowing:java.lang.AssertionError:

Expected:is<7>

but:was<6>

assertThatcanalsobegivena‘reason’message.assertThat("3+3=6",3+3,is(6));

IfanassertThatwithareasonfails,thentheoutputlookslikethefollowing:java.lang.AssertionError:3+3=6

Expected:is<7>

but:was<6>

SinceassertThatissoreadableinthecode,Itendnottoaddareason,andjustusethestacktracetofindthelinewiththeerrorinit.Youcanchooseyourownstyle.

HamcrestCoreMatchers

JUnithasadependencyonHamcrestcore,sowhenyouaddJUnitasadependencyintoyourprojectyoualsogetaccesstoHamcrestcore.

Hamcrestcoreprovidesasetof‘matchers’whichhelpuswriteliterateasserts,sothatourcodebecomesmorereadable.

Hamcrestcoreprovidesmatcherssuchas:

is-truewhenassertThat(x,is(y))equalTo-truewhenassertThat(x,equalTo(y))not-truewhenassertThat(x,is(not(y)))containsString-truewhenassertThat(x,containsString(y))endsWith-truewhenassertThat(x,endsWith(y))startsWith-truewhenassertThat(x,startsWith(y))nullValue-truewhenassertThat(x,is(nullValue()))

Thematcherscanbechainedtomakeliteratestatementse.g.assertThat("",is(not(nullValue())));

Page 150: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:ReplicatealltheJUnitAssertsusingassertThatCopythe@Testmethodyouwroteforalltheasserts.ThenrewritealltheassertstobeassertThatwithHamcrestMatchers.e.g.assertEquals(x,y)becomesassertThat(y,is(x))

Dotheaboveforalloftheassertsbelow:

assertEquals-checkexpectedandactualareequalassertFalse-checkactualisfalseassertTrue-checkactualistrueassertArrayEquals-checkexpectedandactualarraysareequalassertNotNull-checkactualisnotnullassertNotSame-checkexpectedandactualaredifferentassertNull-checkactualisnullassertSame-checkexpectedandactualarethesame

Exercise:UsealloftheHamcrestmatcherslistedCreatean@TestmethodwhichusesalloftheHamcrestmatcherslisted,tryandusethemincombinationwhereyoucantomaketheassertionsliterate.

is-truewhenassertThat(x,is(y))equalTo-truewhenassertThat(x,equalTo(y))not-truewhenassertThat(x,is(not(y)))containsString-truewhenassertThat(x,containsString(y))endsWith-truewhenassertThat(x,endsWith(y))startsWith-truewhenassertThat(x,startsWith(y))nullValue-truewhenassertThat(x,is(nullValue()))

HamcrestprovidesmorematcherswhichyoucanaccessifyouincludethefullHamcrestasadependencyinyourpom.xmlfile.e.g.<dependency>

<groupId>org.hamcrest</groupId>

<artifactId>hamcrest-all</artifactId>

<version>1.3</version>

</dependency>

ForinformationonthefullsetofHamcrestmatchersseetheHamcrestTutoriallinkinthereferencesforthischapter.

fail

JUnitprovidesafailmethodwhichcanbeusedtodeliberatelycauseamethodtofail.

Thiscanbecalledwithoutadescription:fail();

Orwithadescriptionparameter:fail("failalwaysfails");

Whenafailisissued,thenanAssertionErroristhrown.

Page 151: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

staticimportingThemainwayyouhaveseenJUnitassertionsusedsofarisbystaticallyimportingthemethodfromJUnit:importstaticorg.junit.Assert.assertEquals;

Sothatinthemain@Testmethodcodewecanwritetheassertiondirectly:@Test

publicvoidcanAddTwoPlusTwo(){

intanswer=2+2;

assertEquals("2+2=4",4,answer);

}

AnotherstyleofwritingJUnitassertionsthatyoumightsee,orchoosetoadopt,Assert.assertEquals("2+2=4",4,answer);

IntheaboveusageIhaveimportedtheAssertclassratherthanasinglemethod.importorg.junit.Assert;

Inthecontextofthe@Testmethoditwouldlookasfollows:@Test

publicvoidcanAddTwoPlusTwo(){

intanswer=2+2;

Assert.assertEquals("2+2=4",4,answer);

}

Yourpreferencemayvary.

IthinkthefirstapproachwithouttheAssert.prefixisoftenmorereadable.ButusingtheAssert.prefixoftenaidsmewhencodingbecauseIcanseethefullrangeofassertionsavailabletomewhenIuseIDEcodecompletion.

SummaryJUnitoffersmultipleassertionmethods.Trytousetherangeavailabletomakeyourassertionsexpressive,althoughitisoftenpossibletowriteallyourassertionsasassertTrueandassertFalse.Butthismeanspeoplereadingyourcodehavetoparsetheentireassertioncondition,ratherthanusetheassertmethoditselftohelpthemunderstandyourintent.

WecanstickwiththoseassertionsofferedbydefaultJUnit,orwecanchoosetousethoseprovidedbytheHamcrestimportsviatheassertThatassertion.

Hamcrestoffersmorematchersthanthoselistedinthischapter,soonceyouarefamiliarwiththeuseofassertThatinyourcode,readthroughtheHamcrestwebsiteandexperimentwiththeadditionalfeaturesinHamcrest.

Ideallywewouldwritecodewhichdoesmorethansimplyassert.Itshouldalsomaketheintentbehindthoseassertionseasytoreadandunderstandfromthecode.Andwecandothisbyusingacombinationofassertionandmatchermethods.

Page 152: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

YouwillgainalotofvaluefromexperimentingwiththeBeforeandAfterannotationstohelpyoustructureyourcodeandmovesetupandteardowncodetothecorrectlevel:

classlevel(@BeforeClassand@AfterClass),ormethodlevel(@Beforeand@After).

ReferencesandRecommendedReading

JUnithomepagejunit.org

JUnitExceptionCheckinggithub.com/junit-team/junit/wiki/Exception-testing

JUnitAssertionsgithub.com/junit-team/junit/wiki/Assertions

JavaHamcresthomepageithub.com/hamcrest/JavaHamcrest

HamcrestTutorialcode.google.com/p/hamcrest/wiki/Tutorial

Page 153: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterFifteen-StringsRevisited

ChapterSummaryInthischapteryouwillrevisitwhatyoualreadyknow,andlearnmoreaboutstrings:

Stringisanobjectwithmanyusefulmethod,notjustacontainerforcharactersSystem.out.println-printaStringtoconsoleSpecialcharactersencodedinstringusing\e.g.\t,\b,\n,\',\",\\Stringconcatenationusing+andtheconcatmethodConverttoaStringwiththetoStringmethodofmostobjectsConvertfromaStringtootherobjectsusingthevalueOfmethodConstructStringfromchar[],byte[],StringBuffer,StringBuilderandStringStringobjecthasmanycomparisonmethods:

.compareTo-returns0ifStringsareequal

.compareToIgnoreCase-sameascompareTo,butignoringcase

.contains-returnstrueifparameterisinString

.contentEquals-returnstrueifStringcontentequalstoparameter

.equals-returnstrueifcontentisequalandtheparameterisaString

.equalsIgnoreCase-sameasequalsbutignoringcase

.endsWith-returnstrueifendofStringequalsparameter

.startsWith-returnstrueifstartofStringequalsparameter

.isEmpty-returnstrueiflengthofStringis0

.indexOf-returnstheindexpositionofasubstring

.lastIndexOf-returnsthelastindexpositionofasubstring

.regionMatches-comparearegionofthesubstringtoaregionoftheString.matches-easytouseregularexpressionStringmatchingReplacesectionsofaStringwith.replace,.replaceAll,.replaceFirstCaseconversionusing.toUppercaseand.toLowercase.trim-toremovewhitespacefromString.substring-toreturnaportionofaString.format-tousesimplestringtemplates.split-toparseastringStringBuilder-buildstrings:append,delete,insert,replace,reverse

YouhavealreadyseentheuseofStringobjectsthroughoutthebook.

ThischapterwillpullallthatinformationtogetherintoasinglechapterbecausetheStringisanessentialobjecttousewhenbuildingour@Testmethodsandabstractionlayers.

Alotoffieldsonourobjectswillstartasstringse.g.username,password.Atsomepointwemightchoosetomakethemobjectsintheirownrightbecausethenwecanmakethemresponsiblefortheirownvalidation.

StringSummaryJustaquicksummaryofwhatwehavealreadylearned.

AStringisanobject,injava.langsowedon’thavetoworryaboutimportingit.StringaString="abcdef";

Page 154: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

AStringliteralisalsoanobject,sowecancallmethodsonaStringliteral.assertThat("hello".length(),is(5));

Wecanconcatenatestringswiththe+operator.assertEquals("123456","12"+"34"+"56");

AStringisimmutable.OnceaStringiscreated,wecan’tamendit,itmightlooklikeweareamendingit,butreallywearecreatinganewStringobject.

ThismeansthatJavacanre-usethesameStringvaluethroughoutourcode,soevenifwetypeaStringinmultipleplaces,itdoesn’ttakeupanymorememory.Ofcourse,weshouldnotusethisasanexcusetoduplicateStringliteralsthroughoutourcodeasthatcanmakeourcodehardertomaintain.

System.out.println

YouhaveseenSystem.out.printlnusedinearliercode,thisstatementallowsustowriteStringobjectstotheconsole.

Itisveryusefulwhentryingtogaininsightintoasectionofcodeandtogenerateadhocfilesorstringstopasteintoapplications.

Itcanbeusedasasimpleloggingtoole.g.forprintingoutprogressofexecutiontotheconsole,orprintingthevariablesusedasinputdata.

Thefollowingexampleshowsthisinaction:inti=4;

System.out.println("Printaninttotheconsole"+i);

Notethatintheexampleabove,theintisautomaticallyconvertedintoaStringandconcatenatedtothestringliteralwhenoutputas:Printaninttotheconsole4

SpecialcharacterencodingWeencounteredtheescapesequencesinanearlierchapter.

\t-atabcharacter\b-backspace\n-anewline\r-acarriagereturn\'-asinglequote\"-adoublequote\\-abackslash

Whenbuildingstringswehavetomakesureweescapethecharacterslike",and\otherwiseourstringswillfailtobuild.System.out.println("Bobsaid\"hello\"tohiscat'sfriend");

System.out.println("Thisisasinglebackslash\\");

Willoutput:

Page 155: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Bobsaid"hello"tohiscat'sfriend

Thisisasinglebackslash\

Exercise:TryusingtheotherescapecharactersExperimentwithsome@Testmethodswhichusetheotherescapecharactersinastringe.g."\t","\b","\n","\r"andseetheeffectwhenyouuseSystem.out.printlntoprinttotheconsoleoutput.

StringConcatenationWehavealreadyseen+asamethodofconcatenatingstrings.The+isalsousefulasawayofaddingprimitivesandotherobjectsontotheString.Stringps1="Thisis"+"String2";

assertThat(ps1,is("ThisisString2"));

Stringps2="Thisis"+4;

assertThat(ps2,is("Thisis4"));

TheStringclasshasaconcatmethodwhichallowsustoconcatenateotherstrings.ThisdoesnotallowustoconcatenateotherobjectsontotheString.StringthisIs="Thisis";

Strings1=thisIs.concat("String1");

assertThat(s1,is("ThisisString1"));

Convertingto/fromaString

ConvertingtoaStringwithtoStringMostclassesoverridethetoStringmethodtoprovideawayofcreatingaStringrepresentationoftheobject.

ThisprovidesausefulwayofconvertingtoaString,andthisisthemethodcalledwhenyouconcatenateaStringwithadifferenttypeusing+.

Forprimitivetypes,theassociatedobjectversionisusede.g.forinttheInteger.toStringisused.StringintConcatConvert=""+1;

assertThat(intConcatConvert,is("1"));

StringintegerIntConvert=Integer.toString(2);

assertThat(integerIntConvert,is("2"));

TheStringclassitselfhasthevalueOfmethodwhichtakesobjectsandprimitivesandconvertsthemtoaString.Forobjects,theobject’stoStringmethodisusedfortheconversion.StringintegerStringConvert=String.valueOf(3);

assertThat(integerStringConvert,is("3"));

Inadditionyoucanconvertfrombyte[]andchar[](andotherobjects)toaStringusingtheStringconstructor.

ConvertingfromaString

Page 156: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ManyobjectshaveavalueOfmethodwhichcanconvertthevalueoftheStringtotheassociatedobject.e.g.Integer,Float,etc.assertThat(Integer.valueOf("2"),is(2));

TheStringobjectalsohasatoCharArraytoconverttoaCharacterarray.char[]cArray={'2','3'};

assertThat("23".toCharArray(),is(cArray));

WecanconvertaStringtoabytearrayusingthegetBytesmethod.byte[]bArray="hellothere".getBytes();

Convertingtobytesfromstringscanbeproblematicifwewanttomoveourcodebetweendifferentmachinesastheymayhaveadifferentdefaultcharactersetorcharacterencoding.

WhenweconvertbetweenbyteandStringwemayneedtocontroltheencoding.IfweuseanincorrectencodingthenanUnsupportedEncodingExceptionwillbethrown:@Test

publicvoidcanConvertBytesUTF8()throwsUnsupportedEncodingException{

byte[]b8Array="hellothere".getBytes("UTF8");

}

ConstructorsWecanconstructanewStringwithnoargumentstocreatea0lengthString.Stringempty=newString();

assertThat(empty.length(),is(0));

Orwithargumentstoconstructfrom:

String

char[]-anarrayofcharbyte[]-anarrayofbyteStringBuffer-amutableStringStringBuilder-amutableString

e.g.char[]cArray={'2','3'};

assertThat(newString(cArray),is("23"));

Exercise:ConstructaStringConstructaStringfromaString,char[],andbyte[].

Experimentwiththedifferentcombinationsofparameters.

ComparingStringsStringprovidesmanymethodsforcomparisonandsearching:

Page 157: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

.compareTo-returns0ifStringsareequal

.compareToIgnoreCase-sameascompareTo,butignoringcase

.contains-returnstrueifparameterisinString

.contentEquals-returnstrueifStringcontentisequaltoparameter

.equals-returnstrueifcontentisequalandtheparameterisaString

.equalsIgnoreCase-sameasequalsbutignoringcase

.endsWith-returnstrueifendofStringequalsparameter

.startsWith-returnstrueifstartofStringequalsparameter

.isEmpty-returnstrueiflengthofStringis0

.indexOf-returnstheindexpositionofasubstringinaString

.lastIndexOf-returnstheindexpositionofasubstringsearchingfromtheendoftheStringforwards.regionMatches-comparearegionofthesubstringtoaregionoftheString

compareTo&compareToIgnoreCasecompareTocomparestheStringyoucallthemethodon,withaStringparameter:

IfthetwoStringsareequalthencompareToreturns0Stringhello="Hello";

assertThat(hello.compareTo("Hello"),is(0));

IftheargumentStringissmallerthantheStringthencompareToreturnsanegativenumberassertThat(hello.compareTo("hello")<0,is(true));

assertThat(hello.compareTo("Helloo")<0,is(true));

assertThat(hello.compareTo("Hemlo")<0,is(true));

IftheargumentStringislargerthantheStringthencompareToreturnsapositivenumberassertThat(hello.compareTo("H")>0,is(true));

assertThat(hello.compareTo("Helln")>0,is(true));

assertThat(hello.compareTo("HeLlo")>0,is(true));

Notethatlargermeansbothlongerlengthor,acharacterdifference.Similarlysmallermeanssmallerlength,oracharacterdifference.

compareToIgnoreCaseusesthesamelogicascompareTobutthecaseofthelettersisignorede.gassertThat(hello.compareToIgnoreCase("hello"),is(0));

assertThat(hello.compareToIgnoreCase("Hello"),is(0));

assertThat(hello.compareToIgnoreCase("HeLlo"),is(0));

contains

ThemethodcontainsreturnstrueiftheparameterStringiscontainedwithintheString.ThevaluetruewillalsobereturnediftheparameterStringequalstheString.Stringhello="Hello";

assertThat(hello.contains("He"),is(true));

assertThat(hello.contains("Hello"),is(true));

Caseisimportantwhenusingcontains:assertThat(hello.contains("he"),is(false));

Page 158: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThevaluefalseisreturnediftheparameterisnotcontainedwithintheStringassertThat(hello.contains("z"),is(false));

contentEquals&equals&equalsIgnoreCaseThemethodcontentEqualsreturnstrueiftheStringhasthesamecontentastheparameterandfalseifitdoesnot.Stringhello="Hello";

assertThat(hello.contentEquals("Hello"),is(true));

assertThat(hello.contentEquals("hello"),is(false));

ThecontentEqualsmethodwillworkwithanyobjectthatimplementstheCharSequenceinterface,oragainstaStringBuffer(e.g.aStringBuilder).

TheequalsmethodenforcestheadditionalrulethattheparametermustbeaString,aswellashavingequalcontent.

TheequalsIgnoreCasemethodworksthesameasequalsbutignoresthecaseinthecomparison.assertThat(hello.equalsIgnoreCase("hello"),is(true));

endsWith&startsWithTheendsWithmethodcomparestheendoftheStringtotheparameter.Stringhello="Hello";

assertThat(hello.endsWith("Hello"),is(true));

assertThat(hello.endsWith(""),is(true));

assertThat(hello.endsWith("lo"),is(true));

ThestartsWithmethodcomparesthestartofStringtotheparameter.assertThat(hello.startsWith("Hello"),is(true));

assertThat(hello.endsWith(""),is(true));

assertThat(hello.startsWith("He"),is(true));

BothendsWithandstartsWithmethodsimplementcasesensitivesearches.assertThat(hello.startsWith("he"),is(false));

assertThat(hello.startsWith("Lo"),is(false));

isEmpty

TheisEmptymethodreturnstrueifthelengthoftheStringis0,andfalseifthelengthis>0.Stringempty="";

assertThat(empty.isEmpty(),is(true));

assertThat(empty.length(),is(0));

regionMatches

TheregionMatchesmethodallowsyoutouseindexestospecifyaregionintheString,withinwhichtolookforaregioninthecomparisonotherString.regionMatches(booleanignoreCase,inttoffset,

Stringother,intooffset,intlen)

Page 159: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Or:regionMatches(inttoffset,

Stringother,intooffset,intlen)

GivenaparticularString:"Hellofella"

01234567890

IcansearchforasubstringintheaboveStringe.g.Stringhello="Hellofella";

assertThat(

hello.regionMatches(true,6,"fez",0,2),

is(true));

IntheaboveexampleIamspecifying:

theregionofthehelloStringtosearchasstartingatposition6,untiltheendofthestringthesubstringis"fez",and

Iwanttheregionofthis"fez"Stringtostartatposition0,andonlybe2characterslong

IneffectIamlookingfor"fe"inthehelloStringstartingatposition6.

Thisisaparticularlycomplicatedmethodtouse,andIhaverarelyusedit.ItendtousecontainsorindexOfinstead.

Exercise:UseregionMatchesWritean@TestmethodwhichusesregionMatchestosearchintheString"Hellofella".Andmatcharegionofthesubstring"younglady".e.g.searchforthe"la"portionof"younglady"in"Hellofella"

indexOf&lastIndexOfForthefollowingexamplesIamusingtheString:"Hellofella"

01234567890

Declared,inthecode,asfollows:Stringhello="Hellofella";

BoththeindexOfandlastIndexOfmethodsreturnthepositionintheStringwheretheCharacterparameterorStringparametercanbefound.

TheindexOfmethodreturnsthefirstplaceintheStringwheretheparametercanbefound.assertThat(hello.indexOf("l"),is(2));

ThelastIndexOfmethodreturnsthelastplaceintheStringwheretheparametercanbefound.ThesearchfortheindexbeginsfromtheendoftheString,workingtowardsthestartoftheString.

Page 160: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat(hello.lastIndexOf("l"),is(9));

BothindexOfandlastIndexOfcanbecalledwithanadditionalparametertospecifythestartpositionintheStringtosearchfrom.

InthecaseofindexOfitsearchesfromthegivenposition,totheendoftheString.assertThat(hello.indexOf('l',3),is(3));

assertThat(hello.indexOf("l",4),is(8));

ThelastIndexOfmethodsearchesfromthegivenpositiontowardsthestartoftheString.assertThat(hello.lastIndexOf('l',8),is(8));

assertThat(hello.lastIndexOf("l",7),is(3));

IfindexOforlastIndexOfcannotfindanoccurrenceoftheCharacterorsubstringinStringthenthemethodreturns-1(negativeone).assertThat(hello.indexOf('z'),is(-1));

assertThat(hello.lastIndexOf("z"),is(-1));

Exercise:FindpositionsofalloccurrencesinaStringWriteamethod,whichtakesaStringandasubstringasparametersandreturnsaList<Integer>whereeachIntegeristhelocationofthesubstringintheString.

e.g.findAllOccurrences("Hellofella","l")wouldreturnaList<Integer>withthevalues2,3,8,9

Forbonuspoints,writeafindAllOccurrencesmethodwhichreturnsthelistinthereverseorderi.e.9,8,3,2

ComparingWithRegularExpressionsRegularExpressionsareanincrediblypowerfultoolforworkingwithstrings.

Javahasawholepackagededicatedtoregularexpressions,‘java.util.regex’,butadetailedlookatRegularExpressionhandlingisbeyondthescopeofthisbook.Ihavelistedthemainon-linereferencesIuseintheReferencessectionofthischapter.

InthisbookIwanttointroduceyoutoregularexpressionswiththe.matchesmethod.

AregularexpressionisaStringwheresomeoftheCharactershavespecialmeaning,e.g.wildcards,orgroupingconstructs.Thephrase“RegularExpression”isoftenabbreviatedto“Regex”.

Thematchesmethodhelpsustodothesimplestregularexpressiontask,whichisanswerthequestion“doesthisRegularExpressionmatchthisString?”

AnexamplescenariofortheuseofRegularExpressionsmightbethatwewanttoexpandthepasswordvalidationonourUserclass:

passwordmustcontainadigitpasswordmustcontainanuppercaseletter

Page 161: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

WecouldimplementtheaboveconditionsusingtheindexOfoperatorandloopoverdigitsoruppercaselettersandtryandfindthemintheString.Butthatwouldbethehardway,itwouldrequireacomplicatedloopandcouldleadtobuggycode.

Or,wecouldbuildaregularexpressionthatonlymatchesifeachofthoseconditionsiscorrect.

Forexample,IcanwritearegularexpressionofmatchingaStringandcheckthatitincludesadigit".*[0123456789]+.*".

Atahighleveltheaboveregularexpressionmeans:

.*-match0ormorecharacters[0123456789]+-untilwefind1ormoreofthefollowingcharacters“0123456789”.*-whichcanbefollowedby0ormorecharacters

Todetailitfurther:

.-matchesanysinglecharacter*-meansmatch0ormoreoftheprecedingelement[]-matchesanysinglecharactercontainedinthebrackets+-meansmatch1ormoreoftheprecedingelement

IcanuseitinmyJavacodeasfollows:StringmustIncludeADigit=".*[0123456789]+.*";

IassignedtheregularexpressionintoaStringvariableforre-use.

IcallthematchesmethodonaStringandpassintheregularexpressionasaparameter,andiftheregularexpressionmatchestheStringthenmatchesreturnstrue.assertThat("12345678".matches(mustIncludeADigit),is(true));

assertThat("1nvalid".matches(mustIncludeADigit),is(true));

Ifthematchfailsthenfalseisreturned.assertThat("invalid".matches(mustIncludeADigit),is(false));

assertThat("Invalid".matches(mustIncludeADigit),is(false));

Icanwriteasimilarregularexpressiontomatchuppercaseletters:StringmustIncludeUppercase=".*[A-Z]+.*";

Iusedoneadditionalconstructintheaboveregularexpression:

A-Zin[A-Z]-meansanycharacterbetweenA-Z,soIcoulddoa-zor0-9

assertThat("Valid".matches(mustIncludeUppercase),is(true));

assertThat("val1D".matches(mustIncludeUppercase),is(true));

Exercise:RegularExpressionsforUsersetPasswordAddtheregularexpressioncheckstothesetPasswordmethodonUsersothatanIllegalPasswordexceptionisthrownifthepassworddoesnotcontainadigit,ordoesnotcontainanuppercaseletter.

Page 162: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

WorkingwithRegex

WhenyouarenewtoRegularExpressionstheycanseemdaunting.

EverytimeIreturntothem,theyseemdaunting,becauseI’veforgottenalotofthenuancesandhowtowritethem.

SoIwanttoletyouinonmysecretsonhowIgetbackuptospeed.

1. Iuseregular-expressions.infotohelpmerememberthesyntax2. Iuseon-linetoolslikeregexpal.comtoconstructandchecktheregularexpression

againstsampletext3. IusedesktoptoolslikeRegexBuddy(regexbuddy.com)tohelpmeconstructand

checktheregularexpression.RegexBuddyalsobuildscodesnippetstouse.4. IwriteJUnitteststocheckmyregularexpressionworks5. IwriteJUnittestsaroundthecodeusingtheregularexpressione.g.totestthe

setPasswordmethod

Regularexpressionsareatremendoustoolwhenyougetusedtothem.AsyougrowmoreexperiencedwithJavaandstartusingthejava.util.regexpackageyoucanuseregularexpressionstoparsestringsandpulloutsubstringsusingregularexpressions.

Butforthemoment,startwiththe.matchesmethodandgetusedtowritingregularexpressionsforvalidation.

ManipulatingStrings

ReplacingStringsJavaprovidesthreemethodsonStringtohelpusgenerateanewStringbutwithelementsoftheStringreplacedwithothercharacters.

.replace-replaceallmatchingsubstringswithanewsubstring

.replaceAll-replaceallsubstringsthatmatcharegularexpressionwithanewsubstring.replaceFirst-replacethefirstsubstringmatchingtheregularexpressionwithanewsubstring

Stringhello="Hellofellafellafella";

assertThat(hello.replace("fella","World"),

is("HelloWorldWorldWorld"));

YoumightwonderwhythereisnoreplaceFirstfornormalStrings,ratherthanjustusingregularexpressions.Andthereasonisthata‘normal’string,isaregularexpression,butonewhichonlymatchesthatString.

ThisallowsmetousereplaceFirsttoreplacethefirstoccurrenceoffellawithWorld:assertThat(hello.replaceFirst("fella","World"),

is("HelloWorldfellafella"));

Page 163: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

And,whentheregularexpressionisastringliteralwithnoregularexpressionspecialcharacters,IcanusereplaceAllinsteadofreplaceassertThat(hello.replaceAll("fella","World"),

is("HelloWorldWorldWorld"));

replaceFirstandreplaceAllofferusaverysimplewayofaccessingadditionalpowerofregularexpressions.

e.g.toreplacenumbers,withtheString"digit":assertThat("1,2,3".replaceFirst("[0-9]","digit"),

is("digit,2,3"));

assertThat("1,2,3".replaceAll("[0-9]","digit"),

is("digit,digit,digit"));

UppercaseandLowercaseJavaprovidesveryselfexplanatorymethodsforconvertinganentireStringtouppercaseorlowercase

.toUppercase-converttheStringtouppercase

.toLowercase-converttheStringtolowercase

Stringtext="Inthelower3rd";

assertThat(text.toUpperCase(),

is("INTHELOWER3RD"));

assertThat(text.toLowerCase(),

is("inthelower3rd"));

RemovingWhitespaceTheStringtrimmethod,removesleadingandtrailingwhitespacefromaString.Stringpadded="trimme";

assertThat(padded.length(),is(15));

Stringtrimmed=padded.trim();

assertThat(trimmed.length(),is(7));

assertThat(trimmed,is("trimme"));

Thisisaveryhandymethodtousewhentidyingupinputdata,ordatareadfromfiles.

SubstringsStringhastwoformsofsubstring:

substring(intbeginIndex)-fromanindextotheendoftheStringsubstring(intbeginIndex,intendIndex)betweenastartindexandanendindex

GivenaStringofdigits:

Page 164: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Stringdigits="0123456789";

Wecangetfrom(andincluding)the5thdigit,totheendoftheString:assertThat(digits.substring(5),is("56789"));

TheendIndexisnotincludedinthesubstring,so(5,6)means“from5thto(butnotincluding),the6th”:assertThat(digits.substring(5,6),is("5"));

String.format

InsteadofconcatenatingstringsallthetimewecanusethestaticformatmethodonStringtoconstructstrings.

Theformatmethodallowsustocreatesimplestringtemplates,whichwepassargumentsinto.

e.g.insteadofhavingtoconcatenateStringandothervariablestogether:intvalue=4;

Stringoutput="Thevalue"+value+"wasused";

assertThat(output,is("Thevalue4wasused"));

WecoulduseString.formatandaformatstring:Stringtemplate="Thevalue%dwasused";

Stringformatted=String.format(template,value);

assertThat(formatted,is("Thevalue4wasused"));

A‘format’stringisaStringwithembeddedconversionplaceholdersfortheargumentssuppliedtoString.format.e.g.

%d-meansconverttheargumenttoadecimalinteger

Commonplaceholdersare:

%d-adecimal%s-aString

e.g.Stringuse="%s%stowards%dlarge%s";

assertThat(

String.format(use,"Bob","ran",6,"onions"),

is("Bobrantowards6largeonions"));

Theargumentsareusedinordertofilltheplaceholdersintheformatstring.

Theformatstringcanspecifyexactlywhichargumentitwantstouseineachplaceholderbyusing%<index>$e.g.%2$wouldmeanthe2ndargument:Stringtxt="%2$s%4$stowards%3$dlarge%1$s";

assertThat(

String.format(txt,"Bob","ran",6,"onions"),

is("ranonionstowards6largeBob"));

Thisallowsustore-useargumentstofillthetemplateinmultipleplaces:

Page 165: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Stringtxt2="%1$s%1$stowards%3$dlarge%1$s";

assertThat(

String.format(txt2,"Bob","ran",6,"onions"),

is("BobBobtowards6largeBob"));

Theformatstringoffersalotofflexibility,andwhenyoulookattheofficialdocumentationfortheStringFormattingSyntaxyouwillseethis.

docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax

Itendtokeeptheformatstringsverysimple,andmainlyusethemasplaceholdersfor%sand%d,butitisworthbeingawareofthepossibilitiesopentoyouwiththeformatplaceholders.

BasicStringparsingwithsplitsplitallowsustoconvertaStringintoanarray,whereeacharrayelementisaportionoftheStringdelimitedbythesplitargument.

Forexample,Icould‘parse’acommaseparatedvaluestringwithStringcsv="1,2,3,4,5,6,7,8,9,10";

String[]results=csv.split(",");

Theresultsarraywouldhave10elements,whereeachelementwasoneofthenumbersseparatedby“,”intheoriginalString:assertThat(results.length,is(10));

assertThat(results[0],is("1"));

assertThat(results[9],is("10"));

Thesplit,argumentisaregularexpression,socanbeusedcreatesophisticatedsplitfunctionswithminimalcode.

IfrequentlyusesplittoparsesimpleCSV,ortabdelimitedfiles.I’vealsousedittoparseHTMLandXML,withoutbringinginotherlibraries.

ManipulatingstringsWithStringBuilderWehavelearnedthatStringisimmutable,butJavaprovidesaClassformanipulatingandcreatingstringscalledStringBuilder:StringBuilderbuilder=newStringBuilder();

AStringBuilderallowsusto:

appendvaluestotheendofthestringdeletecharacters,orsubstrings,fromthestringinsertvaluesintothestringreplacesubstringswithotherstringsreversethestring

ItdoesthisbyholdinganinternalrepresentationofthestringwhichisonlyconvertedintoaStringwhenthetoStringmethodiscalled.e.g.

Page 166: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

builder.append("HelloThere").

replace(7,11,"World").

delete(5,7);

assertThat(builder.toString(),is("HelloWorld"));

AStringBuilderextendsStringBuffer,andisslightlyfaster,butonlyforusewithsinglethreadedapplications.IfyouadvanceyourJavatothestagewhereyouareusingmultiplethreads,thenyoumayneedtouseStringBufferinstead.

ConstructaStringBuilderWecanconstructanemptyStringBuilder:StringBuilderbuilder=newStringBuilder();

WecanconstructaStringBuilderwithastartingStringvaluefromanythingthatimplementstheCharSequenceinterfacee.g.StringStringBuildersb=newStringBuilder("hello");

CapacityManagement

SinceStringBuildermaintainsaninternalrepresentationoftheStringitallocatesaparticularcapacityinmemoryforthatinternalrepresentation.WhenitemsareappendedtotheStringBuilderthecapacityisautomaticallyincreased.

Bydefault,ifyouusetheno-argumentconstructor,thecapacityis16.StringBuilderbuilder=newStringBuilder();

assertThat(builder.capacity(),is(16));

Youcanfindoutthecurrentcapacitysizeusingthecapacitymethod.

YoucanconstructaStringBuilderwithaspecificcapacityifyouwant.StringBuildersblen=newStringBuilder(512);

assertThat(sblen.capacity(),is(512));

assertThat(sblen.toString().length(),is(0));

Forautomationcodewetypicallydon’tworryaboutthecapacity,butifyouarewritingcodethatneedstobefastthenyoumightsizetheStringBuildertoavoidtoomuchcapacityre-allocation.

YoucansizetheStringBuilderafterconstructionusingtheensureCapacitymethod:builder.ensureCapacity(600);

Ifyouhaveamendedthecapacity,ordeletedalotofthestringthenyoucansetthecapacitytotheminimumnecessarytoholdthestringcharactersbyissuing:builder.trimToSize();

AppendingtotheStringBuilderTheappendmethodworksmuchlikethe+concatenationapproachforString.WecanappendObjects,primitives,Strings,orchar[]totheendofaStringBuilder.StringBuilderbuilder=newStringBuilder();

builder.append(">");

builder.append(1);

builder.append("+");

Page 167: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

builder.append(2);

char[]ca={'','=','','3'};

builder.append(ca);

assertThat(builder.toString(),is(">1+2=3"));

Ifduringtheappending,weaddmorecharactersthanthecurrentcapacity,thenStringBuilderwillautomaticallyresize.

Exercise:CheckStringBuilderresizesWritean@TestannotatedmethodwhichvalidatesthataStringBuilderresizeswhenyouappendmorecharactersthanthecurrentcapacity.

InsertintotheStringBuilderTheinsertmethodsupportsthesameobjectsandprimitivesastheappendmethod.

WhenweinsertintotheStringBuilderwehavetospecifythepositiontoinsertinto:StringBuilderbuilder=newStringBuilder("123890");

builder.insert(3,"4567");

assertThat(builder.toString(),is("1234567890"));

InJava,indexesstartat0,sothefirstspacewecaninsertintoinanEmptystringis0.

IfweuseanindexwhichislongerthanthecurrentinternalrepresentationoftheStringthenaStringIndexOutOfBoundsExceptionwillbethrown.

WhenaStringBuilderhassomevaluesinthestringwecaninsertat:

index0toaddittothefront,indexlengthtoappenditanythinginbetweentoadditintothebody

Exercise:InsertintoaStringBuilderInsertaStringintoanemptyStringBuilder.InsertaStringontheend.InsertaStringinthemiddle.

Whenweinsertachar[]wehaveadditionaloptions.Inadditiontotheindex,wecanspecifytheoffsetinthechararray,andthenumberofcharacterstocopyfromthechararray.

GiventhefollowingStringBuilderwhichstartswiththeString"abgh":char[]ca={'.','a','b','c','d','e','f'};

StringBuilderbuilder=newStringBuilder("abgh");

Thecodebelowwillinsertatposition2inthestring(i.e.afterthe‘b’).Thecharactersfromposition3inthechararray('c')tothenext4characterse.g.(cdef);//atposition2inthestring

//insertfromthechar[]ca

//startingatindex3'c'

Page 168: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

//inclusivethenext4indexes

builder.insert(2,ca,3,4);

assertThat(builder.toString(),is("abcdefgh"));

DeletingfromStringBuilderWecandeletesubstrings,basedonindexesfromtheStringBuilder:StringBuilderbuilder=newStringBuilder("abcdefg");

builder.delete(2,4);

assertThat(builder.toString(),is("abefg"));

Giventhestring"abcdefg"we:

specifythestartindextodeletefrom,e.g.2,whichis“c”,andspecifythelastindextodeleteupto,e.g.4,whichwouldspan“cd”

abcdefg

0123456

OrwecandeleteaspecificcharacterataspecifiedindexusingdeleteCharAt:builder.deleteCharAt(2);

assertThat(builder.toString(),is("abdefg"));

ReplaceSubStringsandCharactersWecanreplacesubstringswiththereplacemethod,whichtakesastartindex,endindex,andaStringasparameters.

Thecharactersfromstartindex,toendindexarereplacedbytheString:StringBuilderbuilder=newStringBuilder("abcdefgh");

builder.replace(0,4,"12345678");

assertThat(builder.toString(),is("12345678efgh"));

Intheexampleabove,thestringtoreplacewasonly4characters,butthe‘gap’waslengthenedtoallowthereplacementStringtobeinserted.

WecanreplaceindividualcharactersbyusingthesetCharAtmethod:StringBuilderbuilder=newStringBuilder("012345678");

builder.setCharAt(5,'f');

assertThat(builder.toString(),is("01234f678"));

ReverseTheabilitytoreversestringscomesinsurprisinglyuseful.

HavingthismethodbuiltintoStringBuildermeansthatIoftensimplyconstructaStringBuilderwithaStringandcall.reverse().toString().StringBuilderbuilder=newStringBuilder("0123456789");

assertThat(builder.reverse().toString(),is("9876543210"));

SubStringsThesubstringmethodreturnsaStringfromastartindextoanendindex:

Page 169: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

StringBuilderbuilder=newStringBuilder("0123456789");

assertThat(builder.substring(3,7),is("3456"));

Orfromastartindextotheendofthestring:assertThat(builder.substring(3),is("3456789"));

StringBuilderSummaryStringBuilderisaverypowerfulclassthatpreventsneedingtousealotofStringsandconstantlyconcatenatingthemtogether.TheuseofStringBuilderisalsoveryefficientsinceitusesaninternalrepresentationratherthanconstructingnewStringobjectsoneachmethodcall.

Forefficiencywecouldmaintainthecapacityourself,andsizetheStringBuilderappropriatelyforthetaskathand,ratherthanhavetheStringBuilderresizeontheflywitheachmethod.

StringBuilderhasothermethodsthatwehaven’tcoveredhere,thishasbeenanoverviewofthemainStringBuilderfunctionalitythatyouwillusemostoften.

IfindthatIuseStringBuildermostforStringconstruction,somainlytheappendandinsertmethods.Irarelyusethereplace,andsubstringmethods,preferringtoreplaceandworkwithsubstringsdirectlywiththeStringclass.

Youwilldevelopyourownstyle,andworkwiththeclassesthatmakemostlogicalsensetoyou.

Forfulldocumentation,ofallthemethods,seethelinkintheReferencesorusecodecompletioninyourIDE.RememberinIntelliJpressingctrl+q(onWindows)orctrl+j(onMac)inthecodecompletionpop-upshowstheJavaDocdocumentationforthemethod.

Concatenation,.format,orStringBuilderHowdoyouchoosetherightwaytobuildStrings?

Wehaveseenmanydifferentwaystoconstructstrings:

simpleconcatenationeitherwith+orconcatsimpletemplatesusingString.formatStringBuilderflexibilitywithinserts,appendsanddeletes

Sowhichisbest?

Well,Iusethemall.

ForsimplestringbuildingIuseconcatenation.

IuseformatswhenIhavetoomanyconcatenationsandthecodebecomeshardtoreadandmaintain,orwhenIwanttoreusetheformatstringinmultipleplaces.ItrytoremembertouseString.formatmore,evenwhenIhaveasmallsetofconcatenations,butsometimesIgetlazyandconcatenateStringstogether.

Page 170: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ItendtouseStringBuilderifI’mbuildingaStringoveralongperiodoftime,orneedtobuildtheStringoveranumberofmethodcalls.

Idon’tthinkthereisarightanswer.Butdobeawarethatyouhaveoptions.

Trytomakeyourcodeasreadableandmaintainableaspossible.Sochoosethemethodthathelpsyoubuildcodethatlasts.

SummaryWhenautomatingIworkwithstringsallthetime:representingdata,parsingfiles,processingJSON,creatingHTTPrequests,etc.

SoIusealotofbasicStringprocessingmethodsandStringBuildergenerationmethods.

Thischapterhascoveredalotofthebasics,eventhoughwehaven’tgoneintodepthinmanyoftheareas.Referbacktothischapterwhenworkingwithautomationanddataandyou’llfindmanyofthebasicfunctionsthatyouareusing,orcoulduse,listedhere.

I’vetriedtocoverthemethodsandclassesbehindthebulkofmystringprocessingneeds,hopefullythatwillmatchyourinitialfutureneeds.

ReferencesandRecommendedReading

JavaEscapeSequencesdocs.oracle.com/javase/tutorial/java/data/characters.html

JavaStringstutorialdocs.oracle.com/javase/tutorial/java/data/strings.html

JavaByteEncodingandStringsdocs.oracle.com/javase/tutorial/i18n/text/string.html

StringFormattingsyntaxdocs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax

StringBuilderTutorialdocs.oracle.com/javase/tutorial/java/data/buffers.html

StringBuilderDocumentationdocs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html

JavaRegularExpressionsdocs.oracle.com/javase/tutorial/essential/regex

RegularExpressionsInformationandTutorialsregular-expressions.info/

WikipediaRegularExpressionsen.wikipedia.org/wiki/Regular_expression

On-lineRegularexpressiontesterregexpal.com

RegexBuddyDesktopToolregexbuddy.com

Page 171: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterSixteen-RandomData

ChapterSummaryInthischapteryouwilllearnhowtouseJava’sRandomfunctionalitytocreateRandomData:

Math.random-easytousestaticwrappertogeneratearandomdoublebetween0.0and1.0java.util.random-themainJavarandompackage:

nextBoolean-returneithertrueorfalsenextLong-returnarandomlongvaluenextInt-randomintovertherangeofallIntegervaluesnextInt(intbelow)-randomintgreaterthanorequalto0andlessthanbelownextDouble-flatdistributionwhereeachvaluebetween0.0and1.0hasequalchanceofbeingreturnednextGaussian-aGaussiandistributionwithameanof0.0andastandarddeviationof1.0,meaningabout70%valueshoveringaroundthe0.0mark(+or-1.0)nextFloat-randomfloatgreaterthanorequalto0.0andlessthan1.0nextBytes-fillagivenbyte[]withrandombytes

seedingrandomnumbergenerationwithnewRandom(seed)Generatingrandomstrings

Randomdatainautomationisacontentioussubject.Somepeoplearguethatautomationshouldbecompletelydeterministicandalwaysrunthesameway-implyingthatwealwaysusethesamedata.Iprefertovarydatathatisnotimportanttotheconditionschecked,i.e.datathatshouldbepartofanequivalenceclass.Bydoingthisweincreasethedatacoverageoftheautomation,andincreasethepossibilitythattheautomatedcheckwillrevealabug.

Javahasaverysimplesetofrandommethodsandclasses.

java.util.random

Math.random()

Java,aspartoftheSecuritypackageshasaSecureRandomclass,whichexposesthesamemethodsaswediscussinthischapter.IdonotcoverSecureRandominthisbookbecause:

Ihaveneveruseditinproductionautomationcode,Itisslightlyslowertoinstantiate,Itisslightlyhardertousewell.

Mostoftherandomnessyouneedinyourautomationcodeyoucanachievewith:

java.util.random

Math.random

ThestaticrandommethodonMathprovidesa‘pseudorandom’number.

Page 172: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Itisactuallyawrapperforthejava.util.randomnextDoublemethod.Butmakesitsimpletouse.

WhenMath.random()isfirstcalled,anewrandomnumbergeneratoriscreatedwhichisusedforeachcalltoMath.random()

Math.random()returnsadouble,greaterthanorequalto0.0andlessthan1.0doublernd=Math.random();

System.out.println(

String.format(

"generated%fasrandomnumber",rnd));

assertThat(rnd<1.0d,is(true));

assertThat(rnd>=0.0d,is(true));

java.util.random

Thejava.util.randompackageprovidesmethodstogeneraterandomvaluesasfollows:

boolean

nextBoolean-returneithertrueorfalselong

nextLong-returnarandomlongvalueint

nextInt-randomintovertherangeofallIntegervaluesnextInt(intbelow)-randomintgreaterthanorequalto0andlessthanbelow

double

nextDouble-flatdistributionwhereeachvaluebetween0.0and1.0hasequalchanceofbeingreturnednextGaussian-aGaussiandistributionwithameanof0.0andastandarddeviationof1.0,meaningabout70%valueshoveringaroundthe0.0mark(+or-1.0)

float

nextFloat-randomfloatgreaterthanorequalto0.0andlessthan1.0byte[]

nextBytes-fillagivenbyte[]withrandombytes.

TousethemethodswefirsthavetoinstantiateaRandomObject:Randomgenerate=newRandom();

Thencalltheappropriatemethodtogeneratetherandomvaluethatwerequire:booleanrandomBoolean=generate.nextBoolean();

intrandomInt=generate.nextInt();

intrandomIntRange=generate.nextInt(12);

longrandomLong=generate.nextLong();

doublerandomDouble=generate.nextDouble();

doublerandomGaussian=generate.nextGaussian();

byte[]bytes=newbyte[generate.nextInt(100)];

generate.nextBytes(bytes);//fillbyteswithrandomdata

Page 173: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MostoftheabovemethodsareprettyselfexplanatoryandIencourageyoutoexperimentwiththembydoingtheexerciseslistedinthischapter.

Iwillgointotwoofthemethodsinmoredetail,aftertheexercise:

nextInt(intbelow)

nextGaussian

Exercise:Create@TestMethodsWhichConfirmRandomLimitsCreate@Testmethodsforeachoftherandommethods.i.e.nextInt,nextLong,etc.Foreachrandommethod,generate1000randomvaluesandassertthatthereturnedvaluesmeetthedescription:

nextIntgeneratesfromInteger.MIN_VALUEandInteger.MAX_VALUEnextBooleangenerateseithertrueorfalsenextLonggeneratesalongbetweenLong.MIN_VALUEandLong.MAX_VALUEnextFloatgeneratesafloatbetween0.0fand1.0fnextDoublegeneratesadoublebetween0.0dand1.0dnextBytesfillsabyte[]withrandomdatanextInt(x)generatesandintfrom0tox-1

nextInt(intbelow)

Whengeneratingarandomintwecanspecifytheupperrangeforthegeneration.

nextInt(intbelow)

Foragivenvaluebelow,thenextIntmethodwillgenerateavaluebetween0(inclusive)andthevalueofthebelowparameter(exclusive)e.g:

nextInt(5)generatearandombetween0and4inclusiveanumbergreaterthanorequalto0(inclusive)butlessthan5(exclusive)

nextInt(200)generatearandomnumberbetween0and199inclusiveanumbergreaterthanorequalto0(inclusive)butlessthan200(exclusive)

IfwewanttousenextInttogenerateanintegerfromaspecificnumber,e.g.1insteadof0thenwehavetouseanalgorithm:

calculatetherangeofnumbersadd1tothis,sincethenextIntmaximumisonelessthandesiredandaddthestartnumber.

e.g.intminValue=1;

intmaxValue=5;

intrandomIntRange=generate.nextInt(

maxValue-minValue+1)+minValue;

Page 174: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:Createan@Testmethodwhichgenerates1000numbersinclusivelybetween15and20Usethealgorithmabovetogenerate1000numbersbetween15and20andassertthatallnumbers15,16,17,18,19,20weregenerated.

nextGaussian

AdoubledrawnfromaGaussiandistributionwithameanof0.0andastandarddeviationof1.0,meaning:

about70%valueshoveringaroundthe0.0mark(+or-1.0),about95%valuesbetween-2.0and2.0about99%valuesbetween-3.0and3.0about99.9%valuesbetween-4.0and4.0

TheoreticallythereisnolimittothevalueofthedoublethatcouldbereturnedbynextGaussianbecauseitisnotalimitedrange,itisaprobabilitydistributionaroundagivenmean.

Youcanfindreferencesto‘StandardDeviation’attheendofthechapter.

Exercise:Writean@TestmethodthatshowsthedistributionsWritean@Testmethodthatgenerates1000‘double’valuesusing‘nextGaussian’.Countthosethatarewithin1standarddeviation,within2standarddeviationsetc.Calculatethepercentagesofnumberswithineachstandarddeviationrangeandseeiftheyalignroughlywiththevaluesabove.

e.g.theoutputafterrunningthemethodcouldbe:

about70%onestandarddeviation=67.299995

about95%twostandarddeviation=95.3

about99%threestandarddeviation=99.8

about99.9%fourstandarddeviation=100.0

UsenextGaussiantogeneratearangeofintegers

ThenextGaussianmethodistypicallyusedincombinationwithothermethodstodistributetherangeofrandomvaluesoveraprobabilitycurve.

e.g.if‘most’ofourusersareaged30-40,thenwehaveameanof35withastandarddistributionof5,thenwecoulduseGaussiandistributiontogeneratetheageintage=(int)(generate.nextGaussian()*5)+35;

about70%valueshoveringaroundthe35+/-5mark(30-40),about95%valuesbetween35+/-10mark(25-45)about99%valuesbetween35+/-15mark(20-50)about99.9%valuesbetween35+/-20mark(15-55)

Page 175: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Whendealingwithagesyoumightneedtoaddadditionalcodetoensureaminimumandmaximumvalue,eventhoughtheprobabilityofgettinganextremevalueislow,itmighthappen.

Exercise:Writean@Testmethodwhichgenerates1000agesusingnextGaussian

Writean@Testmethodwhichgenerates1000agesusingnextGaussianwithameanof35andastandarddeviationof5.Counteachagegeneratedandoutputthesortedlistofagesandcountstotheconsole.

e.g.

...

34:70

35:167

36:83

37:80

38:66

39:51

...

SeedingrandomnumbersTherandomnumbersare‘pseudorandom’becausetheyarebasedona‘seed’,andeachcallto‘random’isdeterministicifthe‘seed’iscontrolled.

Forexample:Randomgenerate=newRandom(1234567L);

WouldgeneratearandomnumbergeneratorwherethenextIntreturns1042961893

Exercise:Createan@TestmethodforRandomwithSeedCreatean@Testmethodfortheseed1234567Landassertthat:

nextInt==1042961893thennextLong==-6749250865724111202Lcontinuetheassertionsandadd:

nextDouble,nextGaussian,nextFloat,nextBoolean

Makesureyoucanre-runthemethodandyougetthesame‘random’numbers.

Thisisusefulwhenyouwanttomakemethodexecutionrepeatable.e.g.ifatthestartofarunyouseedtheRandomwiththecurrentdatetime,thenifyoulogthedateandtime,youcouldrepeattherunexactly,evenifrandomdatawasused.

ForExample:longcurrentSeed=System.currentTimeMillis();

System.out.println("seedused:"+currentSeed);

Page 176: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Randomgenerate=newRandom(currentSeed);

IftheSystem.out.printlnwasaloggingcall,thenIcouldrecreatetherunbyseedingrandomwiththeseedvalueloggedintheoutput.

UsingRandomNumberstogenerateRandomStringsAcrudewaytogeneraterandomstringsistobuildaStringbyrandomlyaddingavalidcharactertotheString.

ForExampleifIwanttobuildaStringfromtheuppercaselettersandspace:StringvalidValues="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

ThenIcanrandomlyselectacharacterfromthatString:intrndIndex=random.nextInt(validValues.length());

charrChar=validValues.charAt(rndIndex);

IfIlooparoundthisgenerationprocessandconcatenatetheresultsthenIcangeneratearandomString.

Exercise:GenerateaRandomString100charslongGeneratearandomstring,100characterslong,containingthecharacters''(space)and'A'to'Z'.

DiscussionrandomdatainautomationManypeopledonotliketoaddrandomdatatotheirautomation.

Ido.

Iviewautomatedchecksasexercisingaparticularpaththroughthesystem,withvariabledata.

Somedata,isneededinordertocontrolthepath,andifIvarythatdatathenIrunadifferentpath.

ForExample:IfIamonlyaskedformypassportnumberwhenIam65,thenifIcreateauserwhoisnot65,Ican’tcoverthatpath.SoIwouldnotvarytheage.ButifIamaskedforapassportnumberwhenIam65orover,thenIhaveanequivalenceclass.AndifIrandomlygenerateanagewhichis65orolderthenIcancoverthatpath.Itshouldmakenodifferencetothe@Testmethods,soIcanvarythedata.IfIvarythedataandthe@TestmethoddoesnotrunasexpectedthenImayhavefoundabugwithourunderstandingoftheequivalenceclass,butImightalsohavefoundabugrelatedtothewaytheapplicationprocessesaparticularage.

Iuserandomnesstogeneratedataforequivalenceclasses,andcontrolthedatawhichneedstobestaticfortheexecutionpathpreconditionstobemet.

ImportanceofLoggingwhenusingRandomdataWhenIuserandomdata,Ineedtologit.

Page 177: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThesimplestloggingmechanismtostartwithisSystem.out.printlnsoifmy@Testmethodswritetotheconsoleanoutputofwhatdatatheyhaveused,thenIcanrecreatetherunlaterbyusingtheoutputlogs.Becausethemethodsmayhavefailedduetothespecificcombinationofrandomvalues,andIneedtorecreateanyfailingassertionwiththatparticulardata.

Imayneedtocreateamechanismtorerunmethodswithparticulardatavalues,inwhichcaseseedingtherandommechanism,andloggingtheseedvalue,mightbeanappropriatesolution.

IhavemanagedtogetbyinmostofmyproductionuseofrandomizationbyloggingtheoutputoftherandomdatagenerationtoSystem.out.println.ThelogappearsinSystem.outwhenthecoderanaspartofcontinuousintegrationandifanassertionfailsduetodatathenwecanlookatthelogandusetheseed,ordata,torecreatetheexecution,orre-runningthefailing@Testmethodmanuallywiththegenerateddata.

Startsimplewithyourautomation.

Don’tthinkthatbecauseyou’vestartedusingrandomdatayouneedtheabilitytorecreatealltherunsexactlyandseedyourdatainthecontinuousintegrationenvironment.Youprobablydon’t.Youprobablyneedtostartwiththeabilitytoseewhatdatayouhaveusedsothatyoucanre-runanyfailingmethodsmanuallyanddetermineiftherandomdatacombinationyouused,triggeredabug.

SummaryYouhaveseenwiththelaterexamplesusingnextGaussianandtherandomStringgenerationthatevenwithasmallsetofrandomnumbergenerationfunctionswecanfairlyeasilyusethemtogeneratecomplicateddatasets.

IfrequentlyuserandomdatatohelpmebuildDomainobjectse.g.randomUsers.AndthenIsetthespecificvaluesIneedformy@Testmethod.i.e.insteadofadefaultusernameandpasswordintheconstructor,Imightassignarandomlygeneratedusernameandpassword.

ReferencesandRecommendedReading

StandardDeviationen.wikipedia.org/wiki/Standard_deviation

Math.random

docs.oracle.com/javase/7/docs/api/java/lang/Math.html#random()java.util.random

docs.oracle.com/javase/7/docs/api/java/util/Random.htmlHintsongeneratingvaluesinarange

http://stackoverflow.com/questions/363681

Page 178: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterSeventeen-DatesandTimes

ChapterSummaryInthischapteryouwilllearnhowtouseJava’snativeDatefunctionality

System.currentTimeMillis-currentsystemtimeinmillisecondssincemidnightJanuary1st,1970System.nanoTime-currentJVMtimesourceinnanosecondsThenativeclassesassociatedwithdates:

Date-simpletouseclassforcomparisonandworkingfrommillisecondsSimpleDateFormat-createaStringfromaDateusingaformatpatternCalendar-awrapperforDatetoallowworkingwithdays,months,etc.

DatesinJavaarehandledalittleroughandready,asaresult,manyJavadevelopersuseexternallibrarieslike‘Joda-Time’.Externallibrariesarebeyondthescopeofthisbook,andwhiletheinternalJavaclassesmaynotoffertheflexibilityas‘JodaTime’,theyarestillverypowerful.

Inadditiontoworkingwithdates,IalsousetheDate/Timefunctionalityto:

seedrandomnumbersgenerateuniquedatae.g.filenames,anduserids

currentTimeMillisandnanoTime

System.currentTimeMillis-returnscurrentsystemtimeinmillisecondssincemidnightJanuary1st,1970System.nanoTime-returnscurrentJVMtimesourceinnanoseconds

System.currentTimeMillisreturnsalongwhichrepresentsthecurrenttimeonyourlocalmachine.ThetimeisrepresentedasthenumberofmillisecondssincemidnightoftheJanuary1st,1970.longstartTime=System.currentTimeMillis();

System.nanoTimereturnsalongwhichrepresentsthecurrentnanosecondsascalculatedbythecurrentJVM.Thisdoesn’tnecessarilymapontothecurrentsystemtime,butthedifferencebetweentwocallstonanoTimerepresentsthepassageoftime(innanoseconds)betweenthetwocalls.longstartTime=System.nanoTime();

Ananosecondisonethousand-millionthofasecond.

Itypicallyusethesemethodsto:

calculatethetimethatataskhastakencreateuniqueidsandfilenames

Page 179: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

CalculatethetimethatatasktakesTocalculatethetimethatatasktakes,Iwould:

instantiateastartTimeperformthetaskinstantiateanendTimecalculatethetotalTimeasendTime-startTime

ForexampletocalculatehowlongittakestooutputthecurrentTimeMillistotheconsoletentimes,Icanwritecodelikethefollowing:@Test

publicvoidcurrentTimeMillis(){

longstartTime=System.currentTimeMillis();

for(intx=0;x<10;x++){

System.out.println("CurrentTime"+

System.currentTimeMillis());

}

longendTime=System.currentTimeMillis();

System.out.println("TotalTime"+(endTime-startTime));

}

WhenIrunthisInormallygetatotalTimevalueofaround1,butsometimesIwillgetatotalvalueof0becausetheentiretasktakesplacewithinthesame‘millisecond’ascalculatedbycurrentTimeMillis.

TheresolutionofvaluesrepresentedbycurrentTimeMilliscanvarybetweenoperatingsystems,itisnotguaranteedtobea‘millisecond’,itmightbemoree.g.tensofmilliseconds.Assuchthisisn’tagreatmethodforexacttime,butitveryoftengoodenoughforautomationtimings,particularlyifyouareroundinguptothenearestsecondanyway.

Whatitisverygoodfor,areuniquenumbersorvalues,assumingthatyoudon’tresetyourcomputerclockintothepast.

Exercise:Re-writethetiming@TestmethodusingnanoTimeRe-writethemillisecond@TestmethodshownaboveusingnanoTimeandseethedifferenceinoutput.

WhenusingnanoTime,againtheresolutionisdeterminedbytheunderlyingoperatingsystem,butisreportedinnanoseconds.

nanoTimeismuchbetterforcalculatingthetimedurationofanactivitywhichrunsquickly,andforwhichyouwantamoreaccuratemeasurement.nanoTimeisnotusefulforcreatinguniquenumbersbecauseyoudon’treallyknowthebasisfortheJVMtime.

CreateuniquevalueswithcurrentTimeMillis

Page 180: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

TocreateuniqueidentifiersornamesIoftenprefixaStringtothecurrrentTimeMillisvalue:StringuserID="user"+System.currentTimeMillis();

Thisiscrudeandsimple,butfastandobvious.

e.g.user1424101386462

Exercise:UsecurrentTimeMillistocreateauniquenamewithnonumbersWeneedtocreateauniquename,thathasallalphabeticcharactersi.e.nonumbersinit.

CreateatestwhichgeneratesauniquestringfromcurrentTimeMillisbuthasnonumbersinthefinalstring.

Date

TheDateclassexposesasmallsetofmethods.Datedate=newDate();

MethodsthatDateprovides:

after-returntrueiftheparameterdateisaftertheDateobjectbefore-returntrueiftheparameterdateisbeforetheDateobjectcompareTo-returns0iftheDateobjectsareequal,negativeiftheDateobjectislessthanparameterandpositiveiftheDateobjectisgreaterthantheparameterequals-returntrueiftheparameterandDateobjectrepresentthesametimeanddatesetTime-setthetimerepresentedbytheDateobjecttoaspecificmillisecondvaluegetTime-returnthenumberofmillisecondsaftermidnight,January11970thatthisDaterepresentstoString-returnaStringrepresentationofthedate

InstantiatingDatewithoutaparameterwilldefaultthetimerepresentedbytheDatetothesamevalueasSystem.currentTimeMillis.

Thefollowingtwostatementsareessentiallyequivalent:DateequivDate1=newDate();

DateequivDate2=newDate(System.currentTimeMillis());

ThetoStringmethodprovidesasimplemethodofoutputtingaStringrepresentationofthedate.System.out.println(date.toString());

OnmymachinetoStringoutputsthefollowingstringformat:

ThuJun2012:18:04BST2013

Page 181: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

WewilllearnhowtocontroltheoutputofaDateinthenextsection.

WecanalsoinstantiateaDatewithalong,inordertosettheDatetoaspecifictime.

Forexample,IcouldcreateaDate7daysinthefuturefromoneDatebymanipulatingthelongthatIinstantiatetheDatewith:longoneWeekFromNowTime=date.getTime();

oneWeekFromNowTime=oneWeekFromNowTime+

(1000*60*60*24*7);

DateoneWeekFromNow=newDate(oneWeekFromNowTime);

System.out.println(oneWeekFromNow.toString());

IntheabovecodeItakethetimefromoneDatethenIadd7daysworthofmillisecondstothelongvalue,andinstantiateanewDatefromthatmillisecondsvalue.Resultinginthefollowingoutput:

ThuJun2712:18:04BST2013

WecanusethesetTimetosetthemillisecondstimevalueofadateafterconstructingit,soIcancreateaDatewithaduplicatetimeusingtheconstructororthesetTimemethod:DatesameDate=newDate();

sameDate.setTime(date.getTime());

assertThat(date.equals(sameDate),is(true));

assertThat(date.compareTo(sameDate),is(0));

SimpleDateFormat

SimpleDateFormatallowsustooutputthevalueofaDateobjectasaString,inaformatthatwechoose.SimpleDateFormatsdf=newSimpleDateFormat();

SoifIinstantiateaDatetothe1stofJanuary1970:SimpleDateFormatsdf=newSimpleDateFormat();

Thenthefollowingtableshowsexamplepatternsandtheassociatedgeneratedoutput,whenIapplythepattern:

Pattern Output"MM/dd/yyyy" "01/01/1970"

"MMM/dd/yyy" "Jan/01/1970"

"MMMM/d/yy" "January/1/70"

IcanusetheapplyPatternmethodtosetthepatternforaSimpleDateFormatandusethepatternonadatewiththeformatmethod.sdf.applyPattern("MM/dd/yyyy");

assertThat(sdf.format(date),is("01/01/1970"));

applyPattern-setthepatternthatthenextformatwilluseformat-formatthegivenDatewiththedefinedpattern

IcanalsoinstantiateSimpleDateFormatwiththepatternthatIwanttousee.g.“yearmonthday24hour:minutes:seconds.milliseconds”shownbelow

Page 182: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

SimpleDateFormatsdf=newSimpleDateFormat("yMdHH:mm:ss.SSS");

YoucanuseSimpleDateFormattogenerateaDateforagivendatestringe.g.thedateof“15thDecember2013”andatimeof“11:39pm”and“54secondsand123milliseconds”:Datedate=sdf.parse("2013121523:39:54.123");

Importantelementsforuseinthepatternformatarelistedbelow,using

Element Description Output"y" year "2013"

"yy" year "13"

"yyy" year "2013"

"yyyy" year "2013"

"yyyyy" year "02013"

"M" Month "12"

"MM" Month "12"

"MMM" Month "Dec"

"MMMM" Month "December"

"d" DayinMonth "15"

"dd" DayinMonth "15"

"ddd" DayinMonth "015"

"h" HourinAM/PMTime "11"

"hh" HourinAM/PMTime "11"

"hhh" HourinAM/PMTime "011"

"H" Hourin24HrTime "23"

"HHH" Hourin24HrTime "023"

"m" MinuteinTime "39"

"mm" MinuteinTime "39"

"mmm" MinuteinTime "039"

"s" SecondinMinute "54"

"ss" SecondinMinute "54"

"sss" SecondinMinute "054"

"S" Milllisecond "123"

"E" WeekDayName "Sun"

"EEEE" WeekDayName "Sunday"

"a" AM/PM "PM"

Moreunusualdateformatpatternsarelistedbelow.These,Ihaven’ttendedtousemuch:

Page 183: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Element Description Output"w" Weekintheyear "50"

"www" Weekintheyear "050"

"W" Weekinthemonth "2"

"WW" Weekinthemonth "02"

"WWW" Weekinthemonth "002"

"D" Dayintheyear "349"

"F" Dayofweekinthemonth "3"

"FF" Dayofweekinthemonth "03"

"FFF" Dayofweekinthemonth "003"

"u" Daynumberintheweek "7"

"uu" Daynumberintheweek "07"

"k" Hourintheday(1-24) "23"

"kkk" Hourintheday(1-24) "023"

"H" Hourintheam/pm(0-11) "23"

"HHH" Hourintheam/pm(0-11) "023"

"z" GeneralTimeZone "GMT"

"Z" RTC822TimeZone "+0000"

"X" ISO8601TimeZone "Z"

Thereasonforshowingsomanydifferentcombinationse.g."y","yy","yyyyy"wastodemonstratethatsomepatternswilltruncate,orpad,orexpanddependingonthevalueintheDate.

SimpleDateFormathasothermethodsavailable,Isuggestyoureadtheon-linedocumentationforSimpleDateFormatifyouwanttolearnmore.TypicallyIcreateaSimpleDateFormatwiththepatternIwanttouse,andthenformataDatewiththatpattern.You’llgetalotofmileageoutofthatsimpleapproach.

Calendar

CalendarprovidesawrapperfortheDateclasswhichallowsustoedititintermsofitsindividualcomponents,e.g.changethedate,orthemonth,ortheyear,ratherthanworkingdirectlywiththemillisecondtime.

InstantiateanewCalendarusingthestaticgetInstancemethodontheCalendarclass.Calendarcal=Calendar.getInstance();

InitiallyIwillcompareCalendarwithDatesoyougainbasicfamiliaritywithit,thenwewillexplorethemethodsandcapabilitiesinmoredetail.

WehavemanyofthemethodsthatyoualreadyencounteredwithDate,butthemethodsworkwithCalendarparameters:

after-returnstrueiftheparameterisaftertheCalendarbefore-returnstrueiftheparameterisbeforetheCalendar

Page 184: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

equals-returnstrueiftheparameterrepresentsthesamedateandtimeastheCalendar

compareTo-returns0,-veor+ve;iftheparameterisequal,after,orbeforetheCalendar

WehaveamethodgetTimeonCalendarjustaswedidwithDatebutthegetTimemethodonCalendarreturnsaDatesothefollowinglinesareequivalentwhenworkingwithCalendar:System.out.println(cal.getTime().getTime());

System.out.println(System.currentTimeMillis());

TheCalendarmethodtoStringdoesnotprintanicelyformattedversionofthedateandtime,insteaditshowsalltheattributesoftheCalendarObject.

Exercise:WritethetoStringtoconsoleWritean@TestmethodwhichinstantiatesaCalendarobjectandwritestheoutputoftoStringtotheconsole.

IcancontroltheDatedetailsofaCalendarwiththesetTimemethod:CalendarsameDate=Calendar.getInstance();

sameDate.setTime(cal.getTime());

assertThat(cal.equals(sameDate),is(true));

assertThat(cal.compareTo(sameDate),is(0));

SinceI’musingtheDatefromanotherCalendarIcancomparethetwoCalendarswithequalsandcompareToandexpectthemtohavethesamedateandtimedetails.

ToadvancethedateandtimedetailsforaCalendarIcanusetheaddmethod.e.g.toaddon7days,asIdidpreviouslywiththeDate:CalendaroneWeekFromNow=Calendar.getInstance();

oneWeekFromNow.setTime(cal.getTime());

oneWeekFromNow.add(Calendar.DATE,7);

IcanthencomparetheCalendarobjectsaswesawbeforewithafter,before,compareTo.assertThat(oneWeekFromNow.after(cal),is(true));

assertThat(cal.before(oneWeekFromNow),is(true));

assertThat(cal.compareTo(oneWeekFromNow),is(-1));

assertThat(oneWeekFromNow.compareTo(cal),is(1));

SettingCalendarValuesCalendarConstants

Calendarprovidessomeconstantsforworkingwithfieldsinaliteralway:

DATE

YEAR

MONTH

DAY_OF_MONTH

Page 185: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

HOUR

MINUTE

SECOND

etc.

Youcanfindafulllistoftheseconstantsintheon-linereferenceorthroughcodecompletionontheCalendarobject.

Weusetheseconstantswhenweadd,setorgetthefieldsontheCalendar.

setindividualCalendarfieldsWecansetindividualCalendarfieldsusingtheCalendarconstants:cal.set(Calendar.YEAR,2013);

cal.set(Calendar.MONTH,11);//startsat0

cal.set(Calendar.DAY_OF_MONTH,15);

cal.set(Calendar.HOUR_OF_DAY,23);

cal.set(Calendar.MINUTE,39);

cal.set(Calendar.SECOND,54);

cal.set(Calendar.MILLISECOND,123);

SinceitcanbeconfusingtoseeMonthsaszerobasedinthecodetherearealsoconstantsfortheMonthnamesthemselves.cal.set(Calendar.MONTH,Calendar.DECEMBER);

settheCalendarYoucanalsocallthesetmethodwithmultiplefields.Thesearetheninafixedorder:

YearMonthDayofMonthHourofdayMinuteSecond

cal.set(2013,11,15);

cal.set(2013,Calendar.DECEMBER,15);

cal.set(2013,11,15,23,39);

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

Notethatthecombinationsdonotletyousetthehourwithoutalsosettingtheminute.

WecanuseDatetosetthetimeonaCalendarwiththesetTimemethod:cal.setTime(newDate(0L));

WecanalsosettheCalendarfromamillisecondvalueinthesamewaywedidforDate:cal.setTimeInMillis(0L);

WecanalsosettheCalendarfromarelativeperspectiveofweekse.g.Thursdayinthe3rdWeekofJanuary2013:cal.setWeekDate(2013,3,Calendar.THURSDAY);

Page 186: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Theabovesetsthedateto17thJanuary2013.Feelfreetodoublecheckthisonanactualcalendar.

getdetailsfromtheCalendarJustasweusetheCalendarconstantstosetvaluesinaCalendarwecanusethesameconstantstogetinformationfromtheCalendar.

GivenaCalendarsetto15thDecember2013,at23:49and54seconds:cal.set(2013,Calendar.DECEMBER,15,23,39,54);

WecanusetheconstantstoassertthattheCalendarhasbeencreatedasweexpected:assertThat(cal.get(Calendar.MONTH),is(Calendar.DECEMBER));

Exercise:UsetheotherCalendarconstantsWritean@TestmethodwhichinstantiatesaCalendar,andassertonthevaluesyouexpectforthefollowingconstants:

UseaCalendarsetto15thDecember2013,at23:49and54seconds.

Assertonthevaluesyouexpectfor:

MONTH

YEAR

DAY_OF_MONTH

HOUR_OF_DAY

MINUTE

HOUR-AM/PMhourAM_PM-Calendar.AMorCalendar.PM

Exercise:ExperimentwithotherconstantsExperimentwiththeotherconstantssothatyouaresureyouunderstandthem.e.g.confirmthefollowingforthe15thDecember2013:

itisaSundayitisinthe3rdweekinthemonth(0indexbased,so0isthefirstweek)itisthe1stdayintheweekitisinthe50thWeekoftheyearitisthe349thdayintheyear

getmoreinformationfromCalendar

getTime-returnstheCalendarasaDateobjectgetTimeInMillis-returnstheCalendarasalong

ThereareothermethodsonCalendartoretrievemoreinformationaboutthecalendar,butIsuggestyoureadtheon-linedocumentationorcodecompletiontohelpyouunderstandthescopeofalltheinformationyoucanretrievefromthisObject.

Page 187: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Inpractice.ItendtosetupdatesasIneedthem,retrievedates,andthenmovedatesforwardorbackwardsintime.Whichwewillcovernext.

addandsubtracttorolldatesthroughtimeTherearetwomainmechanismswiththeCalendarObjectformovingthetimeinarelativefashion:

add-addorsubtractanamountfromafieldroll-changeasinglefieldwithoutaffectingothers

Wecanuseaddtoincrementordecrementfieldvalues.ForexampleIcouldtakeaCalendardateof23:39anddecrementthehourofthetime:cal.add(Calendar.HOUR_OF_DAY,-1);

assertThat(cal.get(Calendar.HOUR_OF_DAY),is(22));

SimilarlyIcouldincrementtheminutesonthetime:cal.add(Calendar.MINUTE,10);

assertThat(cal.get(Calendar.MINUTE),is(49));

Exercise:IncrementandDecrementotherFieldsExperimentwiththeaddmethodandchangethefieldsindifferentwaystomovethedatefrom23rdDecember2013to3rdJune2011.

WiththerollmethodIcanchangeasinglefield,withoutaffectinganyofthelargerunitse.g.giventhedate15thDecember2013,Icanrollforward17Daysofthemonthtorollovertothe1st,anditwillstillbeDecember2013.IfIweretodothiswithanaddthedatewouldbecome1stJanuary2014becausetheotherfieldswouldadvanceaswelltokeepthedatevalid.cal.roll(Calendar.DAY_OF_MONTH,17);

assertThat(cal.get(Calendar.YEAR),is(2013));

assertThat(cal.get(Calendar.MONTH),is(Calendar.DECEMBER));

assertThat(cal.get(Calendar.DAY_OF_MONTH),is(1));

Exercise:ConfirmaddMovestheYearWritean@Testmethodthatdemonstratesthatadding17,to23rdofDecember2013,insteadofrolling17movesthedateto1stJanuary2014.

SummaryIntheproductionenvironment,inthemainapplication,weveryoftenusetheJoda-Timelibrary.ButI’mtryingtokeepcoverageof‘libraries’outofscopeforthisbook,tomakeiteasierforyoutogetstarted,andtohelpyoubuildknowledgeandexperiencewiththein-builtfeatures.

Page 188: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Relyingtoomuchonexternallibrariesoftenmeansaddinganotherlibraryintothecode-basewhenallthatisreallyrequiredisaquickwrapperaroundexistingcoreJava.

Thechaptercoveredbasicexamplesof:

timinghowlongasetofcodetakestoexecutecreatinguniqueidsandnamesforfilesformattingdatesdatearithmeticandmanipulation

Ifrequentlyhavetoformatdatesindifferentways,whenI’mgeneratinginputdataforapplicationautomation.

Itimethehowlongcoderuns,whenI’mwritingsimpleperformanceautomation.IoftenusenanoTimetodothis.

Iveryoftencreateuniquefile-namesusingthevaluereturnedbycurrentTimeMillis.Yousawexamplesofsimplewaystoconvertthenumericfilenamesintoalphabeticcharacters.Isometimesgenerateuniqueusernamesforinputdatainthisway,withcurrentTimeMillis.

Wealsocoveredbasicdatetimearithmeticinthechapter.Averyusefulthingtobeabletodo,whengeneratingrandomdata.

IthinkI’vecoveredthebasicsofDateandTimeforthecoreJavaclasseswellenoughforyoutostartusingtheminyour@Testmethods.

IhaveonlyeverhadtodropdowntoJoda-Timeonceortwiceinmycareer.Iencourageyoutoexperimentwiththein-builtDateTimefunctionality,beforebringinginanexternallibrary.Youmightbesurprisedhowmuchyoucando.

ReferencesandRecommendedReading

Joda-Timejoda-time.sourceforge.net

currentTimeMillis

docs.oracle.com/javase/7/docs/api/java/lang/System.html#currentTimeMillis%28%29nanoTime

docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime%28%29nanosecond

en.wikipedia.org/wiki/NanosecondDate

docs.oracle.com/javase/7/docs/api/java/util/Date.htmlSimpleDateFormat

docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.htmlCalendar

docs.oracle.com/javase/7/docs/api/java/util/Calendar.html

Page 189: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterEighteen-PropertiesandPropertyFiles

ChapterSummaryInthischapteryouwilllearnhowtousethePropertiesclass

Apropertyfilehas“key,value”pairsoneachlinePropertiesclassmakesiteasytoloadandsave“key,value”pairdatasetPropertymethodtoaddapropertykeyandvaluegetPropertymethodtogetthevalueforapropertykeysizemethodtoreturnthenumberofpropertykeysIteratethroughpropertiesbykeyusingstringPropertyNameslisttodisplaypropertiestooutputcontainsKeycheckifapropertykeyexistsAnintroductiontoJavaSystemproperties

user.dir-currentworkingdirectoryforthecodeuser.home-homedirectoryofcurrentuserline.separator-endofnewlinestringfile.separator-characterseparatorfordirectorypathsjava.io.tmpdir-locationofthecurrenttemporarydirectory

LoadingandSavingPropertyfilesstoretosavepropertyfilesloadpropertyfilesincombinationwithaFileReader

OneoftheearlyproblemsIhadwhenworkingwithJava,wasworkingwithfilesformydata.Filesaren’treallythathard,andwe’llcovertheminalaterchapter,butmyinitialworkaroundwastousepropertyfiles,viathePropertiesclass.

Propertyfilesarethoseverysimplefilesyouseemanytoolsuseforconfiguration,withakey=valuepaire.g.#Definethebrowserstouse

browser=chrome

port=8080

Apropertyfiletreatslinesstartingwith#ascomments.Blanklinesareignored.Lineswithcontentaretreatedas“key,value”pairsseparatedbyan=sign.Ifapropertyfilehasmultipleentrieswiththesamekey,thenonlythelastonewillbeusedtrailingandleadingspacesbeforeandaftereitherthekeyorthevalueareignored,e.g.thefollowingentriesareallequivalent

browser=chrome

browser=chrome

browser=chrome

IntheearlydaysIwouldveryoftenusePropertyfilesasinputfileswhichIdidn’thavetostruggletoparsee.g.

Page 190: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

step1=OPEN_APP

step2=TYPE12345

step3=CLICK_ENTER

step4=CLOSE_APP

Youcanprobablyguessthattheaboveexampleisasimplekeyworddrivenscript.Idon’trecommendthisapproach,I’mjustpointingoutthatwhenIwaslearningJava,IusedthebasicknowledgethatIhadtogetthingsdone,withoutworryingtoomuchaboutthe‘best’wayofdoingit.AndProperties,withassociatedpropertyfiles,madecertainthingseasy.

PropertiesBasicsTheJavaPropertiesobjectinjava.util.PropertiesisthemainclasswewilluseforworkingwithProperties.

Itworksmuchlikeahashmap,witha“key,value”pair,wherebothkeyandvalueareStringobjects.

Propertiesalsohasadditionalmethodsforloadingandsavingthepropertiestofiles.

Warning:Don’tgocrazyWhenIfirstlearnedaboutPropertiesIthinkIwentabitcrazyandusediteverywhere.IuseditinsteadofusingaMap.Insteadofdefiningallparametersinmethods,IjuststuckeverythinginaPropertiesobjectandpassedthatintothemethod.Idon’tdothisanymore.Andneithershouldyousinceyoualreadyknowhowtousethecollectionclasses.

CreatingnewPropertiesWecreatenewPropertiesobjectsusingthePropertiesclassfromjava.util.Properties

Propertiesproperties=newProperties();

TheabovewillgiveusaPropertiesobjectwithnoproperties.i.e.sizeof0assertThat(properties.size(),is(0));

SettingandGettingPropertyvaluesUsethesetPropertyandgetPropertymethodstosetandgetpropertyvalues:properties.setProperty("browser","firefox");

properties.setProperty("port","80");

setPropertywillcreatethepropertyifitdoesnotexist,oroverwritethevalueofthepropertyifitalreadyexists.

getPropertyreturnsthevaluefortheproperty:assertThat(properties.getProperty("browser"),

is("firefox"));

assertThat(properties.getProperty("port"),

is("80"));

IfthepropertykeyweprovidetogetPropertydoesnotexistthennullwillbereturned.

Page 191: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat(properties.getProperty("missing"),

is(nullValue()));

WhenwecallgetPropertywecanspecifyadefaultvalue,sothatwedon’treceive‘null’,insteadwereceivethedefaultvalueifthepropertykeyhasnotbeenset.assertThat(properties.getProperty("missing","default"),

is("default"));

WorkingwithPropertiesGenerally,ifwehavesetupthepropertiesthenwewillworkwiththegetPropertymethod.

But,sometimesyouwanttoworkwiththePropertiesusingthesetofkeys.WeusethestringPropertyNamesmethodforthis:

IfIwanttoiterateoverthepropertykeysandoutputallthevalues,thenIcaniterateovertheSetofStringpropertykeys:for(Stringkey:properties.stringPropertyNames()){

System.out.println("Key:"+key+""+

"Value:"+properties.getProperty(key));

}

Theabovewouldoutput:Key:portValue:80

Key:browserValue:firefox

ThePropertiesclasshasamethodcalledlistwhichoutputsthepropertynameandvaluepairtothegivenprintstream:properties.list(System.out);

Callingthelistmethodwouldoutput:--listingproperties--

port=80

browser=firefox

IalsocheckforpropertyexistencewiththecontainsKeymethod:assertThat(properties.containsKey("browser"),is(true));

Exercise:CreateandListaPropertiesobjectWritean@Testannotatedmethodwhich:

CreatesaPropertiesobjectAddthefollowing“key,value”pairs:name=bob,gender=male,password=paSSw0rdAssertthatthesizeofthePropertiesobjectis3Outputthe“key,value”pairstotheconsolebyiteratingoverthekeysUsethelistmethodtooutputthepropertiesAssertthatthePropertiesobjectcontainsthekeygenderAssertthatthevalueofthepropertynameisbobUsegetPropertywithadefaultvalueandassertthatthevalueofkey"permission"is"Admin"

Page 192: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Java’sSystemProperties

ReadingSystemPropertiesJava’sSystemobjecthasasetofpropertiesthatcomeinveryhandwhenwritingautomationcode.

e.g."user.dir"returnstheworkingdirectoryfortherunningapplicationStringworkingDirectory=System.getProperty("user.dir");

IcanusethisforaccessingdatafilesthatIwanttouseinmyautomatione.g.ifIcreateadirectoryinmyprojectcalledproperty_filesunder/src/test/resources/thenIcouldbuildthefullpathtoafilebyprefixingthecurrentworkingdirectory:StringresourceFilePath=workingDirectory+

"/src/test/resources/"+

"property_files/"+

"static_example.properties";

YoucanworkdirectlywiththePropertiesobjectonSystem,byusingthegetPropertiesmethod.

ForexampleifIwantedtolisttheSystempropertiesthenIcanusethefollowingcode:Propertiessys=System.getProperties();

sys.list(System.out);

Apartialoutputoftheabovecommandisshownbelow:--listingproperties--

java.runtime.name=Java(TM)SERuntimeEnvironment

sun.boot.library.path=C:\ProgramFiles\Java\jdk1.7.0_10\jre...

java.vm.version=23.6-b04

java.vm.vendor=OracleCorporation

java.vendor.url=http://java.oracle.com/

path.separator=;

java.vm.name=JavaHotSpot(TM)64-BitServerVM

Exercise:OutputtheSystemPropertiesobjectWritean@TestannotatedmethodwhichwilllistthecontentsoftheSystemProperties

ReadtheSystemPropertiesdocumentationsoyouunderstandtherangeofpropertiesavailableforyoutousebydefault.

docs.oracle.com/javase/tutorial/essential/environment/sysprop.html

SystempropertiesIusemostoftenare:

user.dir-currentworkingdirectoryforthecodeuser.home-homedirectoryofcurrentuserline.separator-endofnewlinestringfile.separator-characterseparatorfordirectorypathse.g.\onwindows,/onlinuxjava.io.tmpdir-locationofthecurrenttemporarydirectory

Page 193: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

SettingSystemPropertiesYoucansetSystemproperties,thesameasyoucanwithanormalPropertiesobjectusingthesetPropertycommand.

IfrequentlydothisifIwanttocontrolsomeenvironmentalconfigurationfromwithinmyrunningcode.

Asanexample,whenusingWebDriverandworkingwithChrome,IhavetosetaSystemproperty,sothattheChromedriverknowswheretofindtheChromeDriver.exethatitusestocontroltheChromebrowser.

webdriver.chrome.driver

Igenerallydon’taddtheChromeDriver.exeintoversioncontrolandhaveaconventionthatitislocatedinadirectoryrelativetomyworkingdirectory.SoIsetthepropertyrelativetomyworkingdirectory.

Sincethisisapropertythatmighthavebeensetalready,ItendtocheckifithasbeensetoutsidetherunningapplicationbeforeIoverwriteit.Leadingtocodelikethefollowing:if(!System.getProperties().containsKey("webdriver.chrome.driver")){

StringcurrentDir=System.getProperty("user.dir");

StringchromeDriverLocation

=currentDir+

"/../tools/chromedriver/chromedriver.exe";

System.setProperty("webdriver.chrome.driver",chromeDriverLocation);

}

IntheabovecodeIfirstcheckifthepropertyisset,ifitisthenIdon’toverwriteit.IfthepropertyisnotsetthenIusethecurrent"user.dir"andsetthepathrelativetothatworkingdirectory.

WorkingwithPropertyfilesInthissectionwearegoingtolookatthemethodsonthePropertiesObjectassociatedloadingandsavingfiles.

SavePropertiesdoeshaveasavemethod,butthisisdeprecatedbecauseitdoesnotthrowanIOException.

DeprecatedDeprecatedmeansthatthemethodshouldnotbeused,andthatthemethodmayberemovedinfutureversionsofJava.Themethodwillwork,butyourcodemayfailinthefuturewhenyouupdatetheJavalibraryorSDKyouareusing.

Insteadweusethestoremethod,whichwritesthefiletoaWriteroranOutputStream.

BecauseIwillcreateafilethatI’monlyusingaspartofthe@Testmethodexecution,I’mgoingtocreateitasatemporaryfile.

Page 194: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Java7providesawayofcreatingtemporaryfiles,whichwewillcoverintheFilesChapter.

SincethisisthePropertieschapter,wewillusetheSystemproperty"java.io.tmpdir"whichreturnsthepathofthesystemtempdirectory.StringtempDirectory=System.getProperty("java.io.tmpdir");

StringtempResourceFilePath=

tempDirectory+

"tempFileForPropertiesStoreTest.properties";

Wethenneedtocreatethepropertiesthatwewillstoretothefile:Propertiessaved=newProperties();

saved.setProperty("prop1","Hello");

saved.setProperty("prop2","World");

WeneedtocreateaFileOutputStreamtostorethepropertiesinto,andwritethemwiththestoremethod.ThestoremethodleavestheOutputStreamopensowehavetocloseitwhenwearefinishedwithit.FileOutputStreamoutputFile=

newFileOutputStream(tempResourceFilePath);

saved.store(outputFile,"HelloThereWorld");

outputFile.close();

Notethatthestoremethodtakestwoparameters:

theOutputStreamthatwewritethedetailstoacommentString

TheStringcommentiswrittentotheOutputStreampriortotheproperties,andinadditionaTimeStampforwhenthepropertiesarewrittenisaddedtothefile.

Sothefinalfileoutputfromtheabovemethodexecutionlooksasfollows:1#HelloThereWorld

2#MonAug0515:12:24BST2013

3prop2=World

4prop1=Hello

Notethatthepropertyorderingisnotretainedwhenwritingtothefile.

LoadSinceIhavealreadycreatedafileinmyproject(usingthestoremethod),allIhavetodoisloaditfromthedirectoryIsaveditto.

IcanuseeitheranInputStreamoraFileReaderforthis.WewillcovertheseinmoredetailintheFilesChapter.Butfornow,wewilluseaFileReader.FileReaderpropertyFileReader=

newFileReader(tempResourceFilePath);

Propertiesloaded=newProperties();

try{

loaded.load(propertyFileReader);

}finally{

Page 195: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

propertyFileReader.close();

}

Ihavewrappedtheloadmethodinatry/finallyblock,becausetheloadmethodleavestheInputStreamorFileReaderopenwhenitfinishes,sowehavetocloseit.AndIwantittocloseeveniftheloadmethodthrowsanIOException.

OncethepropertyfilehasloadedintothePropertiesobject,IcanaccessthepropertywiththegetPropertymethodaswedidbefore:assertThat(loaded.getProperty("prop1"),is("Hello"));

assertThat(loaded.getProperty("prop2"),is("World"));

DeleteFilesWewillcoverfilesinmoredetailinalaterchapter.Butfornow,sincewehavecreatedafile.Weshouldlearnhowtodeleteit:newFile(tempResourceFilePath).delete();

Exercise:StoreandLoadaSavedPropertiesFileUsingthecodepresentedabove:

CreateaPropertiesobjectAddsome“key,value”pairstothePropertiesStorethePropertiesfileinthe"java.io.tmpdir"ReadthePropertiesfileandassertonthevaluesDeletethePropertiesfilewhenyouarefinished

SummaryIstillfindpropertyfilesveryusefulandbeforewritingcomplicatedfileparsingandstoringroutines.IfirstseeifIcanprototypeanyfilestoragefunctionalitywithpropertyfiles.

Propertyfileshavetheadvantagethattheyareeasytoeditbyhumans,sincetheyareasimpleformatoftextfile.

Theyarealsoeasytoparsefortheapplicationcode.

ReferencesandRecommendedReading

Propertiesofficialdocumentation-docs.oracle.com/javase/7/docs/api/java/util/Properties.html

PropertiesJavaTutorialdocs.oracle.com/javase/tutorial/essential/environment/properties.html

SystemPropertiesofficialdocumentationdocs.oracle.com/javase/tutorial/essential/environment/sysprop.html

CreateaTemporarydirectoryinJavastackoverflow.com/questions/617414/create-a-temporary-directory-in-java

Page 196: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterNineteen-Files

ChapterSummaryInthischapteryouwilllearnhowtousethebasicJavafilehandlingclasses

FilethegeneralwrapperforafilecreateTempFile-createatemporaryfilecreateNewFile-createthefiledelete-deletethefilenowdeleteOnExit-deletethefilewhentheapplicationclosesgetName-returnthefilenameordirectorynamegetParent-returnthepathoftheparentdirectorygetAbsolutePath-returnthefullfilenameandpathgetCanonicalPath-returntheuniquefullrepresentationoftheFilemkdir-createsasingledirectorymkdirs-createsadirectoryandallnecessarydirectoriesinthepathisDirectory,isFile-determingtypeofphysicalFileseparator,pathSeparator-forfilese.g.‘\’andPathe.g.‘;’listRootsanarrayoftherootpathsinthefilesystemlength-thelengthoftheFileinbytesgetFreeSpace,getTotalSpace,getUsableSpace-diskspacerenameTo-renameafileDirectorymethods

list-alistofthefilenamesasStringlistFiles-alistofFileobjectsforeachfileanddirectory

AttributemethodscanRead,canWrite,canExecute,lastModifiedsetExecutable,setReadable,setWritable,setReadOnly,setLastModified

FilesclasswithstaticmethodstocopyandmoveafileordirectoryPrintWriter-hasmethodstomakewritingeasiere.g.print,printlnFileWriter-writetocharacterbasedfilesBufferedWriter,BufferedReader-bufferoutputandinputforefficiencyFileReader-readfromaninputstream

Itendtokeepmyfilecodeassimpleaspossible,becausemyusecasesareusuallyfairlysimple:

readingfilesthatotherpeoplehavewritten-sometimestocheckvalidityofthedatareadingsimpleCSVortabdelimitedfiles-oftenasinputtodatadrivencheckscopyingfiles-tokeepafolderofdatausedduringautomation,orforsetupdatacreatingdirectories-tomakemywork-flowsimplermovingfiles-screenshotimages,logfilesdeletingfileswritingreport-simplelogfilesorHTMLreportoutput

InthischapterI’llcoverthebasicclassesandapproachesforimplementingtheaboveusecases.

Page 197: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ExampleofreadingandwritingafileIwillquicklyshowyousomecodethatwritesafile,andreadsthesamefile.

Ifyouwanttoimmediatelyexperimentthenfeelfree.Therestofthechapterwillworkthroughthevariousmethodsandclassesused,explainingtheminmoredetail.

WriteaTempFileprivateFilewriteTheTestDataFile()throwsIOException{

FileoutputFile=File.createTempFile("forReading",null);

PrintWriterprint=newPrintWriter(

newBufferedWriter(

newFileWriter(outputFile)));

for(intlineNumber=1;lineNumber<6;lineNumber++){

print.println("line"+lineNumber);

}

print.close();

returnoutputFile;

}

Theabovecode,createsatemporaryfile,inthesystem‘Temp’directory.

e.g.forReading2536453396676632859.tmpin%TEMP%(onWindows)

Ituses3classestowraparoundthefile:FileWriter,BufferedWriterandPrintWriter.Thenprints5linesoftexttothefile,closesthefile,andreturnstheFiletothecallingmethod.

Readthetempfile@Test

publicvoidoutputFileToSystemOutWithBufferedReader()throwsIOException{

FileinputFile=writeTheTestDataFile();

BufferedReaderreader=newBufferedReader(newFileReader(inputFile));

try{

Stringline;

while((line=reader.readLine())!=null){

System.out.println(line);

}

}finally{

reader.close();

}

}

Thecodeabove,callsthewriteTheTestDataFilemethodtocreateatemporaryfile.ThenitusesthereturnedFile,andwrapsitwithaFileReaderandaBufferedReader,thenreadseachlineandprintsitout.

Itwrapsthereadingcodeinatry/finallyblockwhenreadingtomakesurethatthefileactuallyclosesifanexceptionisthrown.

BasicNotes

Page 198: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Itseemslikealotofclassesareinvolvedthere.Butasyouwillseelater,theybuildoneachothertomakethereadingandwritingoffileseasyforyou.

Ifyoustartbycopyingthecodeabove,andamendingitslightly,youcanprobablymeetatleast3oftheusecasesImentionedatthetopofthischapterasmycommonusecases.

Andyoucouldprobablyfigureouttheotherusecasesbyreadingthecontextsensitivecodecompletionontheclasses.

Theremainderofthischapterwillcovereachoftheclassesinvolvedinmoredetail.

FileTheFileclassprovidesthemainclasstorepresenta‘file’or‘directory’andmethodsforcreatingdirectoriesandotherlocalfileactions.

TheFileclassalsoprovidesasetofstaticmethodsthatcanhelpus.

Fileisinthejava.iopackage.

StaticMethods

createTempFile

createatemporaryfileinthesystem’stemporarydirectory(onWindowsthisis‘%TEMP%’)

separator

theseparatorforfilevaluese.g.‘\’pathSeparator

thesystemseparatorinthePathe.g.‘;’listRoots

anarrayoftherootpathsinthefilesystem

IonlyreallyusethecreateTempFileandseparatorbutwillcoveralltheabovemethods.createTempFile

FileoutputFile=File.createTempFile("forReading",null);

Thismethodcreatesanemptyphysicalfileinthesystemtemporarydirectory(%TEMP%).

IntheaboveexampleIassigntheFileintoavariablecalledoutputFilesothatIcanuseit.

Themandatoryparameterstothismethodare:

prefix

e.g.forReading.Theprefixneedstobe3charsorlongerotherwiseandexceptionisthrown:

java.lang.IllegalArgumentException

suffix

Thevaluetoaddattheendofthetempfilename.Ifyouleavethisasnullthenthefilewillbegiventhesuffix.tmpbutyoucanaddyourownsuffixifyouwantto.

Page 199: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IntheaboveexampleIpassinaprefixofforReading,andnullforthesuffix,sotheendresultisanemptyfilewithanamelike:

forReading16535777254649642741.tmp

ThenumberisaddedbytheJavamethodtotryandmakethefilenameuniqueinthetempfolder.

Theoptionalfinalparametertothismethodis:

directory

AFileobjectforthedirectorytocreatethetempfilein.

aTempFile=File.createTempFile("pre",null,

newFile(System.getProperty("user.dir")));

Intheabovecode,Ileftthesuffixasnullsoitwilluse‘.tmp’asthesuffix,andwillcreatethefileintheUserDirectorywhereIamrunningthecode.Onmysystemthiscreatedafilenamedandlocatedasfollows:D:\Users\Alan\Documents\javaForTesters\pre4051399336820173102.tmp

Exercise:CreateaTempFileandVarytheParametersWritean@Testmethodwhichcreatesatempfile.

FindthefileinyourSystem’stemporarydirectoryandmakesureitwaswritten.

Varytheprefix,andthesuffixtoseetheimpactoftheoutputfile.

separatorandpathSeparator

TheseparatormethodisthemainoneIuse,sinceitprovidestheseparatorbetweenvaluesinfilepaths,i.e.thedirectoryseparator‘\’onWindowsand‘/’onLinux.

IusethiswhenbuildingupStringvaluestoactaspathsforfiles.Assert.assertTrue("UnrecognisedOSfileseparator",

File.separator.equals("\\")||

File.separator.equals("/"));

Assert.assertTrue("UnrecognisedOSpathseparator",

File.pathSeparator.equals(";")||

File.pathSeparator.equals(":"));

ThepathSeparatoristhevalueyouuseinthePATHvariables.

TheseparatorandpathSeparatorreturnsystemdependentvaluessohelpyoumakeyourcodeplatformagnostici.e.runonLinuxorWindows.listRoots

listRootsreturnsanarrayofFileobjectswhichrepresentthe‘root’filepathsinthesystem.File[]roots=File.listRoots();

Page 200: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Onmywindowssystemthisreturnsalistofthe‘drives’onmysystem,e.g.:C:\

D:\

E:\

F:\

G:\

HaveIeverusedthismethod?No.Butitmightcomeinhandyforsomeone.

Exercise:WriteouttherootsWritean@TestmethodwhichprintstoSystem.outtheresultofcallingthegetAbsolutePathmethodoneachoftheFileobjectsreturnedbylistRoots.

ConstructorAndBasicOperationsFileaTempFile=newFile("d:/tempJavaForTesters.txt");

TheabovecodeshowsthesimplestconstructorfortheFileobject.SimplycreateanewFilewiththepathyouwanttouse.

Filewillconvert‘/’to‘\’Notethat,IhaveusedtheLinuxformatforthefilepath,eventhoughIprimarilywrotethebookonaWindowsmachine.

TheFilecanconvertfrom/to\ifyouareworkingonadifferentplatform.

Ifyouwrotean@Testmethodwiththeabovecode,thenuponrunningit,youwillnotethatinstantiatingaFileobject,doesnotcreateaphysicalfileonthedisk.@Test

publicvoidaNewFileDoesNotCreateAFile()throwsIOException{

FileaTempFile=newFile("d:/tempJavaForTesters.txt");

assertThat(aTempFile.exists(),is(false));

}

IusedtheexistsmethodontheFileobjecttocheckexistence.

TheFileobjectcreatesarepresentationofthe‘file’or‘directory’,andallowsustointeractwiththefile.

Weuse‘streams’,‘readers’or‘writers’tointeractwiththeactualfilecontent.

TheFileobjecthasmethodsforfilecreationanddeletion:

createNewFilewillcreatethefiledeletewilldeletethefile

e.g.@Test

publicvoidcreateAFileAndDeleteIt()throwsIOException{

FileaTempFile=newFile("d:/tempJavaForTesters.txt");

Page 201: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat(aTempFile.exists(),is(false));

aTempFile.createNewFile();

assertThat(aTempFile.exists(),is(true));

aTempFile.delete();

assertThat(aTempFile.exists(),is(false));

}

Anotherformoftheconstructorallowsustopassinthefilepathandthefileasseparatearguments.FileaTempFile=newFile("d:","tempJavaForTesters.txt");

NotethatIdon’thavetoworryabouttrailingdirectoryseparatorswhenIusebothparametersintheFileconstructor.

Fileoperationscanthrowavarietyofexceptionsbutthejava.io.IOExceptionisacatchallfortheexceptionsthatarelikelytobethrown.

Inthisshortsectionwecovered:

TwoFileConstructorsexistsmethodtocheckifafileordirectoryexistsdeletetodeleteafileordirectorycreateNewFiletocreateanemptyfile

Exercise:CreateaTemporaryFileWithCustomCodeSimulatethecreateTempFilemethodusingthenormalFileobjectandthecreateNewFilemethod.

Hints:Thesystemtemporarydirectoryisaccessiblefromthe“java.io.tmpdir”Systemproperty.

UseSystem.currentTimeMillistocreatea‘unique’numberaspartofthefilename.

OtherBasicMethodsThebasicmethodsonFileweneedtolearninitiallyare:

deleteOnExit-deletethefilewhentheapplicationclosesgetName-thefilenameordirectorynamegetParent-thepathoftheparentdirectorygetAbsolutePath-thefullfilenameincludingroot,folderhierarchyandfilenameusedtocreatetheFilegetCanonicalPath-theuniquefullrepresentationoftheFilemkdir-createsasingledirectorymkdirs-createsadirectoryandallnecessarydirectoriesinthepath

deleteOnExit

AssoonasyouhaveaFileyoucanaddittothe‘deleteonexit’queue.FileaTempFile=File.createTempFile("prefix","suffix");

aTempFile.deleteOnExit();

Page 202: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Whentheapplicationfinishes.Whenallthe@Testmethodshaverun.Allfilesinthe‘deleteonexit’queuewillbedeleted.

ThisisausefulmethodtocombinewiththecreateTempFilemethodbecauseitmeansyourtemporaryfilesaredeletedaftertherunofthe@Testmethod.Ratherthanrelyingonyouroperatingsystemtemporarydirectorycleanuproutines.

getName,getParent,getAbsolutePath,getCanonicalPath

IfIcreateatempfile:FileaTempFile=File.createTempFile("prefix","suffix");

Idon’tknowexactlywhatthenameofthatfileis.

WhenworkingwiththeFileobjectaTempFile.Idon’tneedtoknowtheactualnamebecauseIoperatewiththeFileobjectdirectly.

IfIdowanttoworkwiththenameorpath,thenIcanusethemethods:

getName,getParent,getAbsolutePathandgetCanonicalPath.

getNamereturnsthefilename,withoutthepath.SofortheexampleaboveIwouldhaveafilenamelikeprefix12345678901234567890suffixcreated.assertThat(aTempFile.getName().startsWith("prefix"),is(true));

assertThat(aTempFile.getName().endsWith("suffix"),is(true));

getParentreturnsthepathstructurefortheparentdirectory.assertThat(aTempFile.getParent()+File.separator,

is(System.getProperty("java.io.tmpdir")));

getAbsolutePathandgetCanonicalPathbothreturnthefullpath,includingthefilenameoftheFile:assertThat(aTempFile.getAbsolutePath().endsWith("suffix"),

is(true));

assertThat(aTempFile.getAbsolutePath().startsWith(

System.getProperty("java.io.tmpdir")),is(true));

assertThat(aTempFile.getCanonicalPath().endsWith("suffix"),

is(true));

assertThat(aTempFile.getCanonicalPath().startsWith(

System.getProperty("java.io.tmpdir")),is(true));

An‘absolute’pathwoulddisplayanyrelativefileoperatorsinthename,e.g.‘../..’but‘canonical’wouldnot.

Canonicalistheuniquepath,soanyrelativeelementsaremadeabsolute.

e.g.thefollowingabsolutepaths:

C:/1/2/3/4/../../..

C:/1/2/../../1

Page 203: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

wouldberepresentedasthefollowingcanonicalpath

C:/1

Exercise:Writean@TestmethodToCheckCanonicalConversionWritean@TestmethodwhichcheckstheassertionthattheabsolutepathsbelowarerepresentedbythecanonicalpathC:/1:

C:/1/2/3/4/../../..

C:/1/2/../../1

DothisbycreatingaFileforeachpath.ThencomparingthevaluesfromgetAbsolutePathwithgetCanonicalPath.

mkdirandmkdirs

Bothmkdirandmkdirsareusedforcreatingdirectories.

Bothmkdirandmkdirsreturneithertrueorfalsetoletyouknowiftheymanagedtocreatethedirectory.

Thedifferencebetweenthemisthatmkdirwillcreateasingledirectory,butonlyiftheparentpathalreadyexists.

mkdirswillcreatethenecessaryparentdirectoriestoallowtheoperationtosucceed.

Anexample

IfIwanttocreateadirectorystructureinthetempdirectorylikethefollowing:

%TEMP%1234567890

0987654321

Theexisting%TEMP%directory,withasubdirectory‘1234567890’,andanothersubdirectory‘0987654321’.WhereeachofthesenumbersissupposedtorepresentacalltoSystem.currentTimeMillis()

StringtempDirectory=System.getProperty("java.io.tmpdir");

StringnewDirectoryStructure=tempDirectory+

System.currentTimeMillis()+

File.separator+

System.currentTimeMillis();

FileaDirectory=newFile(newDirectoryStructure);

Acalltomkdirwillfail,becausethemiddledirectory‘1234567890’doesnotexist,andmkdirwillonlycreatethefinaldirectory,inourexample‘0987654321’.mkdirneedstherestofthedirectorystructuretoexist.assertThat(aDirectory.mkdir(),is(false));

Acalltomkdirswillpass,becauseitwillcreateanynecessarydirectoriesinthedirectorystructure.assertThat(aDirectory.mkdirs(),is(true));

Page 204: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

UsefulChecks

ForaparticularFileobject,youcancheckifitisafileordirectoryusingthefollowingmethods:

isDirectoryreturnstrueiftheFileobjectisadirectoryisFilereturnstrueiftheFileobjectisafile

Exercise:CheckthattheTempDirectoryisaDirectoryCreateaFileobjectthatrepresentsthetemporarydirectory.System.getProperty("java.io.tmpdir")

AssertthatisDirectoryreturnstrueandisFilereturnsfalse.

WritingAndReadingFiles

WritingTextFilesJavaprovidessomewrapperclasseswhichhidelowerlevelinputandoutputclassestomakereadingandwritingfileseasier.

Yousawtheuseofthoseintheinitialexamplesinthechapter.

FileWriterisawrapperaroundFileOutputStreamforcharacterbasedfiles.e.g.textfiles.BufferedWritermakeswritingmoreefficientbywaitinguntilthebufferisfullandthenflushingthebuffertothewriter.Forfilewritingthisqueuesupthewritingofbytestothefile.PrintWriterprovidesconveniencemethodsforwritinglinestofilesforhumanreadableoutput.e.g.println,print

Forexample:FileoutputFile=File.createTempFile("printWriter",null);

FileWriterwriter=newFileWriter(outputFile);

BufferedWriterbuffer=newBufferedWriter(writer);

PrintWriterprint=newPrintWriter(buffer);

YoucanappendtoexistingfilesbycreatingtheFileWriterwithanappendparametersettotrue.writer=newFileWriter(outputFile,true);

WritingwithaPrintWriter

UsingaPrintWriteristhesameasusingtheSystem.out.printlnthatyouhaveseenthroughoutthebook.

Wecanwritealinetothefilebyusingprintlnprint.println("SimplePrinttoBufferedWriter");

print.println("===============================");

Page 205: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ByusingthePrintWriterandprintlntowritetextfiles,wedon’thavetoworryaboutendoflinecharactersasitwillusetheappropriateendoflineforthesystem.

Youcanalsoaddtothefilewithoutanewlineusingprint.

Justremembertoclosethefilewhenyouhavefinishedwritingtoit.

Exercise:WritetoaPrintWriterthenAppendCreateatempfile.ThenusePrintWritertoprintlntexttothefile.Remembertoclosethefile.

Afteryouhaveclosedit,re-openthefile,bycreatinganewFileWriter.Thistimesettingtheappendparametertotrue.Then:

printlnsomenewlinestothefile.closethefile.manuallyopenthefileinatexteditortocheckthatyourlinewasappendedtothefile.

WritingwithaFileWriter

YoucanwritefilesdirectlywithaFileWriter.FileoutputFile=File.createTempFile("fileWriter",null);

FileWriterfileWriter=newFileWriter(outputFile);

fileWriter.write("SimpleReportWithOutputWriter");

fileWriter.write("===============================");

fileWriter.close();

Sincethisisarawtextwriter,therearenolineendingsaftereachline,astherewerewiththePrintWriter’sprintlnsotheoutputfilewouldlookasfollows:SimpleReportWithOutputWriter===============================

ReadingTextFiles

FileReaderisawrapperaroundInputStreamReaderandFileInputStreamwhichusesthedefaultcharacterencodingstream.BufferedReadermakesthereadingmoreefficient.

UsethereadLinemethodtoreadthenextlinefromthefileintoastring.

IfwehavereachedtheendofthefilethenreadLinewillreturnnull.

AdditionalFileMethodsTheFileobjecthasalotofveryusefulmethodsforaccessingthevariouspropertiesofthefile.

SpaceThefollowingmethodsonfilescanbeusedtofindinformationaboutthesizeofthefile,orthediskthefileislocatedon.

Rememberthelengthcontainstheendoflinecharactersaswell.

Page 206: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

length-thelengthoftheFileinbytesgetFreeSpace-numberofbytesoffreespacegetTotalSpace-numberofbytesoftotalspacegetUsableSpace-numberofbytesofusablespace

Exercise:CreateaFileandCalculatethelengthCreateafileandcalculatetheexpectedfilelength.

Hint:UseSystem.lineSeparator()togetthelineendcharacter(s).

DirectoryMethodsForaparticularFilethatrepresentsadirectory.Youcangetalistofthefilescontainedinthedirectory.

listwillreturnalistofthefilenamesasStringlistFileswillreturnalistofFileobjectsrepresentingeverycontainedfileanddirectory

e.g.togetalistofthefilenamesfortheitemsinthetempdirectoryIcouldusethelistmethod:@Test

publicvoidlistTempDirectory(){

FiletempDir=newFile(System.getProperty("java.io.tmpdir"));

String[]fileList=tempDir.list();

for(StringfileInList:fileList){

System.out.println(fileInList);

}

}

Exercise:UselistFilestoshowtheTempDirectorycontentsUsethelistFilesmethodonFiletooutputthenameofeachfileinthetempdirectory.

Foreachfile,alsowritebesideit“DIR:”ifitisadirectoryand“FIL:”ifitisafile.

AttributesYoucancheckandamendthefileAttributeswiththefollowingmethods.

canRead-trueifthefileisreadablecanWrite-trueifthefileiswritablecanExecutetrueifthefileisexecutablelastModified-thelastmodifieddateasalong

Youcansettheaboveattributesusingthemethodsbelow:

Page 207: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

setExecutable

setReadable

setWritable

setReadOnly

setLastModified

Exercise:OutputAttributesofFilesInTempDirectoryExtendthe@TestmethodyouwroteforlistFilestoalsooutputtheread,write,executeattributes,andthelastmodifieddate.

FilesFilesispartofthejava.niopackage.niobeingthe“NewIO”classes,introducedinJava1.4;sonotreallythatnewanymore,buttheyaddsomeusefulfunctionalitythatweoftenlookforotherlibrariestomanage.

Theniopackageoffersalotofmethods,butwewillprimarilylookattheFilesmoveandcopymethods.

copy-willcreateacopyofafileordirectorymove-willmoveafileordirectory,creatinganewoneanddeletingtheold

RenamevsMoveFilehasa‘renameTo’method,butItendtousethemovemethodonFiles,evenwhenIwanttorenameafile.

moveandcopycanbeusedtomoveandcopyentiredirectorytrees.

BothmoveandcopyoperateonPathobjectsratherthanFileobjects.FortunatelytheFileobjecthasatoPathmethodwecanusetoreturnaPathobject.Files.copy(copyThis.toPath(),toThis.toPath());

Bothmoveandcopycantakeanoptionalparameterlistwhichspecifiesthe‘copyoptions’.

Thecopyoptionsarecontainedinjava.nio.file.StandardCopyOption.soyouhavetoaddanadditionalimporttoyourclass.importstaticjava.nio.file.StandardCopyOption.*;

Whenyouimportthecopyoptionsyoucanuse:

REPLACE_EXISTING-willallowtheoperationtocompleteevenifdestinationexistsCOPY_ATTRIBUTES-preservethefileattributesduringthecopyATOMIC_MOVE-anyoperatingsystemfollowonfileactionswaittillthemoveiscomplete

Themovebelowusescopyoptions:

Page 208: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Files.move(moveThis.toPath(),toThis.toPath(),

REPLACE_EXISTING,ATOMIC_MOVE);

Exercise:copyAndmoveaFileWriteafiletothetemporarydirectoryandcopyittoanewfilewitha“.copy”suffix.Writeafiletothetemporarydirectoryandmoveittoanewfilewitha“.moved”suffix.

SummaryWehaven’tcoveredallthemethodsavailableforworkingwithfiles.

IrecommendyouusecodecompletionandtheofficialhelpdocumentationtoexploretheclassesavailabletoyouontheJavainputoutputpackages.Doreadthe‘JavaIOOfficialDocumentation’linkedtointheReferencessection.

Themethodsandclasseswecoveredinthischaptershouldgiveyouenoughinformationfortacklingtheinitialproblemsyouwillneedforautomationtosupportyourtesting.

Certainlyyoushouldbearmedwithenoughinformationtoreadandwritetextfiles:eitherforinputdataorforwritingad-hocreports.

Readthepageslinkedtobelow.ThereisarichsetoflibrariesinJavacoreforworkingwithfiles.

AlsointhischapterweconcentratedonworkingwithtextfilessinceIsuspectthatmostofthefilesyouwillhavetoparseandwritewhileautomatingwillbetextfiles.

ReferencesandRecommendedReading

JavaIOOfficialDocumentationdocs.oracle.com/javase/tutorial/essential/io/index.html

JavaFileOfficialDocumentationdocs.oracle.com/javase/7/docs/api/java/io/File.html

JavaFilesOfficialDocumentationdocs.oracle.com/javase/7/docs/api/java/nio/file/Files.html

JavaNiovsJavaIOblogs.oracle.com/slc/entry/javanio_vs_javaio

BufferedWriterdocs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html

PrintWriterdocs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html

Readingandwritingfilepracticeswww.javapractices.com/topic/TopicAction.do?Id=42

Differentwaysofreadingfilesstackoverflow.com/questions/4716503/best-way-to-read-a-text-file

Copydocs.oracle.com/javase/tutorial/essential/io/copy.html

Page 209: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Movedocs.oracle.com/javase/tutorial/essential/io/move.html

Page 210: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTwenty-MathandBigDecimal

ChapterSummaryInthischapteryouwilllearnhowtouseadditional‘number’classes:

BigDecimal-aclassthatoffersaccuratemathoperationswithoutrounding,importantforfinancialapplications

subtract-amethodtosubtractavaluefromtheBigDecimaladd-amethodtoaddavaluetotheBigDecimalmultiply-amethodtomultiplytheBigDecimalbythevaluedivide-amethodtodividetheBigDecimalbythevaluevalueOf-astaticmethodtoreturnaBigDecimalrepresentingthesupplieddoubleorlongBigDecimaldoesnotsupport==,!=,<,>etc.insteadusethemethodsequalsandcompareTo

Math-aclassthathasadditionalmethodsforworkingwithfloatanddoublemax-comparetwovaluesandreturnthelargermin-comparetwovaluesandreturnthesmallerabs-returntheabsolutevaluerandom-returnarandomnumber>=0.0and<1.0trigonometricfunctions:sin,cos,tan,asin,acos,atan,toDegrees,toRadians

TheMathclasscanhelpyouwithasetofmethodstohelpyouworkwithdoubleandfloat,sowewilllookatthatclassinthischapter.

Formostofyourautomationyou’llprobablygetawaywithfloatanddouble.Butyouhavetobecarefulasthesetypesuseroundingandapproximationintheircalculations.Theydonotrepresent0.1inaformthatyoucanuseforexactcalculations,forexactoperationsandvaluesyouuseBigDecimal.

e.g.0.10+0.73=0.83

but…floattotal=0.1f+0.73f;

assertThat(total,is(0.83f));

Theabovecodefailswhenpartofan@Testmethodbecause:java.lang.AssertionError:

Expected:is<0.83F>

but:was<0.83000004F>

Withdoubleandfloatyouhavetobecarefulandhandleroundingyourselfthroughoutthecalculationprocess.

OryoucanusetheBigDecimalclass.

Page 211: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

YoucouldalsouseintorlongIfyouuseanintthenyoudon’tworryaboutrounding,particularlywhendoingacalculationliketheexamplewhichactuallyrepresents10pence,plus73pence.i.e0.1pounds+0.73pounds.

Icouldhavedonethecalculationinpenniesandbeenfine.

BigDecimalBigDecimalisimportedusingthejava.mathpackage.importjava.math.BigDecimal;

BigDecimalisnotaprimitive,soisalittleclumsiertoworkwith,andwillperformmoreslowlythantheprimitives.BigDecimalbdtotal=newBigDecimal("0.1").add(newBigDecimal("0.73"));

assertThat(bdtotal,is(newBigDecimal("0.83")));

BigDecimalmaintainsthedecimalpointprecision.Particularlyusefulforfinancialcalculations

Soif,asatesterworkinginfinance,youneedtoreadvaluesfromafileandcomparethecalculationsproducedfromsomeothersystem.YouarelikelytouseBigDecimaltoensurethatyourcalculationsareasaccurateasyoucanmakethem.

Youcoulduseintorlongandmanagetheroundingyourself.OrtaketheeasyrouteanduseBigDecimalwhenyouwanttomaintaintheprecision.

JoshuaBloch,theauthorof“EffectiveJava”,summarizesthesituationas“Ifthequantitiesdon’texceedninedecimaldigits,youcanuseint;iftheydon’texceedeighteendigits,youcanuselong.Ifthequantitiesmightexceedeighteendigits,youmustuseBigDecimal”.

Beawareofthechoicesnow,soyoudon’traisedefectsagainstsystemswhenthebugsareactuallyinyourmathcalculationcode.

Page 212: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Exercise:ConvinceYourselfofBigDecimalorintCreatean@Testmethodwhichcalculatestheresultofthefollowingsituation.

(Thereare100pencetothepound,or100centstothedollar)InthisexampleIusepoundsandpence.Feelfreetomentallytranslatethisintoanycurrencyyouwant,justbeawarethatthereare100pencetothepoundwhenyoutranslate.

Istartwith5pounds.Ispend43pence,thenIspend73pence,thenIspend1poundand73pence.

i.e.5-0.3-0.47-1.73

InmyhandIhave2pounds50pence(or2.5pounds).

Howmuchdoesyourdoublehave?Recreatethecodewithint.RecreatethecodewithBigDecimalusingthesubtractmethod.

BigDecimalMethodsConstructor

YoucanconstructaBigDecimalfroma:

int

long

String

double

BigInteger-anunboundedintegere.g.largerthana64bitlong.

BigDecimalfromInt=newBigDecimal(5);

BigDecimalfromLong=newBigDecimal(5L);

BigDecimalfromString=newBigDecimal("5");

BigDecimalfromDouble=newBigDecimal(5.0);

BigDecimalfromBigInteger=newBigDecimal(BigInteger.valueOf(5L));

StaticMethods

BigDecimalprovidessomefactorymethodsforcreatingaBigDecimalobject.

ONE

TEN

ZERO

valueOf-convertadoubleoralongtoaBigDecimal

BigDecimalbd0=BigDecimal.ZERO;

BigDecimalbd1=BigDecimal.ONE;

BigDecimalbd10=BigDecimal.TEN;

BigDecimalbdVal=BigDecimal.valueOf(5.0);

BasicArithmeticMethods

Page 213: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThebasicarithmeticoperatormethodsonBigDecimalare:

add

subtract

multiply

divide

EachofthesetakesaBigDecimalasargumentandreturnsanewBigDecimalrepresentingtheresultoftheassociatedoperator+,-,*,or/

Exercise:BasicArithmeticwithBigDecimalCreatean@TestannotatedmethodwhichimplementsthefollowingcalculationusingBigDecimalmethods:

aBigDecimal=0

(((aBigDecimal+10)*2)-10)/2)=5

ComparisonOperators

Youcan’tusethenormalcomparisonoperatorsonBigDecimali.e.>,<,==,!=,>=,or<=

YoucanuseequalstocompareBigDecimalobjects.assertThat(BigDecimal.ONE.equals(

newBigDecimal(1.0)),is(true));

assertThat(BigDecimal.ONE.equals(

newBigDecimal("1")),is(true));

YoucanalsousethecompareTomethod:

compareTo(value)returns:-1iftheBigDecimalislessthanvalue,0iftheBigDecimalisequaltovalue,1iftheBigDecimalisgreaterthanvalue

TheofficialdocumentationsuggeststhefollowingusageBigDecimal.TEN.compareTo(BigDecimal.ONE)>0

Whichwouldbeequivalentto:BigDecimal.TEN>BigDecimal.ONE

Exercise:CompareTENandONEWritean@TestannotatedmethodtocompareTENandONE.

Simulatingeachofthecomparisonoperators:

>,<,==,!=,>=,or<=

Followthesuggestedusagepatternabovee.g.>0

Page 214: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

UsingBigDecimal

IfyoustartworkingwithBigDecimalthenreadtheofficialdocumentationorusingcodecompletioninyourIDEtoseetheadditionalrangeofmethodsoffered.InthischapterwecoveredasmallsubsetofBigDecimalmethodstohelpyougetstarted,andtohelpyouunderstandthedifferencebetweenBigDecimalandtheearlierprimitivesdoubleandfloat.

BigDecimalsupportsdifferentroundingmethodswhichyoucanuseinconjunctionwiththearithmeticoperations.Youcanalsoprovidea‘scale’toworkatdifferentpowersoften.

JavaalsooffersaBigIntegerobjectinthejava.mathpackagewhichworkswithgreaterthan64bitintegers.Thenormaloperatorsandfunctionsassociatedwithanintorlong,areaccessibleviamethodsonBigInteger.

YoucanalsoconvertfromBigDecimalusingfloatValue,doubleValue,intValue,longValueetc.ThisisusefulwhenyouwanttousesomeofthemethodsintheMathclassafteraseriesofcalculations.

MathThejava.lang.Mathclassprovidesarangeofmathematicalmethodsforworkingwithfloatordouble,andsometimeswithanintorlong.

Theofficialdocumentationliststhesetofmethodsavailablesoyoucanfindtherangeeasilyenoughon-lineorinyourIDE.

Themethodsontheclassareallstatic,soareusedwithoutinstantiatingaMathobject,andyouwillnotneedtoimportthejava.lang.Mathpackage.

e.g.tofindthemaximumoftwovalues:assertThat(Math.max(23.0,42.0),is(42.0));

I’vedescribedasmallsetofmethodsIhavefoundusefulinthepastbelow.

Thefollowingmethodsoperateonint,long,doubleorfloat:

max-comparetwovaluesandreturnthelargermin-comparetwovaluesandreturnthesmallerabs-returntheabsolutevaluerandom-returnarandomnumber>=0.0and<1.0

Youalsohavetrigonometricfunctions:sin,cos,tan,asin,acos,atan,toDegrees,toRadians.

Idonotintendtocoverallthemethodsinthisbook.IsimplywanttomakeyouawareofthebuiltinMathclass.Andnow,whenyoustartworkingwithmathematicalfunctionalityinyourtests,goingbeyondthetypicalarithmeticoperations,youcanexaminetheMathclassinmoredetailtoseeifithasexistingmethodsthatmeetyourneeds.

SummaryThiswasachapterintroducingtwoimportantclassesataveryhighlevel:

Page 215: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

BigDecimal

Math

UseBigDecimalwhenworkingwithcurrencyvaluesorwhenyouneedaccuracyinthecalculations,andavoidingrounding.

UseMathwhenyouneedtogobeyondthesimplemathematicaloperators+-*/.

RememberalsotheBigIntegerclasswhenyouneedtoworkwithlargerthan64bitintegervalues.

ReferencesandRecommendedReading

JavaBigDecimaldocs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

BigIntegerofficialdocumentationdocs.oracle.com/javase/7/docs/api/java/math/BigInteger.html

JavaMathclassofficialdocumentationdocs.oracle.com/javase/7/docs/api/java/lang/Math.html

Page 216: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTwentyOne-CollectionsRevisited

ChapterSummaryInthischapteryouwillrevisitthecollectionclasses.

CoreCollections-Corecollectioninterfaces:SortedSet-likeaSetbutmaintainsanorder

first-returnthefirstitemlast-returnthelastitemheadSet(e)-returntheelements,beforeelementetailSet(e)-returntheelementsafterandincludingelementesubSet(e1,e2)-theelementsfrom(andincluding)elemente1,to(butexcluding)e2comparator-returntheComparatorobjectusedforcomparisonforsortorder

SortedMap-likeaMapbutmaintainsanorderfirstKey-thefirstkeybasedonthesortorderlastKey-thelastkeybasedonthesortorderheadMap(k)-every“key,value”pairbeforekeyktailMap(k)-every“key,value”pairafterandincludingthekeyksubMap(k1,k2)-every“key,value”pairbetweenk1andk2(includingk1,excludingk2)comparator-thecomparatorusedtodeterminethesortorderofthekeys

Queue-afirstinfirstoutcollectionDeque-addelementseitheratfrontorendbutnotmiddle

CoreImplementations-Corecollectionimplementations:TreeSet-implementsaSortedSetTreeMap-implementsaSortedMap

CoreCollectionInterfacesRevisitedTheofficialdocumentationliststhefollowingastheCoreCollectioninterfaces:

Collection

List

Set

SortedSet

Queue

Deque

Map

SortedMap

ThefollowingtableprovidesasummaryofthekeymethodsontheInterfaces,andIhaveremovedListandaddedtheSortedSetandSortedMapsoyoucanseetheadditionalnuances.:

Page 217: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Collection Set SortedSet Map SortedMap

add(e)AllinCollection

first put(k,v) firstKey

remove(e) last remove(k) lastKey

removeAll(c) headSet(e) entrySet headMap(k)

retainAll(c) tailSet(e) get(k) tailMap(k)

clear subSet(i1,i2) clear subMap(k,k)

contains(e) containsKey(k) containsAll(c) containsValue(v) size comparator size comparator

isEmpty AllinCollection

isEmpty AllinMap

toArray values toArray(a) keySet addAll(c) putAll(m)

where:e==element,c==collection,a==array,i==index,k==key,v==value,m==map

SetWedescribedSetintheearliercollectionchapter.

InthischapterwewillbuildonSetandconsidertheSortedSet.

SortedSet

TheSortedSet,liketheSetstripsoutduplicatesifyoutrytoaddthem.

TheSortedSetalso:

guaranteestheorderoftheelementsbasedonaComparatororthecompareTomethodoftheelements

ThesortingreliesontheelementsinthesettoimplementaComparableinterfacewhichmandatestheimplementationofacompareTomethod.OryoucanprovideaComparatortotheSortedSetimplementationatinstantiation,andtheComparatorknowshowtocomparetheobjects.

FortheexamplesIwillmainlyuseStringbutwillalsoprovideashortoverviewoftheComparator.

first-returnthefirstitemlast-returnthelastitemheadSet(e)-returntheSortedSetofelements,beforeelementetailSet(e)-returntheSortedSetofelementsafterandincludingelementesubSet(e1,e2)-theSortedSetfrom(andincluding)elemente1,to(butexcluding)e2

Page 218: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

comparator-returntheComparatorobjectusedforcomparisonforsortorder

WithaSortedSetyoualsohaveaccesstoallmethodsintheCollectioninterface.

WithaSortedSetIusetheTreeSetfromjava.utilasmydefaultimplementation.

Thefollowingexampleshows:

theSortedSetmaintainingtheorderoftheelements,eventhoughIaddedthemoutofordertheSortedSetdoesnotaddtheduplicated"a"element

@Test

publicvoidsortedSetCanMaintainSortOrder(){

SortedSet<String>alphaset=new<String>TreeSet();

alphaset.add("c");

alphaset.add("d");

alphaset.add("a");

alphaset.add("b");

alphaset.add("a");

assertEquals(4,alphaset.size());

String[]alphas=newString[alphaset.size()];

alphaset.toArray(alphas);

assertEquals("a",alphas[0]);

assertEquals("b",alphas[1]);

assertEquals("c",alphas[2]);

assertEquals("d",alphas[3]);

}

Intheabovelisting,IaddtheStringvaluestothealphasetinarandomorder,butwhenIconvertthealphasettoanarray,thearrayhastheStringvaluesinorder.

Also,althoughIaddedtheString"a"twice,itisonlyaddedtothealphasetonce:asevidencedbythesize()methodreturning4,andtheconversiontoarrayonlycontainingtheString"a"once.

firstretrievesfirstelementinsort

WhennewelementsareaddedtotheSortedSet,thesortorderofelementsismaintainedsothatfirstalwaysreturnsthefirstelementinthesetbasedonthesortorder.@Test

publicvoidcanRetrieveFirstFromSortedSet(){

SortedSet<String>alphaset=new<String>TreeSet();

alphaset.add("c");

assertEquals("c",alphaset.first());

alphaset.add("d");

assertEquals("c",alphaset.first());

alphaset.add("b");

assertEquals("b",alphaset.first());

Page 219: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

alphaset.add("a");

assertEquals("a",alphaset.first());

}

lastretrieveslastelementinsort

WhennewelementsareaddedtotheSortedSet,thesortorderofelementsismaintainedsothatlastalwaysreturnsthelastelementinthesetbasedonthesortorder.@Test

publicvoidcanRetrieveLastFromSortedSet(){

SortedSet<String>alphaset=new<String>TreeSet();

alphaset.add("c");

assertEquals("c",alphaset.last());

alphaset.add("b");

assertEquals("c",alphaset.last());

alphaset.add("d");

assertEquals("d",alphaset.last());

alphaset.add("a");

assertEquals("d",alphaset.last());

}

headSetsubsetbeforeanelement

Youcancreateasortedsubsetofallelementsinthesetbeforeaspecificelement.SortedSet<String>subset=alphaset.headSet("c");

Theabovestatementwouldreturneveryelementbefore“c”i.e“a”and“b”,asthefullexamplebelowillustrates.@Test

publicvoidsortedSetcanReturnHeadSet(){

SortedSet<String>alphaset=new<String>TreeSet();

alphaset.add("c");

alphaset.add("d");

alphaset.add("b");

alphaset.add("a");

SortedSet<String>subset=alphaset.headSet("c");

assertEquals(2,subset.size());

String[]alphas=newString[subset.size()];

subset.toArray(alphas);

assertEquals("a",alphas[0]);

assertEquals("b",alphas[1]);

}

tailSetsubsetafter,andincluding,anelementSortedSet<String>subset=alphaset.tailSet("c");

Page 220: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ThetailSetcreatesasubset,butthistimethesetofallelementsinthesetwhicharegreaterthanorequaltotheelement,sothesubsetalsoincludestheelementitself.

Thisisillustratedbytheexamplebelow:@Test

publicvoidsortedSetcanReturnTailSet(){

SortedSet<String>alphaset=new<String>TreeSet();

alphaset.add("c");

alphaset.add("d");

alphaset.add("b");

alphaset.add("a");

SortedSet<String>subset=alphaset.tailSet("c");

assertEquals(2,subset.size());

String[]alphas=newString[subset.size()];

subset.toArray(alphas);

assertEquals("c",alphas[0]);

assertEquals("d",alphas[1]);

}

subSetbetweentwoelementsSortedSet<String>subset=alphaset.subSet("b","d");

ThesubSetcontainsasubsetfrom,andincluding,thefirstelementargument,to,butexcludingthesecondelementargument.e.g.given"a","b","c","d"thenasubSet("b","d")wouldbefromandincluding“b”,to(butexcluding)"d",giving"b","c".

Thisisillustratedbytheexamplebelow:@Test

publicvoidsortedSetcanReturnSubSet(){

SortedSet<String>alphaset=new<String>TreeSet();

alphaset.add("c");

alphaset.add("d");

alphaset.add("b");

alphaset.add("a");

SortedSet<String>subset=alphaset.subSet("b","d");

assertEquals(2,subset.size());

String[]alphas=newString[subset.size()];

subset.toArray(alphas);

assertEquals("b",alphas[0]);

assertEquals("c",alphas[1]);

}

comparatorusedforsorting

Page 221: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

comparatorreturnstheComparatorobjectwhichtheSortedSetisusingforcomparisons.

ThereforeweshouldlearnhowtocreateaComparator.

IhavechosentoexpandonComparatorbutnothashSetandequalsbecauseIthinktheComparatoroffersmorere-usepotentialandlikelihoodofyouimplementingit.

ToillustratethisfunctionalitywearegoingtocreateaSortedSetoftheUserdomainobjectthatwecreatedearlier.

Wedidn’taddacompareTomethodtothatobject,nordidwecreateequalsorhashCode.

Intheexamplebelow,ourfirstattemptatcreatingaSortedSetofUserobjectswouldfailwithaClassCastException.TheClassCastExceptionwouldbethrownassoonaswetrytoaddtheUsernamed"Bob"totheSortedSet.BecauseourUserobjectdoesnotimplementtheComparableinterface.Userbob=newUser("Bob","pA55Word");//11

Usertiny=newUser("TinyTim","hello");//12

Userrich=newUser("Richie","RichieRichieRich");//22

Usersun=newUser("sun","tzu");//6

UsermrBeer=newUser("Stafford","sys");//11

SortedSet<User>userSortedList=newTreeSet<User>();

userSortedList.add(bob);

OurimmediatethoughtmightbetoimplementtheComparableinterfaceontheUserclass.Butsometimeswedon’thavecontroloveralltheclassesweuse,andsometimeswedon’twanttoimplementthatinterfaceforallourdomainobjects.Wemightonlywanttosortthemonceortwice.

CreatingacustomComparatorcanbeveryuseful.Alsowemightwanttosortthemindifferentways,atdifferenttimes,andembeddingthecomparisoncodeintheobjectitselfmightnotgiveusthatflexibility.

InthisbookIwilltaketheapproachofcreatingaUserComparator.TheUserComparatorisaclasswhichwillcompareUserobjects.

Inthe@TestmethodwhereIwanttocreatetheSortedSetIinstantiatetheTreeSetasfollows:SortedSet<User>userSortedList=newTreeSet<User>(newUserComparator());

HereIcreateanewUserComparatorandpassitasanargumenttotheTreeSetconstructor.ThisprovidesflexibilitybecauseifIwanttosortorcomparetheobjectsindifferentwaysthenIcouldconstructtheTreeSetwithadifferentComparatorobject.

SothatyouunderstandthecomparisonthatIwanttouse,Iwillshowyouthefullmethodcode:@Test

publicvoidsortedSetWithComparatorForUser(){

Userbob=newUser("Bob","pA55Word");//11

Usertiny=newUser("TinyTim","hello");//12

Userrich=newUser("Richie","RichieRichieRich");//22

Usersun=newUser("sun","tzu");//6

UsermrBeer=newUser("Stafford","sys");//11

Page 222: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

SortedSet<User>userSortedList=

newTreeSet<User>(newUserComparator());

userSortedList.add(bob);

userSortedList.add(tiny);

userSortedList.add(rich);

userSortedList.add(sun);

userSortedList.add(mrBeer);

User[]users=newUser[userSortedList.size()];

userSortedList.toArray(users);

assertEquals(sun.getUsername(),users[0].getUsername());

assertEquals(bob.getUsername(),users[1].getUsername());

assertEquals(mrBeer.getUsername(),users[2].getUsername());

assertEquals(tiny.getUsername(),users[3].getUsername());

assertEquals(rich.getUsername(),users[4].getUsername());

}

Iwantthesortordertobebasedonthelengthoftheusername+thelengthofthepassword.ThisisthealgorithmthattheUserComparatorwillimplement.

YoucanseethatIhaveaddedthelengthsascommentsaftereachoftheUserinstantiationssothatIknowwhattoasserton.

Therestofthecodeisprettysimple:

createtheUserobjectsinstantiateaSortedSetwiththeUserComparatorconvertthesettoanarraysothatwecanassertontheexpectedorder

ThenextstepistocreatetheComparator.

Iwillcreateitinthesrc\main\javabranchasI’llprobablyreuseitinmoreplaces.AndI’lladdittothecom.javafortesters.domainentitiespackage.

Thisisthefirstclassyouareseeinguscreatewhichimplementsaninterface.InthisexamplewewillimplementtheComparatorinterface:publicclassUserComparatorimplementsComparator{

Inordertosatisfythisinterface,IhavetoimplementacomparemethodwhichtakestwoObjectasarguments,andreturnsanint:publicintcompare(ObjectoUser1,ObjectoUser2){

Theinthastocorrespondto:

0ifthetwoobjectsareequalinthetermsofthesortingalgorithmnegative-veifobject1islessthanobject2positive+veifobject1isgreaterthanobject2

SincetheargumentshavetobeoftypeObjectweneedtocasttheminthecodetothecorrecttype,whichforusisUser:

Page 223: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Useruser1=(User)oUser1;

Useruser2=(User)oUser2;

Implementthealgorithmdecidedupontohelpmecomparethetwovalues:intuser1Comparator=user1.getPassword().length()+

user1.getUsername().length();

intuser2Comparator=user2.getPassword().length()+

user2.getUsername().length();

Thencalculatethereturnintintval=user1Comparator-user2Comparator;

Great.Andallofthatimplementsthesortingalgorithm.TheproblemisthatSortedSetalsousestheComparatortodecideifthevaluesintheSortedSetareunique.AndtheimplementationabovewouldnotletmeaddanyUserintotheSortedSetwheretheusername+passwordlengthisthesame.

InthecodeaboveIwouldfailtoaddmrBeerbecausehehasthesamelengthasbob.AndIwantmrBeerintheSortedSet.

BeerIdon’tactuallyliketodrinkbeer.InfactIcan’tstandthestuff.Imuchprefertodrinkwine.ButIdolovethebooksofMrStaffordBeer.AparticularlysplendidSystemsThinkerandCybernetician.Ifyougetthechance,readhiswork.

IhavetoaddonelittleadjustmenttotheComparatortoallowforduplicatelengths,butIwillexcludeduplicatelengthswithaduplicateusernamefromtheSortedSet.ThiswouldstillallowinUserswithduplicatenames(providedtheyhavedifferentlengthpasswords)butthatisfineforthiscomparisonalgorithm.if(val==0){

val=user1.getUsername().compareTo(user2.getUsername());

}

Andwiththatwecanreturnval;

ThefullcodefortheUserComparatorwhichallowsthe@Testmethodtocompleteisbelow:publicclassUserComparatorimplementsComparator{

publicintcompare(ObjectoUser1,ObjectoUser2){

Useruser1=(User)oUser1;

Useruser2=(User)oUser2;

intuser1Comparator=user1.getPassword().length()+

user1.getUsername().length();

intuser2Comparator=user2.getPassword().length()+

user2.getUsername().length();

intval=user1Comparator-user2Comparator;

Page 224: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

if(val==0){

val=user1.getUsername().compareTo(user2.getUsername());

}

returnval;

}

}

Exercise:Removeif(val==0)Removetheif(val==0)blockofcodeandrunthe@Testmethod.Ensurethatyouunderstandwhyweaddedthatlineofcode.

Exercise:DisallowDuplicateUserNamesCreateaDupeUserComparatorwhichimplementsthelengthcheckasabove,butalsodoesnotallowUserwithaduplicateusernametobeaddedtotheSortedSet.

Useitinan@Testannotatedmethodtodemonstrateitworks.

Exercise:UserclassimplementsComparableAddcodetotheUserclasssuchthatitimplementsComparablewiththealgorithmfordisallowingaUserwithduplicateusernameaswellasthelengthcheckinthecompareTomethod.

Useitinan@Testannotatedmethodtodemonstrateitworks.

Exercise:SeethesortinactionAddthelineofcodebelow,toyourComparator.JustbeforethereturnvallineandseetheComparatorinactioninyourconsole.

System.out.println("Compare"+user1.getUsername()+

"with"+user2.getUsername()+"="+val);

Set&SortedSetDocumentation

YoucanfindthedetailsofSetandSortedSetontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/set.htmldocs.oracle.com/javase/tutorial/collections/interfaces/sorted-set.html

Implementation:

docs.oracle.com/javase/tutorial/collections/implementations/set.html

Page 225: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

MapWedescribedMapintheearliercollectionchapter.

InthischapterwewillbuildonMapandconsidertheSortedMap.

SortedMapSortedMapistoMap,asSortedSetistoSet.AndtheinterfaceandfunctionofthemethodsofSortedMaparealmostthesameasSortedSet.Soitwon’ttakelongforyoutofigureouthowSortedMapworks.

ASortedMapisorderedonitskeys,notitsvalues.Thecomparatorisusedtodeterminetheordering,orthecompareTomethodonthekey

ThemethodsshouldbefamiliarastheyarealmostthesameasSortedSet

firstKey-thefirstkeybasedonthesortorderlastKey-thelastkeybasedonthesortorderheadMap(k)-theSortedMapcontainingevery“key,value”pairbeforekeyktailMap(k)-theSortedMapcontainingevery“key,value”pairafterandincludingthekeyksubMap(k1,k2)-theSortedMapcontainingevery“key,value”pairbetweenk1andk2(includingk1,excludingk2)comparator-thecomparatorusedtodeterminethesortorderofthekeys

Forthesakeofbrevity,sincewecoveredtheSortedSetindetail,andSortedMapismuchthesame,IwilluseexamplestoexplainSortedMapratherthanalotofdescriptivetext.AlltheexamplesfortheSortedMapmethodsusethefollowingMapdeclarationandinstantiation:SortedMap<String,String>map=newTreeMap<>();

map.put("key1","value1");

map.put("key3","value3");

map.put("key2","value2");

map.put("key5","value5");

map.put("key4","value4");

firstKey&lastKeytoretrievekeylimits

firstKeyandlastKeyrespectivelyreturnthefirstandlastkeysinthemap:assertEquals("key1",map.firstKey());

assertEquals("key5",map.lastKey());

CreatesortedextractswithheadMap,tailMapandsubMap

headMap(k)returnsaSortedMapcontainingeverykey,valuepairbeforethekeypassedasargument.e.g.SortedMap<String,String>headMap;

headMap=map.headMap("key3");

Page 226: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals(2,headMap.size());

assertTrue(headMap.containsKey("key1"));

assertTrue(headMap.containsKey("key2"));

tailMap(k)returnsaSortedMapcontainingeverykey,valuepairafterandincludingthekeypassedasargument.e.g.SortedMap<String,String>tailMap;

tailMap=map.tailMap("key3");

assertEquals(3,tailMap.size());

assertTrue(tailMap.containsKey("key3"));

assertTrue(tailMap.containsKey("key4"));

assertTrue(tailMap.containsKey("key5"));

subMap(k,k)returnsaSortedMapcontainingeverykey,valuepairafterandincludingthekeypassedasfirstargumentandbefore,butexcluding,thekeypassedassecondargument.e.g.SortedMap<String,String>subMap;

subMap=map.subMap("key2","key4");

assertEquals(2,subMap.size());

assertTrue(subMap.containsKey("key2"));

assertTrue(subMap.containsKey("key3"));

comparatorforsorting

ThecomparatorusageforSortedMap,differsfromSortedSetonlybecausethekeyissortedandnotthevalue(orelement).

WheneverIhaveusedaSortedMap,mykeystypicallyareStringsandsonaturalsortorderisnormallyadequate.

AMapcanuseanyobjectasthekey,soIhaveusedthesameexamplefromSortedSettoillustratethecomparatoronSortedMap.EventhoughthisrepresentsafairlyobtuseuseoftheMap.

InthisexampleyoushouldimaginethattheUseristhekeyandthevalueisadescriptionoftheUser

IinstantiatetheSortedMapwiththeUserComparatorasIdidwithSortedSet:SortedMap<User,String>userSortedMap=

newTreeMap<User,String>(newUserComparator());

ThentherestofthecodeisthesameasSortedSet

createabunchofUserobjectsinstantiatetheSortedMapputalltheUserobjectsintotheMapasthekey,andaddadescriptionasthevalueextractthekeystoanarray-theywillbeinthesortorderspecifiedbythecomparator

assertonthesortorder

@Test

publicvoidsortedMapWithComparatorForUser(){

Userbob=newUser("Bob","pA55Word");//11

Page 227: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Usertiny=newUser("TinyTim","hello");//12

Userrich=newUser("Richie","RichieRichieRich");//22

Usersun=newUser("sun","tzu");//6

UsermrBeer=newUser("Stafford","sys");//11

SortedMap<User,String>userSortedMap=

newTreeMap<User,String>(newUserComparator());

userSortedMap.put(bob,"Bobrules");

userSortedMap.put(tiny,"TinyTime");

userSortedMap.put(rich,"RichRichie");

userSortedMap.put(sun,"WarfareArt");

userSortedMap.put(mrBeer,"Cybernetician");

User[]users=newUser[userSortedMap.size()];

userSortedMap.keySet().toArray(users);

assertEquals(sun.getUsername(),users[0].getUsername());

assertEquals(bob.getUsername(),users[1].getUsername());

assertEquals(mrBeer.getUsername(),users[2].getUsername());

assertEquals(tiny.getUsername(),users[3].getUsername());

assertEquals(rich.getUsername(),users[4].getUsername());

}

MapKeySetExploredkeySetreturnsaSetwhereeachelementisakeyfromtheMap:Set<String>keys=map.keySet();

IcouldusethistocreateaSortedSetofkeys:SortedSet<String>keys=newTreeSet<String>(map.keySet());

Exercise:AccessValuesinaMapinKeyorderCreateaMapUseaSortedSetforthekeystoiteratethroughtheMapinkeyorder.

Map&SortedMapDocumentationYoucanfindthedetailsofMapandSortedMapontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/map.htmldocs.oracle.com/javase/tutorial/collections/interfaces/sorted-map.html

Implementation:

docs.oracle.com/javase/tutorial/collections/implementations/map.html

Queue&Deque

Page 228: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

I’mnotgoingtogointodetailontheQueueandDeque(deck).SimplybecauseI’veneverhadtousethemintherealworld.

AQueueprovidesafirstin,firstoutcollection.Whereyouaddelementsatthebackofthequeueandremovethemfromthefront.

ADequeallowsyoutoaddelementsatthefrontorbackofthequeue,butnotthemiddle.

Itisworthknowingthatthesecollectiontypesexist,butifyouneedtousethem,I’msureyou’llnowbeabletounderstandthedocumentationontheofficialsite.

Queue&DequeDocumentation

YoucanfindthedetailsofQueueandDequeontheofficialdocumentationsite.

Interface:

docs.oracle.com/javase/tutorial/collections/interfaces/queue.htmldocs.oracle.com/javase/tutorial/collections/interfaces/deque.html

Implementation:

docs.oracle.com/javase/tutorial/collections/implementations/queue.htmldocs.oracle.com/javase/tutorial/collections/implementations/deque.html

ImplementationsYouhaveseeninthelistingsabovetheImplementationsIused.

ForcompletenessI’velistedbelowtheimplementationsforthevariousCollectioninterfacesthatwecoveredinbothchapters.

Collection&List:ArrayList

Set:HashSet

TreeSet-forsortedMap:

HashMap

TreeMap-forsortedonkeys

PeriodicallyIhavehadtocallupontheConcurrentHashMapinjava.util.concurrentwhenIwaswritingcodetoshareobjectsinmemoryacross@Testmethodsrunninginparallel.Ididn’tknowabouttheConcurrentHashMapbeforeIstarted.ButIknewaboutcollections,andIknewIneededsomethingtoworkconcurrentlysoIdidafewInternetsearchesandfoundthecollection.

WhatI’mreallysuggestingintheaboveparagraphisthatyoulearnafewclassestostartwith.Then,ifyouhavetime,lookaroundatothers,orwaituntilyouneedone.You’llknowyouneedanewimplementationbecauseyouarehavingtocodeworkaroundswith

Page 229: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

yourexistingimplementation,andchancesaresomeoneelsehasalreadyexperiencedyourproblem,andwrittenaclasssosolveit.Youjustneedtohuntitout.

SummaryTheSortedMapandSortedSetrequirealittleextrawork-specificallytheimplementationofaComparatororanObjecttoimplementComparable.

Inpractice,IdefaulttoimplementingComparatorObjectsasthisgivesmemoreflexibilityandIdon’thavetocluttermydomainobjectswiththeComparableinterface.

ReferencesandRecommendedReading

SortedSetInterfacedocs.oracle.com/javase/tutorial/collections/interfaces/set.htmldocs.oracle.com/javase/tutorial/collections/interfaces/sorted-set.html

SortedSetImplementationdocs.oracle.com/javase/tutorial/collections/implementations/set.html

SortedMapInterfacedocs.oracle.com/javase/tutorial/collections/interfaces/map.htmldocs.oracle.com/javase/tutorial/collections/interfaces/sorted-map.html

SortedMapImplementationdocs.oracle.com/javase/tutorial/collections/implementations/map.html

QueueandDequeInterfacedocs.oracle.com/javase/tutorial/collections/interfaces/queue.htmldocs.oracle.com/javase/tutorial/collections/interfaces/deque.html

QueueandDequeImplementationdocs.oracle.com/javase/tutorial/collections/implementations/queue.htmldocs.oracle.com/javase/tutorial/collections/implementations/deque.html

Page 230: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTwentyTwo-AdvancingConcepts

ChapterSummaryThischapterprovidesabriefoverviewofeachofthefollowingareas,withlinksforyoutostartconductingyourownresearchonthetopic.

InterfacesAbstractClassesGenericsLoggingEnumRegularExpressionsReflectionAnnotationsDesignPatternsConcurrencyAdditionalFileconsiderations

Andwearealmostfinishednow.

TheoriginalintentbehindthisbookwastocoverthebasicsofJavathatyouneedtounderstand,inanorderthatallowedyoutousetheconceptsquickly,withoutbeingdistractedbytoomuchadditionaloverhead.

Thischapterprovidesanoverviewof‘advancing’conceptswhicharenotnecessarilyrequiredtobefunctionalinJava,butitisimportanttoknowtheyexist,andgiveyousomethingtoresearchinyournextsteps.

Youprobablywon’tneedtheseconceptsforwritingsimpleJUnittests.

Youmayneedthesewhenyoustartbuildingalotofcodethathastohangtogetherwell,andwhentheJavacodeitselfneedstoembodygooddesignprinciples.

Forthefirst3or4yearsofmywritingautomationcode,Iprobablydidn’tuseanyoftheseconceptsverymuchatall.

Iusedcompositiontore-usecode,withoutusingInterfaces.IrarelyusedInheritance.IneverusedAbstractClasses.Ididn’treallyknowwhatanenumwasetc.

Mycodewassimple,butdidn’thavedesignprinciplesholdingittogether.WhichiswhyIthinkoftheseas“AdvancingConcepts”.

Theyarenot‘advanced’sincetheyarefundamentaltothewaythatJavaandgoodprogrammingworks.Butintermsofyourusageofthem,theyonlyneedtobecome

Page 231: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

relevantwhenyouare“Advancing”yourunderstandingofJavaandtherobustnessofyourabstractionlayers.

InterfacesInearliersectionsofthebookweusedInterfaceswithoutactuallyexplainingmuchaboutthem.

AnInterfacedeclaresasetofmethodsthataClassmustimplement.Anywhereinourcodethatweonlywanttousethesetofinterfacemethods,wecancastobjectstotheinterface,ordeclareobjectsas,thatinterface,ratherthanworkingwithconcreteclasses.

e.guseaListratherthananArrayList

Eachobjectthatimplementsaninterfacethenhasfreedomtodecidehowtoimplementthemethodsonthatinterface,suchthattheyareappropriatetothatparticularobject.

ItendtointroduceinterfacesintomycodewhenIstarttoseesimilarusagepatternsoftheobjects.

Asanexample.WhenautomatingawebsiteImightcreateobjectstorepresenteachPageonthesite.Pagesonthesitetendtohavesimilarcomponentse.g.headerorfooter.EarlyinmycodeImighthaveagetHeadermethodonsomepages,butnotothersandImighthaverepeatedcodeasaresult.

WhenIspotthis,IcancreateaninterfacecalledHasHeaderandthismightforcethepagetoimplementthegetHeadermethod.AndIcanwritemethodsthatoperateonaHeaderofapagewhichtakeaHasHeaderinterfaceasaparameterinsteadofindividualpageobjects,orangenericObject.

ResearchInterfacessoyouunderstandtheircapabilities.Andusethemtohelpyouorganizeyourabstractionlayers.

ResearchLinks:

InterfaceDefinitiondocs.oracle.com/javase/tutorial/java/concepts/interface.html

HowtocreateanInterfacedocs.oracle.com/javase/tutorial/java/IandI/createinterface.html

AbstractClassesAbstractclassesareclasseswhichyoucanextend,butcan’tinstantiatedirectlysincenotallthemethodsintheAbstractclasswillhavebeenimplementedintheAbstractClass.

IrarelyuseAbstractClasses.Itendtouseinterfacesanddelegateouttootherconcreteclasses.IdothisbecauseIknowthatmyautomationabstractionsarelikelytochangefrequentlyandIneedalotofflexibilityinmycode.

ResearchLinks:

AbstractClassesOfficalDocumentationdocs.oracle.com/javase/tutorial/java/IandI/abstract.html

Page 232: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

AbstractClassesvs.Interfacesjavaworld.com/javaqa/2001-04/03-qa-0420-abstract.html

GenericsInthemainbodyofthisbookyousawGenericsusedwheninstantiatingCollectionsandwedeclaredthetypeofobjectsthatthecollectionwouldhold.

YoucanuseGenericswhencreatingyourownobjectsandmethods,suchthatyoudon’tknowexactlywhatobjecttheywilluse.

Thisisaverypowerfulcodingstyle,tomakeyourautomationabstractionsflexible,butonethatItendnottohavetouseveryoften.

ResearchLinks:

OfficialJavaTutorialonGenericsdocs.oracle.com/javase/tutorial/java/generics

LoggingWedidn’tcoverlogginginthisbook.TheclosestwecamewaswritinginformationouttoaFile,andusingSystem.out.printlntooutputtotheconsole.

FormostofmyautomationcodeIcangetawaywithwritinglogmessagestoSystem.outsincetheywillbedisplayedincontinuousintegrationsystems,andwerarelyhavetoconfigurethelevelofloggingwhenrunningautomation.

Javaloggingallowsyoutowritecodethatoutputslogmessagese.g.warnings,errors,etc.Thelevelofloggingoutputwhenrunningthecodecanbeconfiguredexternallytotheapplicationbytheuserrunningtheapplication.

Whenyouneedthislevelofflexibility,itistimetolearnaboutloggingframeworks.

Javahasabuiltinloggingframework.Andalotofexternalframeworkswhichincreasetheeaseofuse,orflexibilityofconfiguration.

ResearchLinks:

OfficialJavaLoggingOverviewdocs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html

TutorialbyLarsVogelvogella.com/articles/Logging/article.html

EnumAnenumcanbethoughtofasasetofpredefinedconstants.Usefulwhenorganizingconstantsinyourabstractionlayers.

Anenumcanbeusedastheargumentinaswitchstatement.Thiscanleadtoreadableandsimplecode.

Page 233: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Theseconstantscanalsohavemethodsmakingthemveryflexible,andmightevenremovetheneedtoputtheminaswitchstatement,andinsteadusetheenum’smethoditself.

ResearchLinks:

OfficialEnumdocumentationdocs.oracle.com/javase/tutorial/java/javaOO/enum.html

RegularExpressionsWebrieflytoucheduponregularexpressionsinthemaintext.

RegularExpressionsprovideamassiveamountofpowerandflexibilityforparsingandprocessinginput.

Whenyourcodestartstolookcomplicated,andyouhaveaseriesofnestedifstatements,orcomplicatedtransformations.ThenitmightbetimetograduatetotheuseofRegularExpressions.

ResearchLinks:

docs.oracle.com/javase/tutorial/essential/regex/

ReflectionMostofourprogrammingworkusesspecificobjects,andweknowthemethodsandinterfacesavailableatthetimeofcoding.

Reflectionmeansqueryingtheclassatruntimetofindoutinformationabouttheobject,e.g.findingoutwhichmethodsareontheobject,whataretheirparameters,whatannotationsexistetc.

Youcanalsoamendthemethodsignaturestoallowyoutocallprivatemethods,oraccessprivatevariablesetc.

MostprogrammersIknowspurnreflection.Andindeedmostofthetimeinanapplicationitisn’tused,itcanbeslow,anditcanbedangeroustoperformtheseactionsatRuntime.

SomeoftheproblemsI’vefacedinthepasthowever,couldonlybesolvedusingreflection:

TryingtouselibrarieswithoutdocumentationUsingpiecesoffunctionalityoutofsequenceWorkingaroundlimitationsinabstractionlayers

Someofthetoolsweusee.g.JUnit,canonlyworkbecauseofreflection,andalltheannotationsyouaddedtoyourcodeareaccessedviareflection.

Learnaboutreflectionsothatyouknowwhatitiscapableof.Thenyoucantryanduseitwhenyouencounteraproblemthatyouseenootherwaytosolve.

ResearchLinks:

Page 234: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

docs.oracle.com/javase/tutorial/reflect

AnnotationsYouusedannotationswhenyouput@Testatopyourmethodcode.

Annotationsaremeta-data.MeaningtheyareusedbythecompilerandwhenyourcodeisaccessedatruntimeusingReflection.

IhaveinthepastusedannotationswhentryingtofindwaysofreportingonexecutioncoverageandcreatingcustomJUnitrunners.

Importanttoknowabout,butIimagineyouwillnotusethemveryoften.

ResearchLinks:

docs.oracle.com/javase/tutorial/java/annotations

DesignPatternsDesignPatternsarethosestatementsthatyouhearontheprojectthateveryoneassumesthateveryoneelseunderstandsandneverexplains,e.g.

SingletonObserverVisitorFactoryProxyetc.

Thesearecommonapproachestosolvingcommonproblems.Thefamousbook“DesignPatterns”byGamma,Helm,JohnsonandVlissideslists23commonpatternsandsomesolutions.

Somefamiliaritywiththemisimportantbecausetheyofferapproachestoproblemsthatotherpeoplehavesolved.Theywillalsohelpyouunderstandwhatdevelopersaretalkingaboutwhentheyexplaintheircodetoyou.

ResearchLinks:

c2.com/cgi/wiki?DesignPatternsBookoodesign.com/

ConcurrencyConcurrencyisimportantinJava.Itallowsyoutoruncodeinmultiplethreadsandpotentiallyachievesomeresultsfaster,orrunmorethanone@Testmethodatthesametime.

Youwilloftenreadthatcertainclassesarenot“ThreadSafe”whichmeanstheyshouldnotbeusedwhenyoutryanduseconcurrency.

Page 235: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Therearedifferentapproachestoconcurrency,rangingfromsimpleuseofsynchronizedwhichmeansthatamethodcanonlybecalledbyasinglethreadatatime.Tofullnon-blockingconcurrency.

Thistopicisfartoadvancedforthisbook.Unfortunatelymanytesterstryandtacklethissubjectearlybecausetheywanttoruntheir@Testmethodsinparallel.Oftenbeforethereisevenacompellingneedtoruntheautomationchecksinparallel.

ConcurrencyisaveryinterestingpartofJavatostudy,andIhavehadtocreateautomationabstractionsthatwereusableinamulti-threadedmanner.ButnotearlywhenIwaslearningJava.Irecommendyoureadaboutit,butdon’ttryanddoanyconcurrentprogramminguntilyouareverycomfortableunderstandinghowyourapplicationworks.Otherwiseyoumaycreatecodethatfailsintermittentlythatishardtodebugandfix.

IprimarilyaddedConcurrencyinthissectiontowarnyouofftryingtouseittooquickly.

ResearchLinks:

docs.oracle.com/javase/tutorial/essential/concurrency

AdditionalFileconsiderationsInthefilechapterIskippedoveralotofinformation,totryandcreateexamplecodeandbasicinformationthatwillcovermanyofyourinitialfileprocessingneeds.

IalsocoveredmostofthethingsthatIusefilesfor.Irarelyhavetoworkwiththebasicfilebuildingblocks:streamsandchannels.

IrarelyworryaboutFileencoding,becausemostofmyfilesarecreatedandreadfromwithinthesameJUnittestclass,andbecausetheyaretemporary,theygetdeletedafterthe@Testmethodsfinish.

Iincludethelinksbelowasresearchitemsincaseyouneedtheminyourenvironment.

ResearchLinks:

Streamsdocs.oracle.com/javase/tutorial/i18n/text/stream.html

FileIOdocs.oracle.com/javase/tutorial/essential/io/file.html

SummaryIknowthischapterhasveryfewexamples.ThemainpurposewastomakeyouawareofadditionalareasoffunctionalityavailableinJava.

Ididnotexplainanyindetailbecauseeachareareasthatcouldhaveentirebooksdedicatedtothem,andinsomecasesbooksdoexistdedicatedtothem,andImentionsomeofthosebooksinthenextchapter.

I’vetriedtomakeyouawareofthecircumstancesthatwillleadyoutousingtheconcepts.ButIhopeyoufollowandreadtheprovidedresearchlinkssoyouhaveabasicmemoryofthecapability,evenifyouhaven’tusedit,ordon’tyetunderstandit.

Page 236: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to
Page 237: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterTwentyThree-NextSteps

ChapterSummaryThischapterwillprovideyouwitharecommendedsetofnextsteps:

RecommendedReadingListRecommendedVideosRecommendedWebSitesRecommendedNextSteps

Ihopethatifyoumadeitthisfarintothebook,thatyouattemptedtheexercises.Ifyoudid,andyoufollowedthesuggestionspepperedthroughoutthebook,thenyounowhaveagraspofthefundamentalsofwritingJavacode.Thischaptersuggestsbooksandwebsitestovisittohelpyoucontinuetolearn.

Certainlyyou’veseenalotofcodesnippets.Mostofthecodeyouhaveseenhasbeenwrittenintheformof@Testannotatedmethodswithassertions.Prettymuchwhatyouwillbeexpectedtowriteintherealworld.

RecommendedReadingIdon’trecommendalotofJavabooksbecausetheyareaverypersonalthing.TherearebooksthatpeopleraveaboutthatIcouldn’tgetmyheadaround.AndtherearethosethatIlovethatotherpeoplehate.

ButsinceIhaven’tprovidedmassivecoverageoftheJavalanguage.I’veprettymuchgivenyou“justenough”togetgoingandunderstandthecodeyouread.I’mgoingtolisttheJavabooksthatIgainedmostfrom,andstillreferto:

“EffectiveJava”byJoshuaBloch

“ImplementationPatterns”byKentBeck

“GrowingObject-OrientedSoftware,GuidedbyTests”bySteveFreemanandNatPryce

“CoreJava:Volume1-Fundamentals”byCayS.HorstmannandGarryCornell

“CovertJava:TechniquesforDecompiling,PatchingandReverseEngineering”byAlexKalinovsky

“JavaConcurrencyinPractice”byBrianGoetz

“MasteringRegularExpressions”byJeffreyFriedl

Page 238: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Now,tojustifymyselections…

EffectiveJava“EffectiveJava”byJoshuaBloch,atthetimeofwritinginits2ndEdition.Thisbookworksforbeginnersandadvancedprogrammers.

Javadevelopersbuildupalotofknowledgeabouttheirlanguagefromotherdevelopers.“EffectiveJava”helpsshortcutthatprocess.

Ithas78chapters.Each,fairlyshort,butdenseintheircoverageandpresentation.

WhenIfirstreadit,Ifounditheavygoing,becauseIdidn’thaveenoughexperienceorknowledgetounderstanditall.ButIre-readit,andhavecontinuedtore-readitoverthetimeIhavedevelopedmyJavaexperience.AndeachtimeIreadit,Ifindanewnuance,oradeeperunderstandingoftheconcepts.

Becauseeachchapterisshort,Ireturntothisbooktorefreshmymemoryofcertaintopics.

Thiswasalsothebookthathelpedmeunderstandenumwellenoughtousethemandhelpedmeunderstandconcurrencywellenoughtothenread,andunderstand,“JavaConcurrencyinPractice”.

Irecommendthatyoubuyandreadthisbookearlyinyourlearning.Evenifyoudon’tunderstanditall,readitall.Thencomebacktoitagainandagain.ItconcentratesonverypracticalaspectsoftheJavalanguageandcanboostyourreal-worldeffectivenesstremendously.

Youcanfindaverygoodoverviewofthebook,intheformofarecordingofaJoshuaBlochtalkat“GoogleI/O2008-EffectiveJavaReloaded”onYouTube:

youtu.be/pi_I7oD_uGI

ImplementationPatternsAnotherbookthatbenefitsfromrepeatedreading.Youwilltakedifferentinformationfromitwitheachreading,dependingonyourexperiencelevelatthetime.

“ImplementationPatterns”byKentBeckexplainssomeofthethoughtprocessesinvolvedinwritingprofessionalcode.

Thisbookwasoneofthebooksthathelpedme:

concentrateonkeepingmycodesimple,decidetolearnthebasicsofJava(andknowhowtofindinformationwhenIneededit),trytouseinbuiltfeaturesofthelanguage,beforebringinginanewlibrarytomycode.

Thebookisthinand,againdense.MostcomplaintsIseeon-lineseemtostemfromthelengthofthebookandthetersenessofthecoverage.Ifoundthatbeneficial,itmeantverylittlepaddingandwaste.Ihavelearned,orre-learned,somethingfromthisbookeverytimeIreadit.

Page 239: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Otherbooksthatcoversimilartopicsinclude“CleanCode”byRobertC.Martin,and“ThePragmaticProgrammer”byAndrewHuntandDavidThomas.ButIfound“ImplementationPatterns”farmoreusefulandapplicabletomywork.

FormoreinformationonKentBeck’swritingandwork,visithiswebsite:

threeriversinstitute.org

GrowingObject-OrientedSoftwareAnotherbookIbenefitedfromreadingwhenIwasn’treadyforit.Iwasabletore-readitandlearnmore.Istillgainvaluefromre-readingit.

“GrowingObject-OrientedSoftware,GuidedbyTests”,bySteveFreemanandNatPryce

Heavilyfocusedonusing@Testmethodcodetowriteandunderstandyourcode.Italsocoversmockobjectsverywell.

Thisbookhelpedchangemycodingstyle,andhowIapproachthebuildingofabstractionlayers.

Theofficialhomepageforthebookisgrowing-object-oriented-software.com

CovertJava“CovertJava:TechniquesforDecompiling,PatchingandReverseEngineering”,byAlexKalinovskystartstoshowitsagenowasitwaswrittenin2004.ButhighlightssomeofthewaysofworkingwithJavalibrariesthatyoureallywouldn’tuseifyouwereaprogrammer.

Butsometimesasatesterwehavetoworkwithpre-compiledlibraries,withoutsourcecode,andusepartsofthecodebaseoutofcontext.

IfoundthisaveryusefulbookforlearningaboutreflectionandotherpracticesrelatedtotakingapartJavaapplications.

Youcanusuallypickthisupquitecheaplysecondhand.Thereareotherbooksthecoverdecompiling,reverseengineeringandreflection.Butthisonegotmestarted,andIstillfinditclearandsimple.

JavaConcurrencyinPracticeConcurrencyisnotsomethingIrecommendtryingtoworkwithwhenyouarestartingoutwithJava.

Butatsomepointyouwillprobablywanttorunyourcodeinparallel,orcreatesomethreadstomakeyourcodeperformfaster.Andyouwillprobablyfail,andnotreallyunderstandwhy.

Iused“EffectiveJava”tohelpmegetstarted.But“JavaConcurrencyinPractice”byBrianGoetz,wasthebookIreadwhenIreallyhadtomakemyautomationabstractionlayerworkwithconcurrentcode.

Page 240: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

CoreJava:Volume1TheCoreJavabooksaremassive,over1000pages.AndifyoureallywanttounderstandJavaindepththenthesearethebookstoread.

Ifindthemtobehardworkanddon’treadthemoften.ItendtousetheJavaDocfortheJavalibrariesandmethodsthemselves.

But,periodically,Iwanttohaveanoverviewofthelanguageandunderstandthescopeofthebuiltinlibraries,becausetherearelotsofin-builtfeaturesthatIdon’tuse,thatIwouldotherwiseturntoanexternallibraryfor.

EverytimeI’veflickedthrough“CoreJava”,Ihavediscoveredanuanceandanewsetoffeatures,butIdon’tdoitoften.

MasteringRegularExpressionsWedidn’tcoverthefullpowerofRegularExpressionsinthisbook.

ItendtotryandkeepmycodesimpleandreadablesoI’llusesimplestringmanipulationtostartwith.

Butovertime,IoftenfindthatIcanreplaceaseriesofifblocksandstringtransformationswitharegularexpression.

SinceIdon’tuseregularexpressionsoftenIfindthateachtime,Ihavetore-learnthemandIstillturnto“MasteringRegularExpressions”byJeffreyE.F.Friedl.

Asanalternativetoconsider:“RegularExpressionsCookbook”byJanGoyvaerts,whichisalsoverygood.

IsometimesusethetoolRegexMagicregexmagic.com,writtenbyJanGoyvaertswhenwritingregularexpressions,itletsmetestouttheregularexpressionacrossarangeofexampledata,andgeneratesamplecodeforalotofdifferentlanguages.

Janalsomaintainsthewebsiteregular-expressions.infowithalotoftutorialinformationonit.

RecommendedVideosThevideosproducedbyJohnPurcellatcaveofprogramming.comhavebeenrecommendedtomebymanytesters.

I’velookedthroughsomeofthem,andJohnprovidesexamplecodingformanyoftheitemscoveredinthisbook,andinthe“AdvancingConcepts”section.

John’sapproachisgearedaroundwritingprograms,andIthinkthatifyouhavenowfinishedthisbook,youwillbenefitfromthetraditionalprogrammerbasedcoveragethatJohnprovides.

RecommendedWebSitesForgeneralJavanews,anduptodateconferencevideos,Irecommendthefollowingwebsites.

Page 241: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

theserverside.cominfoq.com/java

MakesureyousubscribetotheRSSfeedsfortheabovesites.

IwillremindyouthatIhaveawebsitejavaForTesters.comandIplantoaddmoreinformationthere,andlinkstootherresourcesovertime.Iwillalsoaddadditionalexercisesandexamplestothatsiteratherthancontinuetoexpandthisbook.

Remember,allthecodeusedinthisbook,andtheanswerstotheexercisesisavailabletodownloadfromgithub.com/eviltester.

NextStepsThishasbeenabeginner’sbook.

Youcanseefromthe“AdvancingConcepts”chapterthattherearealotoffeaturesinJavathatIdidn’tcover.ManyofthemIdon’tusealotandIdidn’twanttopadoutthebookwithextensivecoveragethatyoucanfindinotherbooksorvideos.

IwantedthisbooktowalkyouthroughtheJavalanguageinanorderthatIthinkmakessensetopeoplewhoarewritingcode,butnotnecessarilywritingsystems.

Yournextstep?Keeplearning.

Irecommendyoustartwiththebooksandvideosrecommendedhere,butalsoaskyourteammates.

Youwillbeworkingonprojects,andthetypeoflibrariesyouareusing,andthetechnicaldomainthatyouareworkingon,mayrequiredifferentapproachesthanthosementionedinthisbook.

Ihopeyouhavelearnedthatyoucangetalotdonequiteeasily,andyoushouldnowunderstandthefundamentalclassesandlanguageconstructsthatyouneedtogetstarted.

Now:

startwriting@Testmethodswhichexerciseyourproductioncodeinvestigatehowmuchofyourrepeatedmanualeffortcanbeautomated

Thankyouforyourtimespentwiththisbook.

Iwishyouwellforthefuture.ThisisjustthestartofyourworkwithJava.Ihopeyou’llcontinuetolearnmoreandputittouseonyourprojects.

Myabilitytouseautomationtosupportmytestingandaddvalueonprojectscontinuestoincrease,themoreIlearnhowtoimprovemycodingskills.Ihopeyoursdoestoo.

References

JavaForTestersgithub.com/eviltester/javaForTestersCodeJavaForTesters.com

Page 242: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

JoshuaBlochen.wikipedia.org/wiki/Joshua_Blochyoutu.be/pi_I7oD_uGI

KentBecktwitter.com/kentbeck“ThreeRiversInstitute”threeriversinstitute.org

GrowingObjectOrientedSoftware,GuidedbyTestsgrowing-object-oriented-software.comSteveFreeman’sBloghigherorderlogic.comnatpryce.com

CoreJavaBookhorstmann.com/corejava.html

JavaConcurrencyInPracticejcip.net.s3-website-us-east-1.amazonaws.com/

RegularExpressionsMasteringRegularExpressionshomepageregex.inforegular-expressions.info/regexmagic.comregexpal.comwww.regexr.com

Page 243: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Appendix-IntelliJHintsandTips

ThroughoutthebookImentionedhintsandtips,andshortcutsforusingIntelliJ.

Icollateallofthoseinthisappendixforeasyreference,andaddsomeadditionalinformationonusingIntelliJwiththisbook.

ShortcutKeysThistablecontainstheshortcutkeysthatIusemostoften.

Function Windows MacCreateNew alt+insert ctrl+n

IntentionActions

alt+enter alt+enter

IntentionActions

alt+return alt+return

RunJUnitTest ctrl+shift+F10 ctrl+shift+F10

ShowParameters

ctrl+p cmd+p

ShowJavaDoc ctrl+q ctrl+j

CodeCompletion

ctrl+space ctrl+space

Findbyclass ctrl+n ctrl+n

Findbyfilename ctrl+shift+n ctrl+shift+n

Findbysymbol ctrl+shift+alt+

n

ctrl+shift+alt+

n

JetBrainsIntelliJhavesupportingdocumentationontheirwebsite:

ReferencepdfforWindowsandLinuxjetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard.pdf

ReferencepdfforMacOSXjetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard_Mac.pdf

Andthehelpfileshave“Keyboardshortcutsyoucannotmiss”

jetbrains.com/idea/help/keyboard-shortcuts-you-cannot-miss.html

CodeCompletionCodecompletionisyourfriend.YoucanuseittoexploreAPIsandLibraries.

Allyoudoisstarttypingandafterthe.youwillseecontextspecificitemsyoucanuse.

Page 244: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Youcanforceastartofcodecompletionifyouclosethepop-upmenubypressing:

ctrl+space

NavigatingSourceCode

ctrl+click

Foranymethodinyourcode,eitherabuiltinmethod,oralibrarymethod,orevenonethatyouhavewritten.Youcanholddownctrlandleftmouseclickonthemethodnametojumptothesourceofthatmethod.

YoumightbepromptedtoallowIntelliJtodownloadthesourceforexternallibraries.

Thiscanhelpwhenworkingwiththeexamplesourcecodeforthisbookasyoucannavigatetothedomainobjectsfromwithinthe@Testmethodcode.

FindingClassesandSymbolsIfinthisbookyouseeamethodnameoraclassname,butdon’tknowwheretofinditinthesourcecodethenyoucanusethefindfunctionalityinIntelliJtohelp.

Tofindaclassbyname,usethekeyboardshortcut:

ctrl+n

Thiscanperformpartialmatching,soyoudon’thavetotypeinthefullnameoftheclass.

Ifyouwanttofinda‘file’intheprojectthenusekeyboardshortcut:

ctrl+shift+n

Ifyouwanttofindamethodname,orvariablename(symbol)thenusethekeyboardshortcut:

ctrl+shift+alt+n

RunningaJUnitTestAnnotatingmethodswith@Testmakesiteasyforusto‘run’themethodswewrite.YoucanrightclickonthemethodnameorclassandchoosetoRunasJUnittest.Oruseshortcutkey:

ctrl+shift+F10

LoadingProjectSourceTheeasiestwaytoloadaprojectintoIntelliJ,andthisappliestothebookexamplesourcecode,istouse:

File\Openandselectthepom.xmlfile.

Page 245: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

HelpMenuThehelpmenudoesmorethanofferalinktoahelpfile.

FindActionThemenuoptionHelp\FindActionallowsyoutotypeanactionandIntelliJwillprovidemenuoptionsandshortcutkeystohelp.

e.g.

SelectHelp\FindActiontype“junit”andyouwillseealistof‘settings’youcanusetohelpconfigureJUnitinIntelliJtype“run”andyouwillseealistofoptionsforrunningcode,ortests

Thelistisn’tjustforinformation,youcanclickontheitemsinthelistandyouwillbetakentothefunctionalityinIntelliJorrunthecommand.

ProductivityGuideTheHelp\ProductivityGuidemenuoptionshowsadialogwithcommonproductivityimprovements.

Youcanclickontheitemsinthelisttoseewhatitdoes,andyoucanalsoseewhichonesyouhaveused,andwhichyouhaven’t.

ThiscanhelpyoulearnthebasicsofIntelliJveryquickly.

SummaryIntelliJoffersalotofflexibilityinhowweworkwithcode.OvertimeyouwilllearntomakeyourworkwithJavafasterasyoulearnmoreabouttheIDE.

OvertimeIwilladdvideosandinformationtoJavaForTesters.comtodemonstratemorefunctionalitywithIntelliJthatIdonothavespacetoaddtothisbook.

Page 246: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Appendix-ExerciseAnswers

Thisappendixcontainsanswersto,andcommentaryon,theexercisesinthebook.

Allthecodefoundhere,canalsobefoundinthesupportingsourcecodegithubrepository:

https://github.com/eviltester/javaForTestersCode

ChapterThree-MyFirstJUnitTest

Checkfor5insteadof4WhenIrantheJUnittestIsawconsoleoutputinformingmeofanAssertionError.1java.lang.AssertionError:2+2=4expected:<5>butwas:<4>

2 atorg.junit.Assert.fail(Assert.java:88)

3 atorg.junit.Assert.failNotEquals(Assert.java:743)

4 atorg.junit.Assert.assertEquals(Assert.java:118)

5 atorg.junit.Assert.assertEquals(Assert.java:555)

6 atcom.javafortesters.chap003myfirsttest.examples.MyFirstTest.

7 canAddTwoPlusTwo(MyFirstTest.java:19)

Theactualmessagewaslongerthanthis,butwewillexplainerrormessagesinalaterchapter.

ItisimportanttonotethatinIntelliJIcouldclickonthehypertextintheerrormessageMyFirstTest.java:19andIwillbetakentothelineofcodeintheeditorthatthrewtheexception.Didyoutryclickingonthelink?Itmakesdebuggingaloteasier.

Createadditional@Testmethodstocheck@Test

publicvoidcanSubtractTwoFromTwo(){

intanswer=2-2;

assertEquals("2-2=0",0,answer);

}

@Test

publicvoidcanDivideFourByTwo(){

intanswer=4/2;

assertEquals("4/2=2",2,answer);

}

@Test

publicvoidcanMultiplyTwoByTwo(){

intanswer=2*2;

assertEquals("2*2=4",4,answer);

}

CheckthenamingoftheTestclasses

Page 247: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IntheexamplecodeyouwillseethatIhavewrittentheJUnitteststhatdonotrunfromMaven,asfailingmethodsi.e.theassertionsfail.Justtomakethepointthatnamingisveryimportant.publicclassNameClass{

@Test

publicvoidwhenClassNameHasNoTestInItThenItIsNotRun(){

//thistestwillnotrunfrommavensoicanmake

//afailingtest…itfailsintheIDE

assertTrue("whenClassNameHasNoTestInItThenItIsNotRun",

false);

}

}

publicclassNameClassTest{

@Test

publicvoidwhenClassHasTestAtEndThenTestIsRun(){

//thistestwillrunfrommavensoitneedstopass

assertTrue("whenClassHasTestAtEndThenTestIsRun",

true);

}

}

publicclassNameTestClass{

@Test

publicvoidwhenClassHasTestInMiddleThenTestIsNotRun(){

//thistestwillnotrunfrommavensoicanmake

//afailingtest…itfailsintheIDE

assertTrue("whenClassHasTestInMiddleThenTestIsNotRun",

false);

}

}

publicclassTestNameClass{

@Test

publicvoidwhenClassHasTestAtFrontThenTestIsRun(){

//thistestwillrunfrommavensoitneedstopass

assertTrue("whenClassHasTestAtFrontThenTestIsRun",

true);

}

}

ChapterFour-WorkWithOtherClasses

ConvertaninttoHex@Test

publicvoidcanConvertIntToHex(){

assertEquals("hex11isb","b",

Integer.toHexString(11));

assertEquals("hex10isb","a",

Integer.toHexString(10));

assertEquals("hex3isb","3",

Integer.toHexString(3));

assertEquals("hex21isb","15",

Integer.toHexString(21));

}

ConfirmMAXandMINIntegersizes

Page 248: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Test

publicvoidcanConfirmIntMinAndMaxLimits(){

intminimumInt=-2147483648;

intmaximumInt=2147483647;

assertEquals("integermin",minimumInt,Integer.MIN_VALUE);

assertEquals("integermax",maximumInt,Integer.MAX_VALUE);

}

ChapterFive-WorkWithOurOwnClasses

ExperimentwiththecodeWhenyoureplacetheStringwithanint,youshouldseeasyntaxerrorbecauseanintdoesnotsatisfythemethoddeclarationwhichneedsaString

WhenyoureplacetheStringliteral"http://192.123.0.3:67"withnull,youwon’tgetasyntaxerrorbecausenullisavalidobjectreference,butifyourunthe@Testmethoditshouldfail.

ConvertfromStaticUsagetoStaticImportTheexamplesourceshowstheindividualimportsofDOMAINandPORT,ifIcommentthosetwoimportsoutandaddintheimportforTestAppEnv.*thenIhaveimportedeverythingstaticallyandthenhavetheoptiontoremovetheTestAppEnvprefixfromgetUrl,butIdon’thaveto.

InormallywouldnotimportTestAppEnvstaticallyasIdon’tthinkitisasreadableasasimpleimportoftheclass.1importcom.javafortesters.domainobject.TestAppEnv;

2importorg.junit.Assert;

3importorg.junit.Test;

4

5//IcouldimporteverythingonTestAppEnvstatically,andthen

6//Idon'tneedtoprefixgetUrlwithTestAppEnv

7/*

8importstaticcom.javafortesters.domainobject.TestAppEnv.*;

9*/

10//IfIjustimporttheDOMAINandPORTthenIstillneedto

11//prefixgetUrlwithTestAppEnv

12importstaticcom.javafortesters.domainobject.TestAppEnv.DOMAIN;

13importstaticcom.javafortesters.domainobject.TestAppEnv.PORT;

14

15

16publicclassTestAppEnvironmentNoStaticImportTest{

17

18@Test

19publicvoidcanGetUrlStatically(){

20Assert.assertEquals("ReturnsHardCodedURL",

21"http://192.123.0.3:67",

22TestAppEnv.getUrl());

23}

24

25@Test

26publicvoidcanGetDomainAndPortStatically(){

Page 249: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

27

28Assert.assertEquals("JusttheDomain",

29"192.123.0.3",

30DOMAIN);

31

32Assert.assertEquals("Justtheport",

33"67",

34PORT);

35}

36}

ChapterSix-JavaClassesRevisited:Constructors,Fields,Getter&SetterMethods

ExperimentwiththepackagestructureWhenIhavetheJunitTestclassinthesamepackageastheUserclassthenIdonotneedtoimportit.Eventhoughweareindifferentsourcehierarchiesi.e.oneinsrc\testandoneinsrc\main.1packagecom.javafortesters.domainentities;

2

3importorg.junit.Test;

4

5importstaticorg.junit.Assert.assertEquals;

6

7publicclassUserTest{

IfIchangethepackagethenIhavetoaddtheimportfortheUserclass.1packagecom.javafortesters.chap006domainentities.exercises.differentpackage;

2

3importcom.javafortesters.domainentities.User;

4importorg.junit.Test;

5importstaticorg.junit.Assert.assertEquals;

6

7publicclassUserTest{

IwouldalsohavetoaddtheimportifthereweremultipleUserclassesinmycodebase,inordertotellJavawhichoneIwanttouse.

ExperimentwithprivateandpublicfieldsWhenaclasshasfieldswhicharepublic:1publicclassUser{

2publicStringusername;

3publicStringpassword;

4

5publicUser(){

6username="admin";

7password="pA55w0rD";

8}

9}

Thenitdoesn’treallyneedgetterorsettermethods.

Page 250: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ButtheUserclasshasnocontroloveritsdata.Laterweaddchecksonthesetterandgettermethodssothatwecan’taddinvaliddatatotheobject.Ifyoumakethefieldspublicthenyoudon’thavethosesafeguards.1@Test

2publicvoidcanConstructWithUsernameAndPassword(){

3Userauser=newUser();

4auser.username="bob";

5assertEquals("notdefaultusername",

6"bob",

7auser.username);

8}

9

10@Test

11publicvoidcanSetNameToInvalidValue(){

12Userauser=newUser();

13auser.username="12345£$%$";

14assertEquals("invalidusername",

15"12345£$%$",

16auser.username);

17}

ExperimentwiththefieldandparameternamesWhenyouremovethis.fromtheconstructor:1publicUser(Stringusername,Stringpassword){

2username=username;

3password=password;

4}

WhenJavaseestheline:1username=username;

Itexecutesit,butassignsthevaluepassedinastheparametertotheparameter,andnottothefield,soourfieldcalledusernameisneverassignedavalueandsoisnull,asreportedbytheassertionmessage:java.lang.AssertionError:givenusernameexpectedexpected:<admin>butwas:

<null>

Whenwerenametheparameters:1publicUser(StringaUsername,StringaPassword){

2username=aUsername;

3password=aPassword;

4}

Thenwedonotneedthethiskeyword.Theparametersandfieldshavedifferentnames,sotheywillnotclash.

Itisuptoyouwhichstyleyouchoosetoadoptforyourcoding.

Iusebothandswitchbetweenthematdifferenttimes.Bynamingtheparameterthesameasthefield,andusingthethiskeywordtodistinguishthem,whenIusecodecompletionintheconstructor,thecodecompletionshowsmeusernameandpasswordmakingiteasyformetoseewhattheparametersreferto.Thiscodecompletionusecaseisthemain

Page 251: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

decisionmakerforme,whenIchoosewhetherornottousethisorrenametheparameters.

ChapterEight-SelectionsandDecisions

CatorCats?TernaryOperatorWritean@Testmethodthatusesaternaryoperatortoreturn“cats”ifanumberOfCatsequals1.Andreturn"cat"ifthenumberOfCatsisnot11@Test

2publicvoidcatOrCats(){

3

4intnumberOfCats=1;

5

6assertEquals("1==cat",

7"cat",

8(numberOfCats==1)?"cat":"cats");

9

10numberOfCats=0;

11assertEquals("0==cats",

12"cats",

13(numberOfCats==1)?"cat":"cats");

14

15numberOfCats=2;

16assertEquals("2==cats",

17"cats",

18(numberOfCats==1)?"cat":"cats");

19}

WhenIrewritethecodesothatitusesamethod,thenthecodeiscleanerandavoidstherepetition.1@Test

2publicvoidcatOrCatsAsMethod(){

3

4assertEquals("1==cat","cat",catOrCats(1));

5

6assertEquals("0==cats","cats",catOrCats(0));

7

8assertEquals("2==cats","cats",catOrCats(2));

9}

10

11privateStringcatOrCats(intnumberOfCats){

12return(numberOfCats==1)?"cat":"cats";

13}

AssertTrueiftrue1@Test

2publicvoidtruthyIf(){

3booleantruthy=true;

4

5if(truthy)

6assertTrue(truthy);

7

8if(truthy){

9assertTrue(truthy);

Page 252: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

10assertFalse(!truthy);

11}

12}

AssertTrueelseAssertFalseForasinglestatementIdonotneedtoaddthebraces:1@Test

2publicvoidtruthyIfElse(){

3booleantruthy=true;

4

5if(truthy)

6assertTrue(truthy);

7else

8assertFalse(truthy);

9}

WhenthereismorethanonestatementintheifortheelsethenIneedtoaddthe{}braces:1@Test

2publicvoidtruthyIfElseBraces(){

3booleantruthy=true;

4

5if(truthy){

6assertTrue(truthy);

7assertFalse(!truthy);

8}else{

9assertFalse(truthy);

10}

11}

Icanchoosetoleaveoffthebracesfortheelsebecausethereisonlyonecondition,butinpracticeIwouldnotdothisbecauseImightwanttoexpandthenumberofstatementsontheelseconditioninthefuture,andImakethecodehardertoreview:1@Test

2publicvoidtruthyIfElseOnlyOneSetOfBraces(){

3booleantruthy=true;

4

5if(truthy){

6assertTrue(truthy);

7assertFalse(!truthy);

8}else

9assertFalse(truthy);

10}

NestedIfElseHorrorIfyoueverfindyourselfwritingcodelikethefollowingthenIguaranteethatyouhavedonesomethingwrong,andhavenotthoughtthroughtheproblemproperly.

IdecidedtopullthemainlogicoutintoaseparatemethodsothatIcouldcallitmoreeasilywiththedifferentcombinationsoftrueandfalsefortruthyandfalsey.

IalsoaddedasetofSystem.out.printlnsothatIcouldseethetruthtablecombinations.ItwasfortunateIdidthisbecauseIactuallymadeamistakeinthenestedif/elsestatementswhenIfirstwrotemyanswer-howdidyoucheckyouranswer?

Page 253: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

1@Test

2publicvoidnestedIfElseHorror(){

3horrorOfNestedIfElse(true,true);

4horrorOfNestedIfElse(true,false);

5horrorOfNestedIfElse(false,true);

6horrorOfNestedIfElse(false,false);

7}

8

9publicvoidhorrorOfNestedIfElse(booleantruthy,booleanfalsey){

10

11if(truthy){

12if(!falsey){

13if(truthy&&!falsey){

14if(falsey||truthy){

15System.out.println("T|F");

16assertTrue(truthy);

17assertFalse(falsey);

18}

19}

20}else{

21System.out.println("T|T");

22assertTrue(truthy);

23assertTrue(falsey);

24}

25}else{

26if(!truthy){

27if(falsey){

28System.out.println("F|T");

29assertTrue(falsey);

30assertFalse(truthy);

31}else{

32System.out.println("F|F");

33assertFalse(falsey);

34assertFalse(truthy);

35}

36}

37}

38}

SwitchonShortCodeIaddedabreak,afterthedefault.Removethebreaktoverifyforyourselfifitisrequiredornot,anddecideifthereisanydifferenceinthereadabilityofthecode.

Also,removesomeofthebreakstatementsandverifythattheresultsarenotasexpected.1@Test

2publicvoidcountrySwitch(){

3

4assertEquals("UnitedKingdom",countryOf("UK"));

5assertEquals("UnitedStates",countryOf("US"));

6assertEquals("UnitedStates",countryOf("USA"));

7assertEquals("UnitedStates",countryOf("UsA"));

8assertEquals("France",countryOf("FR"));

9assertEquals("Sweden",countryOf("sE"));

10assertEquals("RestOfWorld",countryOf("ES"));

11assertEquals("RestOfWorld",countryOf("CH"));

12}

13

Page 254: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

14privateStringcountryOf(StringshortCode){

15

16Stringcountry;

17

18switch(shortCode.toUpperCase()){

19case"UK":

20country="UnitedKingdom";

21break;

22case"US":

23case"USA":

24country="UnitedStates";

25break;

26case"FR":

27country="France";

28break;

29case"SE":

30country="Sweden";

31break;

32default:

33country="RestOfWorld";

34break;

35}

36

37returncountry;

38}

SwitchonintThisexercisewasdesignedtoallowyoutoswitchonvariablesotherthanString,andalsotoseewhatcreativeapproachyouadoptedforthe>4and<1conditions.

Inmyanswerbelow,youcanseethatIaddedasetofifstatementsinthedefaultblock.1@Test

2publicvoidintegerSwitch(){

3

4assertEquals("One",integerString(1));

5assertEquals("Two",integerString(2));

6assertEquals("Three",integerString(3));

7assertEquals("Four",integerString(4));

8assertEquals("Toobig",integerString(5));

9assertEquals("Toobig",integerString(Integer.MAX_VALUE));

10assertEquals("Toosmall",integerString(0));

11assertEquals("Toosmall",integerString(Integer.MIN_VALUE));

12}

13

14privateStringintegerString(intanInt){

15

16StringvalReturn="";

17

18switch(anInt){

19case1:

20valReturn="One";

21break;

22case2:

23valReturn="Two";

24break;

25case3:

26valReturn="Three";

Page 255: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

27break;

28case4:

29valReturn="Four";

30break;

31default:

32if(anInt<1){

33valReturn="Toosmall";

34}

35if(anInt>4){

36valReturn="Toobig";

37}

38break;

39}

40

41returnvalReturn;

42}

Andfortheextrapoints,youexploredwritingaswitchstatementwithoutusingbreak;.

Inthisexample,becausethemethodissosimple,thecodeactuallyreadsquitewell,andsuccinctly.Ididhavetoaddanextrareturn"";line,whichwillneverbeexecuted,inordertosatisfythemethod’sdeclarationofreturningaString.1privateStringintegerStringUsingReturnOnly(intanInt){

2switch(anInt){

3case1:

4return"One";

5case2:

6return"Two";

7case3:

8return"Three";

9case4:

10return"Four";

11default:

12if(anInt<1){

13return"Toosmall";

14}

15if(anInt>4){

16return"Toobig";

17}

18}

19

20return"";

21}

ChapterNine-ArraysandForLoopIteration

CreateanArrayofUsersInordertoworkwiththeUserobjects,IfirsthadtoimporttheUserclass.importcom.javafortesters.domainentities.User;

ThenIcreatedthearrayandaddedtheusers.@Test

publicvoidcreateAnArrayOfUsers(){

User[]users=newUser[3];

Page 256: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

users[0]=newUser("bob","bA55Word");

users[1]=newUser("eris","eA55Word");

users[2]=newUser("ken","kA55Word");

assertEquals("bob",users[0].getUsername());

assertEquals("eris",users[1].getUsername());

assertEquals("ken",users[2].getUsername());

}

NotethatIaddedassertsontheusernametocheckthatIhadaddedtheuserscorrectly.Didyouaddassertstoyour@Testmethod?Ifnot,howdidyouknowitworked?

IterateovertheArrayofUsersIaddedthefollowingcodetomy@Testmethodabove,toiterateoverthearrayandprintoutthevaluesinthearray:for(UseraUser:users){

System.out.println(aUser.getUsername());

}

Createanarrayof100usersInmysampleanswer,IchosetoSystem.out.printlnthearraytocheck.

Icouldhaveputabreakpointaftertheloopandusedthedebuggertocheckbyrunningthecodeindebugmode.

Iaddedassertioncode,whichusestheforeachsoIiterateovereveryitem,andcounteachitem,usingthecountuserIdtochecktheusernameandpassword.SinceIknowthattherearesupposedtobe100,whenIexittheforeachloop,IexpectmyuserIdtoequal101.

Youmayhavechosenanothermethod.That’sfine.Therearemanywaystodothis.@Test

publicvoidexerciseCreateAnArrayOf100Users(){

User[]users=newUser[100];

for(intuserIndex=0;userIndex<100;userIndex++){

intuserId=userIndex+1;

users[userIndex]=newUser("user"+userId,

"password"+userId);

}

//checkcreation

for(UseraUser:users){

System.out.println(aUser.getUsername()+

","+

aUser.getPassword());

}

//bonuspointsassertcreation

intuserId=1;

for(UseraUser:users){

assertEquals("user"+userId,aUser.getUsername());

assertEquals("password"+userId,aUser.getPassword());

userId++;

}

//checkthelastoneoutputwas100,i.e.nextwouldbe101

Page 257: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals(userId,101);

}

SortWorkdaysArrayandAssertResultThetextissortedinalphabeticalorder,andsinceallthestringsstartwithuppercase,thewordsareintheorderwewouldexpect.@Test

publicvoidsortWorkdaysArrayAndAssertResult(){

String[]workdays={"Monday","Tuesday","Wednesday",

"Thursday","Friday"};

Arrays.sort(workdays);

assertEquals(workdays[0],"Friday");

assertEquals(workdays[1],"Monday");

assertEquals(workdays[2],"Thursday");

assertEquals(workdays[3],"Tuesday");

assertEquals(workdays[4],"Wednesday");

}

Afteramendingthedaynames,Iexpectthewordsstartingwithlowercaseletterstocomeafterthewordswithuppercaseletters.@Test

publicvoidsortWorkdaysMixedCaseArrayAndAssertResult(){

String[]workdays={"monday","Tuesday","Wednesday",

"thursday","Friday"};

Arrays.sort(workdays);

assertEquals(workdays[0],"Friday");

assertEquals(workdays[1],"Tuesday");

assertEquals(workdays[2],"Wednesday");

assertEquals(workdays[3],"monday");

assertEquals(workdays[4],"thursday");

}

Understandhowprint2DIntArraymethodworks1publicvoidprint2DIntArray(int[][]multi){

2for(int[]outer:multi){

3if(outer==null){

4System.out.print("null");

5}else{

6for(intinner:outer){

7System.out.print(inner+",");

8}

9}

10System.out.println("");

11}

12}

line01:declarethemethodasacceptinga2dimensionalintarrayasparameterline02:iterateovertheouterarrayline03:iftheouterarrayisnull,then…

line04:output"null",wedonottryandprocessthecontentsofthisarray

Page 258: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

line05:theouterarrayisnotnull,therefore…line06:iterateoverthecontentsofthisarray

line07:outputthecontentsofthearraycellline10:outputablankline

CreateaTriangleTocreateatriangle,Icreatethearraytoallowaraggedarray.

Thenloopoverthearray,andassignanarraytoeachcellinthearray.

Foreachofthenewarrays,Iloopoverthecellcontentsandinserttheindexvalue.@Test

publicvoidcreateTriangle2dArray(){

int[][]triangle=newint[16][];

for(introw=0;row<triangle.length;row++){

triangle[row]=newint[row+1];

for(inti=0;i<(row+1);i++){

triangle[row][i]=i;

}

}

print2DIntArray(triangle);

}

publicvoidprint2DIntArray(int[][]multi){

for(int[]outer:multi){

if(outer==null){

System.out.print("null");

}else{

for(intinner:outer){

System.out.print(inner+",");

}

}

System.out.println("");

}

}

ChapterTen-IntroducingCollections

Useaforloopinsteadofawhileloop@Test

publicvoiduseAForLoopInsteadOfAWhile(){

String[]someDays={"Tuesday","Thursday",

"Wednesday","Monday",

"Saturday","Sunday",

"Friday"};

List<String>days=Arrays.asList(someDays);

intforwhile;

for(forwhile=0;!days.get(forwhile).equals("Monday");forwhile++){

}

Page 259: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals("Mondayisatposition3",3,forwhile);

}

CreateandmanipulateaCollectionofUsers@Test

publicvoidcreateAndManipulateACollectionOfUsers(){

Collection<User>someUsers=newArrayList<User>();

Userbob=newUser("bob","Passw0rd");

Usereris=newUser("eris","Cha0sTime");

assertEquals(0,someUsers.size());

assertTrue(someUsers.isEmpty());

someUsers.add(bob);

someUsers.add(eris);

assertEquals(2,someUsers.size());

assertFalse(someUsers.isEmpty());

Collection<User>secondUsers=newArrayList<User>();

Userrobert=newUser("robert","9assword");

Useraleister=newUser("aleister","Pass5word");

secondUsers.add(robert);

secondUsers.add(aleister);

assertEquals(2,secondUsers.size());

someUsers.addAll(secondUsers);

assertEquals(4,someUsers.size());

assertTrue(someUsers.containsAll(someUsers));

assertTrue(someUsers.contains(aleister));

secondUsers.removeAll(someUsers);

assertEquals(0,secondUsers.size());

someUsers.clear();

assertEquals(0,someUsers.size());

}

CreateandmanipulateaListofUsers@Test

publicvoidcreateAndManipulateAListOfUsers(){

List<User>someUsers=newArrayList<User>();

assertEquals(0,someUsers.size());

Userbob=newUser("bob","Passw0rd");

Usereris=newUser("eris","Cha0sTime");

someUsers.add(bob);

assertEquals(1,someUsers.size());

someUsers.add(0,eris);

assertEquals(2,someUsers.size());

assertEquals(1,someUsers.indexOf(bob));

assertEquals(0,someUsers.indexOf(eris));

Page 260: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

someUsers.remove(0);

assertEquals(0,someUsers.indexOf(bob));

assertEquals(1,someUsers.size());

}

CreateandmanipulateaSetofUsers@Test

publicvoidcreateAndManipulateASetOfUsers(){

Set<User>someUsers=newHashSet<User>();

assertEquals(0,someUsers.size());

Userbob=newUser("bob","Passw0rd");

someUsers.add(bob);

assertEquals(1,someUsers.size());

someUsers.add(bob);

assertEquals(1,someUsers.size());

}

CreateandmanipulateaMapofUsers@Test

publicvoidcreateAndManipulateAMapOfUsers(){

Map<String,User>someUsers=newHashMap<String,User>();

assertEquals(0,someUsers.size());

Userbob=newUser("bob","Passw0rd");

Usereris=newUser("eris","Cha0sTime");

someUsers.put(bob.getUsername(),bob);

assertEquals(1,someUsers.size());

someUsers.put(bob.getUsername(),eris);

assertEquals(1,someUsers.size());

}

ChapterEleven-IntroducingExceptions

FixtheNullPointerExceptioninthecodeAllIhadtodowastakethecodelistedearlierinthechapter,andassign18totheagevariablebeforetryingtoaccessit.@Test

publicvoidnoLongerThrowANullPointerException(){

Integerage=18;

StringageAsString=age.toString();

StringyourAge=

"Youare"+ageAsString+"yearsold";

Page 261: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals("Youare18yearsold",yourAge);

}

Uninitialisedvariables,andparametersareacommonsourceofexceptions.

UseadifferentexceptioninsteadofNullPointerExceptionWhenIreplacedNullPointerExceptionwithArithmeticException.

TheNullPointerExceptionisthrownbecausetherewasnocodetocatchit.@Test(expected=NullPointerException.class)

publicvoidcatchADifferentException(){

Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(ArithmeticExceptione){

age=18;

ageAsString=age.toString();

}

StringyourAge=

"Youare"+age.toString()+"yearsold";

assertEquals("Youare18yearsold",yourAge);

}

YoucanseeIusedtheexpectedparametertoallowmetocheckforthisExceptionthrownbythe@Testmethod.

Don’tfixthecauseoftheexceptionWhenIremovetheage=18;statementfromwithinthecatchblockandrunthecode.ThecodethrewaNullPointerExceptionbecauseweaddednotrycatchblockinsidethecatchblock.@Test(expected=NullPointerException.class)

publicvoidtestNotFixedStillThrowsNullPointer(){

Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(ArithmeticExceptione){

//age=18;

ageAsString=age.toString();

}

StringyourAge=

"Youare"+age.toString()+"yearsold";

assertEquals("Youare18yearsold",yourAge);

}

Page 262: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

CatchaCheckedExceptionWhenIusedNoSuchMethodExceptioninsteadofNullPointerException.Ireceivedasyntaxerror.@Test

publicvoidthisTriggersASyntaxErrorBecauseExceptionIsNotDeclared(){

Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(NoSuchMethodExceptione){

age=18;

ageAsString=age.toString();

}

StringyourAge=

"Youare"+age.toString()+"yearsold";

assertEquals("Youare18yearsold",yourAge);

}

IreceivedasyntaxerrorontheNoSuchMethodExceptionline:}catch(NoSuchMethodExceptione){

NoSuchMethodExceptionisacheckedexceptionandneedstobedeclaredasthrownbymethods.ThetoStringmethoddoesnotdeclarethatitwillthrowaNoSuchMethodExceptionsoIreceiveasyntaxerror.

NullPointerExceptionandArithmeticExceptionareuncheckedexceptionsanddon’tneedtobedeclaredasthrownbymethods.

UseExceptionasanobjectWhenIaddthecodetousethemethodsontheexception:@Test

publicvoiduseExceptionAsAnObject(){

Integerage=null;

StringageAsString;

try{

ageAsString=age.toString();

}catch(NullPointerExceptione){

System.out.println("getMessage-"+

e.getMessage());

System.out.println("getStacktrace-"+

e.getStackTrace());

System.out.println("printStackTrace");

e.printStackTrace();

}

}

Page 263: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Ireceivethefollowingoutput,Ihavecutdowntheoutputtosavespaceso...representssomemissingoutput:getMessage-null

getStacktrace-[Ljava.lang.StackTraceElement;@4ea3c69a

printStackTrace

java.lang.NullPointerException

atcom.javafortesters.exceptions.exercises.IntroducingExceptionsExercisesTest.

useExceptionAsAnObject(IntroducingExceptionsExercisesTest.java:99)

...

atjava.lang.reflect.Method.invoke(Method.java:601)

atcom.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

FromthisIcanseethatgetMessageonaNullPointerExceptiondoesnotreturnamessage,soweneedtousethestacktracetofigureoutwhatwentwrong.Otherexceptionsdoreturnmessages,andwhenyoustartcreatingyourownexceptions,Irecommendthatyouaddamessagetomakeiteasierforotherpeopletounderstandtheprobleminthecode.

ThegetStacktraceisanarrayofStackTraceElementObjects,soIcouldaccesselement[0],whichisthemostrecentitemontheArray,anduseittofindinformationaboutthatpartofthestacktracee.g.

getClassName

getFileName

getLineNumber

getMethodName

System.out.println("StackTraceLength-"+

e.getStackTrace().length);

System.out.println("StackTrace[0]classname-"+

e.getStackTrace()[0].getClassName());

System.out.println("StackTrace[0]filename-"+

e.getStackTrace()[0].getFileName());

System.out.println("StackTrace[0]linenumber-"+

e.getStackTrace()[0].getLineNumber());

System.out.println("StackTrace[0]methodname-"+

e.getStackTrace()[0].getMethodName());

whichwoulddisplay:StackTraceLength-27

StackTrace[0]classname-com.javafortesters.exceptions.exercises

IntroducingExceptionsExercisesTest

StackTrace[0]filename-IntroducingExceptionsExercisesTest.java

StackTrace[0]linenumber-100

StackTrace[0]methodname-useExceptionAsAnObject

FormoreinformationontheStackTraceElementyoucanreadtheofficialdocumentation:

docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html

ChapterTwelve-IntroducingInheritance

CreateaUserthatiscomposedofTestAppEnv

Page 264: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Ihavemultipleapproachesforimplementingthis.

Ican:

createaTestAppEnvobjectwithinmyUserobject,orre-useTestAppEnvstaticallyfromwithinmyUserobjectcreateanewEnvironmentUserobjectwhichextendsobjectandusesTestAppEnv

CreateaTestAppEnvobjectwithinmyUserobject

TocreateaTestAppEnvobjectwithinmyUserobjectIcould:

addanewTestAppEnvfield,instantiatetheobjectintheconstructor,andimplementagetUrlmethodontheobject.

publicclassUser{

privateStringusername;

privateStringpassword;

privateTestAppEnvtestAppEnv;

publicUser(){

this("username","password");

}

publicUser(Stringusername,Stringpassword){

this.username=username;

this.password=password;

this.testAppEnv=newTestAppEnv();

}

publicStringgetUsername(){

returnusername;

}

publicStringgetPassword(){

returnpassword;

}

publicvoidsetPassword(Stringpassword){

this.password=password;

}

publicStringgetUrl(){

returnthis.testAppEnv.getUrl();

}

}

Re-useTestAppEnvstaticallyfromwithinmyUserobject

SinceTestAppEnvwasoriginallydesignedtobeaccessedstatically,Idon’tneedtodeclareafieldorinstantiateanobject,Icouldjust:

addagetUrlmethodtoUserdelegatetothestaticmethodonTestAppEnv

Page 265: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

publicStringgetUrl(){

returnTestAppEnv.getUrl();

}

CreateanewEnvironmentUser

SincetheEnvironmentUserisaspecialcaseofuser,Idon’tneedtoamendtheUserobjectatall.IcouldcreateanewobjectcalledEnvironmentUserwhichextendsUser,andthenaddanewmethodtotheEnvironmentUserwhichstaticallyusestheTestAppEnvobject.packagecom.javafortesters.chap012inheritance.exercises;

importcom.javafortesters.domainentities.User;

importcom.javafortesters.domainobject.TestAppEnv;

publicclassEnvironmentUserextendsUser{

publicStringgetUrl(){

returnTestAppEnv.getUrl();

}

}

AndIwouldusetheobjectinan@Testmethodasfollows:@Test

publicvoidcreateAnEnvironmentUser(){

EnvironmentUserenuser=newEnvironmentUser();

assertEquals("username",enuser.getUsername());

assertEquals("http://192.123.0.3:67",enuser.getUrl());

}

CreateaReadOnlyUserTocreateaReadOnlyUserwhichhasthepermissionReadOnly,withthesamedefault“username”and“password”fromUser.Ifirstwrotean@Testmethodwhichcheckedforthecorrectimplementation.@Test

publicvoidreadOnlyUserPrivsAndDefaults(){

ReadOnlyUserrod=newReadOnlyUser();

assertEquals("ReadOnly",rod.getPermission());

assertEquals("username",rod.getUsername());

assertEquals("password",rod.getPassword());

}

ThenIimplementedtheReadOnlyUser.ThiswasaverysimpleclasswhichextendstheUser,andimplementsan@OverrideofgetPermissionpackagecom.javafortesters.chap012inheritance.exercises;

importcom.javafortesters.domainentities.User;

publicclassReadOnlyUserextendsUser{

@Override

publicStringgetPermission(){

return"ReadOnly";

}

}

Page 266: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

ChapterThirteen-MoreExceptions

CreateanInvalidPasswordexceptionPartof‘helping’peopleusetheUserdomainobjectistoalertthemtovalidationandexceptionsthattheymightencounterusingtheclass.Wecandothisthroughdocumentation,andwecandothisthroughcustomexceptions.

BycreatinganInvalidPasswordexceptionwealertpeopletothevalidationrulesaroundsettingthepasswordonauser.

Asyousawinthechapter,IcreateaclasswiththecodeforanInvalidPassword:publicclassInvalidPasswordextendsException{

publicInvalidPassword(Stringmessage){

super(message);

}

}

InmyUserclass,ImakethesetPasswordmethodthrowtheInvalidPasswordwhenitfailsthepasswordlengthcheck:publicvoidsetPassword(Stringpassword)throwsInvalidPassword{

if(password.length()<7){

thrownewInvalidPassword("Passwordmustbe>6chars");

}

this.password=password;

}

YoucanseeinthecodethatIpassinamessagetotheInvalidPasswordexceptiontodescribethecircumstancesunderwhichtheexceptionwasthrown.

Inordertocheckallofthis,Icreateaclasswith@Testmethodswhichwillcheck:

theInvalidPasswordexceptionisthrownintheconstructortheInvalidPasswordexceptionisnotthrowninthedefaultconstructortheerrormessagethrownbytheexceptioncontainsthetext“Passwordmustbe>6chars”theInvalidPasswordexceptionisthrownonsetPassword

TocheckthattheInvalidPasswordexceptionisthrownintheconstructor,Iusetheexpectedparametertocheckforthethrownexception.SincetheexceptionisacheckedexceptionIhavetoaddthethrowskeywordinthemethoddeclaration:@Test(expected=InvalidPassword.class)

publicvoidconstructUserWithException()throwsInvalidPassword{

UseraUser=newUser("username","p");

}

Tocheckthatthedefaultconstructordoesnotthrowanexception,allIdoiscreatetheUserandassertthatthedefaultpasswordwascreated.@Test

publicvoidcreateDefaultUserWithNoThrowsInvalidPasswordException(){

UseraUser=newUser();

Page 267: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertEquals("password",aUser.getPassword());

}

Mythinkingaroundthiswas:

SincetheexceptionisChecked,Ican’twritethecodeiftheexceptionisthrownsinceIwouldhavetoeitheraddatrycatchblockoraddthethrowsstatementtothemethod.IassertthattheUserwascreatedcorrectlybecauseifthecreationfailedthentheassertionwouldfail.Ifanexceptionisthrownthenthe@Testmethodwillfail

Tocheckfortheerrormessage,Itryandcatchtheexception,thenchecktheerrormessage:@Test

publicvoidcreateUserWithInvalidPasswordExceptionMessages(){

UseraUser;

try{

aUser=newUser("username","p");

fail("AnInvalidPasswordExceptionshouldhavebeenthrown");

}catch(InvalidPassworde){

assertTrue(e.getMessage().startsWith("Passwordmustbe>6chars"));

}

}

NoteintheabovethatIaddafailstatementinthetryblock:

Idothisbecausetheexceptionissupposedtohavebeenthrownandthisfailstatementshouldneverbereached.IfthefailstatementisreachedthentheexceptionwasnotthrownandIneedtoforcean@Testfailure.IfIdidnotaddthefailstatementandanexceptionwasnotthrownthenthe@Testmethodwouldpass,butforthewrongreasons.

IalsomakesurethatthesetPasswordmethodthrowstheexception.@Test

publicvoidsetPasswordWithInvalidPasswordExceptionMessages(){

UseraUser=newUser();

try{

aUser.setPassword("tiny");

fail("AnInvalidPasswordExceptionshouldhavebeenthrown");

}catch(InvalidPassworde){

assertTrue(e.getMessage().startsWith("Passwordmustbe>6chars"));

}

}

Todothis,IcreatetheUserwiththedefaultconstructorsinceIknowthatwillnotthrowtheexception.ThenwrapthesetPasswordwithatrycatch.AndIrepeatthetextassertioninthecatchblock.NotethatIalsoaddthefailstatement.

Page 268: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thisexerciseisagoodexampleofwhythefailstatementisimportant.Withoutthefailstatementmy@Testmethodscouldpassbecausetheydidnotthrowtheexception.

ChapterFourteen-JUnitExplored

Createan@Testmethodwhichusesalloftheasserts@Test

publicvoidjunitHasAssertions(){

assertEquals(6,3+3);

assertEquals("3+3=6",6,3+3);

assertFalse("falseisfalse",false);

assertFalse(false);

assertTrue("trueistrue",true);

assertTrue(true);

int[]oneTo10={1,2,3,4,5,6,7,8,9,10};

int[]tenToOne={10,9,8,7,6,5,4,3,2,1};

Arrays.sort(tenToOne);

assertArrayEquals(oneTo10,tenToOne);

assertNotNull("Anemptystringisnotnull","");

assertNotNull("");

assertNotSame("Anemptystringisnotnull",null,"");

assertNotSame(null,"");

assertNull("Onlynullisnull",null);

assertNull(null);

assertSame("Onlynullisnull",null,null);

assertSame(null,null);

}

ReplicatealltheJUnitAssertsusingassertThat@Test

publicvoidassertThatWithHamcrestMatchers(){

assertThat(3+3,is(6));

assertThat("3+3=6",3+3,is(6));

assertThat("falseisfalse",false,equalTo(false));

assertThat(false,is(false));

assertThat("trueistrue",true,equalTo(true));

assertThat(true,is(true));

int[]oneTo10={1,2,3,4,5,6,7,8,9,10};

int[]tenToOne={10,9,8,7,6,5,4,3,2,1};

Arrays.sort(tenToOne);

assertThat(oneTo10,equalTo(tenToOne));

assertThat("Anemptystringisnotnull","",

is(not(nullValue())));

assertThat("",is(not(nullValue())));

Page 269: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat("",is(notNullValue()));

assertThat("Onlynullisnull",null,is(nullValue()));

assertThat(null,nullValue());

}

UsealloftheHamcrestmatcherslisted@Test

publicvoiduseTheListedHamcrestMatchers(){

assertThat(3,is(equalTo(3)));

assertThat(3,is(not(4)));

assertThat("Thisisastring",containsString("is"));

assertThat("Thisisastring",endsWith("string"));

assertThat("Thisisastring",startsWith("Thisis"));

}

ChapterFifteen-StringsRevisited

Tryusingtheotherescapecharacters@Test

publicvoidtryUsingTheOtherEscapeCharactersOutputToConsole(){

System.out.println("Newlines,andTabs");

StringfirstLine="|firstline\n";

StringsecondLine="|\tsecondline\n";

StringthirdLine="|\t\tthirdline\n";

StringfullLine=firstLine+secondLine+thirdLine;

System.out.println(fullLine);

System.out.println("Carriagereturnaftereachword");

System.out.println("one\rtwo\rthree\rfour\rfive\r");

System.out.println("Backspaceaftereachword");

System.out.println("one\btwo\bthree\bfour\bfive\b");

System.out.println("Quotesandslashes");

System.out.println("Bob\'stoysaid\"DOSuses\'\\\'\"");

}

Youprobablywon’tnoticemucheffectofsomethecharacterswhenoutputtotheconsole.i.e.\rand\b

Andsometimeswhenyououtputtexttotheconsoleyoudon’tseeexactlywhatyouexpectduetobufferingandflushingtheoutputtotheconsole,sodon’tnaturallyassumethatyourSystem.out.printlnisshowingyouabug,investigateanypotentialbuginthedebuggerorwriteanasserttocheck.

ConstructaString@Test

publicvoidcanConstructStrings(){

Stringempty=newString();

assertThat(empty.length(),is(0));

char[]cArray={'2','3'};

Page 270: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat(newString(cArray),is("23"));

assertThat(newString(cArray,1,1),is("3"));

byte[]bArray="hellothere".getBytes();

assertThat(newString(bArray,3,3),is("lo"));

byte[]b8Array=newbyte[0];

try{

b8Array="hellothere".getBytes("UTF8");

assertThat(newString(b8Array,3,3,"UTF8"),is("lo"));

}catch(UnsupportedEncodingExceptione){

e.printStackTrace();

}

Stringhello=newString("hello"+""+"there");

assertThat(hello,is("hellothere"));

}

YoucanseethatIusedtheHamcrestmatchesandassertThattomakethecodemorereadable.

UseregionMatches@Test

publicvoidexerciseUseRegionMatches(){

Stringhello="Hellofella";

assertTrue(hello.regionMatches(true,9,"younglady",6,2));

}

IfindregionMatchespainfultouse.Imadeseveralmistakestryingtogetthematchingsyntaxlinedupwhenwritingthebookandexercises.

Remember,thefirstintegeristhestartindexintheStringwearematching,thismustmatchthefirstcharacteroftheStringwewanttofind.

Thesecondtwointegersaretheindexinthematchingstringwewantthematchingsubstringregiontostartat,andthefinalintegerthelengthofthesubstringregion.

MakesureyouwrapyourregionMatchesinanasserttocheckyoucreateditcorrectly.

FindpositionsofalloccurrencesinaStringusingindexOfprivateList<Integer>findAllOccurrences(Stringstring,

Stringsubstring){

List<Integer>results=newArrayList<Integer>();

if(string==null||substring==null){

thrownewIllegalArgumentException("Cannotsearchusingnull");

}

if(substring.isEmpty()){

thrownewIllegalArgumentException(

"CannotsearchforEmptysubstring");

}

//setsearchtothestartofthestring

Page 271: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

intlastfoundPosition=0;

do{

//tryandfindthesubstring

lastfoundPosition=string.indexOf(substring,

lastfoundPosition);

//ifwefoundit

if(lastfoundPosition!=-1){

//addittotheresults

results.add(lastfoundPosition);

//nextstartafterthisindex

lastfoundPosition++;

}

//keeplookinguntilwecan'tfindit

}while(lastfoundPosition!=-1);

returnresults;

}

Imayhaveaddedmoreparameterchecksthanyoudid,butsinceI’mreleasingthecodeinabook,I’mtheoneonthereceivingendofemailsthatsay“Youcan’tcode.WhenIpassanemptysubstringinthenthereisaninfiniteloop”etc.etc.

Itisworthgettinginthehabitoftryingtomakeyourcodeasrobustasyoucan.

ItmightalsohelptoseethecodethatIwrotefirst,tohelpmeconstructthismethod.@Test

publicvoidcanFindAllOccurrencesInStringUsingIndexOf(){

List<Integer>results;

results=findAllOccurrences("Hellofella","l");

assertThat(results.size(),is(4));

assertThat(results.contains(2),is(true));

assertThat(results.contains(3),is(true));

assertThat(results.contains(8),is(true));

assertThat(results.contains(9),is(true));

assertThat(results.get(0),is(2));

assertThat(results.get(1),is(3));

assertThat(results.get(2),is(8));

assertThat(results.get(3),is(9));

}

IntheabovecodeyoucanseethatIhavetwochecksforthevalues,usingthe.containsassertThat(results.contains(2),is(true));

Andusingthe.getassertThat(results.get(0),is(2));

MyfeelingwasthatIfirstwantedtomakesurethatthecorrectvalueswereinthelist,andthenIwantedtocheckiftheywereintherightorder.

Page 272: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Thisway,ifIsomehowdidtheminthewrongorder,onlythe.getwouldfail.ButifIfailedtofindtheoccurrencethenthecontainswouldfail.

Itmightseemredundanttohavebothcontainsandget,butIthinkthatbydoingthisthe@TestmethodwillmostlikelyhelpmeinthefutureifIrefactorandsomehowgettheorderofthereturnvalueswrong.

Havingwrittentheabovecode,Istartedtothinkaboutwhatotherparametersthemethodmightbeexpectedtohandle,andwrotethe@Testmethodswhich‘stress’themethod.

Thesehelpedmeaddtheparametercheckingcode.@Test

publicvoidworksWhenNothingToFind(){

List<Integer>results;

results=findAllOccurrences("Hellofella","z");

assertThat(results.size(),is(0));

results=findAllOccurrences("","z");

assertThat(results.size(),is(0));

}

@Test(expected=IllegalArgumentException.class)

publicvoidcannotSearchForEmpty(){

List<Integer>results=findAllOccurrences("","");

}

@Test(expected=IllegalArgumentException.class)

publicvoidcannotSearchForNullString(){

List<Integer>results=findAllOccurrences(null,"hello");

}

@Test(expected=IllegalArgumentException.class)

publicvoidcannotSearchForNullSubString(){

List<Integer>results=findAllOccurrences("hello",null);

}

@Test(expected=IllegalArgumentException.class)

publicvoidcannotSearchForNulls(){

List<Integer>results=findAllOccurrences(null,null);

}

usinglastIndexOf

ToreversethelistIreliedonthelastIndexOfmethod.

Themain@TestmethodIusedwas:@Test

publicvoidcanFindAllOccurrencesInStringUsingLastIndexOf(){

List<Integer>results;

results=findAllOccurrences("Hellofella","l");

assertThat(results.size(),is(4));

assertThat(results.contains(2),is(true));

assertThat(results.contains(3),is(true));

assertThat(results.contains(8),is(true));

assertThat(results.contains(9),is(true));

Page 273: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

assertThat(results.get(0),is(9));

assertThat(results.get(1),is(8));

assertThat(results.get(2),is(3));

assertThat(results.get(3),is(2));

}

IhavenotincludedtheadditionalmethodsthatIusedtocheckthismethod,buttheyaremuchthesameasthoseusedfortheindexOfapproach.privateList<Integer>findAllOccurrences(Stringstring,

Stringsubstring){

List<Integer>results=newArrayList<Integer>();

if(string==null||substring==null){

thrownewIllegalArgumentException("Cannotsearchusingnull");

}

if(substring.isEmpty()){

thrownewIllegalArgumentException(

"CannotsearchforEmptysubstring");

}

//setsearchtothestartofthestring

intlastfoundPosition=string.length();

do{

//tryandfindthesubstring

lastfoundPosition=string.lastIndexOf(substring,

lastfoundPosition);

//ifwefoundit

if(lastfoundPosition!=-1){

//addittotheresults

results.add(lastfoundPosition);

//nextstartbeforethisindex

lastfoundPosition--;

}

//keeplookinguntilwecan'tfindit

}while(lastfoundPosition!=-1);

returnresults;

}

RegularExpressionsforUsersetPasswordpublicvoidsetPassword(Stringpassword)throwsInvalidPassword{

if(password.length()<7){

thrownewInvalidPassword("Passwordmustbe>6chars");

}

if(!password.matches(".*[0123456789]+.*")){

thrownewInvalidPassword(

"Passwordmusthaveadigit");

}

Page 274: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

if(!password.matches(".*[A-Z]+.*")){

thrownewInvalidPassword(

"PasswordmusthaveanUppercaseLetter");

}

this.password=password;

}

AndofcourseIhavetochangethedefaultconstructoronUseraswell,otherwiseitwillfailthevalidation:publicUser(){

this("username","Passw0rd",false);

}

Sincethedefaultpasswordhastochange,Ihadtoamendthecheckingcodesurroundingthisclassaswell.

CheckStringBuilderresizes@Test

publicvoidcapacitySizeIncreasesAutomaticallyWithAppend(){

StringBuilderbuilder=newStringBuilder(5);

assertThat(builder.capacity(),is(5));

builder.append("HelloWorld");

assertThat(builder.capacity()>5,is(true));

}

InsertintoaStringBuilder@Test

publicvoidwriteATestToInsert(){

StringBuilderbuilder=newStringBuilder();

//insertatstart

builder.insert(0,"a");

assertThat(builder.toString(),is("a"));

//inserttoend

builder.insert(builder.toString().length(),"b");

assertThat(builder.toString(),is("ab"));

//inserttomiddle

builder.insert(1,".");

assertThat(builder.toString(),is("a.b"));

}

ChapterSixteen-RandomData

Create@TestmethodsWhichConfirmRandomLimitsThebasic@TestmethodIcreatedlookslikethefollowing:@Test

publicvoidcanGenerateRandomInt(){

Randomgenerate=newRandom();

Page 275: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

for(intx=0;x<1000;x++){

intrandomInt=generate.nextInt();

System.out.println(randomInt);

assertThat(randomInt<Integer.MAX_VALUE,is(true));

assertThat(randomInt>=Integer.MIN_VALUE,is(true));

}

}

IuseSystem.out.printlntodisplaythevaluestotheconsole,justsoIcanseetherandomrange.AndIassertontheconditionsmentionedinthedocumentation.

Allothermethodstakethesameform,withadifferentrandomgenerationapproach.

Forthebooleanchecks,Icountthetrueandfalsevaluestomakesurethatbothvaluesaregenerated,andassertonthetotal:@Test

publicvoidcanGenerateRandomBoolean(){

Randomgenerate=newRandom();

intcountTrue=0;

intcountFalse=0;

for(intx=0;x<1000;x++){

booleanrandomBoolean=generate.nextBoolean();

if(randomBoolean)

countTrue++;

if(randomBoolean==false)

countFalse++;

System.out.println(randomBoolean);

}

System.out.println(

String.format("Generated%dastrue",countTrue));

System.out.println(

String.format("Generated%dasfalse",countFalse));

assertThat(countTrue>0,is(true));

assertThat(countFalse>0,is(true));

assertThat(countTrue+countFalse,is(1000));

}

Sinceallother@Testmethodstakethesameform,Ihavenotincludedthefullcodebelow,justthesubsetthathastherandomgenerationandtheassertions.

CheckingforLonglongrandomLong=generate.nextLong();

System.out.println(randomLong);

assertThat(randomLong<Long.MAX_VALUE,is(true));

assertThat(randomLong>=Long.MIN_VALUE,is(true));

NotethatthedocumentationfornextLongreportsthatthealgorithmwillnotreturnalllongvalues.

Page 276: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

CheckingforFloatfloatrandomFloat=generate.nextFloat();

System.out.println(randomFloat);

assertThat(randomFloat<1.0f,is(true));

assertThat(randomFloat>=0.0f,is(true));

Notethattheupperlimitcheckisexclusive(<)andthelowerlimitcheckisinclusive(>=).

CheckingforDoubledoublerandomDouble=generate.nextDouble();

System.out.println(randomDouble);

assertThat(randomDouble<1.0d,is(true));

assertThat(randomDouble>=0.0d,is(true));

Notethattheupperlimitcheckisexclusive(<)andthelowerlimitcheckisinclusive(>=).

CheckingforByte//randomlygenerateabytearraybetween0and99length

intarrayLength=generate.nextInt(100);

byte[]bytes=newbyte[arrayLength];

generate.nextBytes(bytes);//fillbyteswithrandomdata

Assert.assertEquals(arrayLength,bytes.length);

Stringviewbytes=newString(bytes);

System.out.println(bytes.length+"-"+viewbytes);

NotethatIrandomlygeneratethesizeofthebytearray.

CheckingforIntRangeintrandomIntRange=generate.nextInt(12);

System.out.println(randomIntRange);

assertThat(randomIntRange<=11,is(true));

assertThat(randomIntRange>=0,is(true));

NotethatIgeneratebelow12somyassertionisfrom0to11inclusive

Createan@Testmethodwhichgenerates1000numbersinclusivelybetween15and20@Test

publicvoidgenerateRandomIntGivenRangeNot0(){

Randomgenerate=newRandom();

intminValue=1;

intmaxValue=5;

intrandomIntRange=generate.nextInt(

maxValue-minValue+1)+minValue;

assertThat(randomIntRange<=maxValue,is(true));

assertThat(randomIntRange>=minValue,is(true));

}

Intheabovecode,Ilooparound1000timesinordertomakesurethatIdon’tjusthitoneluckynumberthatpassesmyassertions.

Istorethegeneratednumbersinaset:

thispreventsduplicatessoeachnumbergeneratedwillonlyappearoncethismeansthatthesizeofthesetisthenumberofdifferentintegersgenerated

Page 277: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Iassertonthesizeoftheset,becauseIknowthat6numbersaresupposedtobegenerated.

Iassertthateachofthenumbers{15,16,17,18,19,20}hasbeengenerated.

Writean@Testmethodthatshowsthedistributions@Test

publicvoidcanGenerateRandomGaussianDistributionDouble(){

Randomgenerate=newRandom();

intstandardDeviationCount1=0;

intstandardDeviationCount2=0;

intstandardDeviationCount3=0;

intstandardDeviationCount4=0;

for(intx=0;x<1000;x++){

doublerandomGaussian=generate.nextGaussian();

//System.out.println(randomValue);

if(randomGaussian>-1.0d&&randomGaussian<1.0d)

standardDeviationCount1++;

if(randomGaussian>-2.0d&&randomGaussian<2.0d)

standardDeviationCount2++;

if(randomGaussian>-3.0d&&randomGaussian<3.0d)

standardDeviationCount3++;

if(randomGaussian>-4.0d&&randomGaussian<4.0d)

standardDeviationCount4++;

}

floatsd1percentage=(standardDeviationCount1/1000f)*100f;

System.out.println("about70%onestandarddeviation="+

sd1percentage);

floatsd2percentage=(standardDeviationCount2/1000f)*100f;

System.out.println("about95%twostandarddeviation="+

sd2percentage);

floatsd3percentage=(standardDeviationCount3/1000f)*100f;

System.out.println("about99%threestandarddeviation="+

sd3percentage);

floatsd4percentage=(standardDeviationCount4/1000f)*100f;

System.out.println("about99.9%fourstandarddeviation="+

sd4percentage);

Assert.assertTrue(sd1percentage<sd2percentage);

Assert.assertTrue(sd2percentage<sd3percentage);

//Idonotassertthatsd3andsd4aredifferent

//becauseofthesmall%difference,theydooverlap

}

Writean@Testmethodwhichgenerates1000agesusingnextGaussian@Test

publicvoidcanGenerate1000AgesUsingDeviation(){

Page 278: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

Randomgenerate=newRandom();

Map<Integer,Integer>ages=

newHashMap<Integer,Integer>();

for(intx=0;x<1000;x++){

intage=(int)(generate.nextGaussian()*5)+35;

intageCount=0;

if(ages.containsKey(age)){

ageCount=ages.get(age);

}

ageCount++;

ages.put(age,ageCount);

}

SortedSet<Integer>agesSorted=newTreeSet(ages.keySet());

for(intage:agesSorted){

System.out.println(age+":"+ages.get(age));

}

}

Createan@TestmethodforRandomwithSeed@Test

publicvoidcanGenerateRandomNumbersWithSeed(){

for(intx=0;x<10;x++){

Randomgenerate=newRandom(1234567L);

assertThat(generate.nextInt(),is(1042961893));

assertThat(generate.nextLong(),is(-6749250865724111202L));

assertThat(generate.nextDouble(),is(0.44762832574617084D));

assertThat(generate.nextGaussian(),is(-0.11571220872310763D));

assertThat(generate.nextFloat(),is(0.33144182F));

assertThat(generate.nextBoolean(),is(false));

}

}

InordertoidentifythevaluesIneededtoasserton,IfirstcreatedaSystem.out.printlnforeachofthelines,thenusedthevalueoutputtotheconsoleasthevaluetoasserton.

GenerateaRandomString100charslong@Test

publicvoidgenerateARandomString(){

StringvalidValues="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

StringBuilderrString;

Randomrandom=newRandom();

rString=newStringBuilder();

for(intx=0;x<100;x++){

intrndIndex=random.nextInt(validValues.length());

charrChar=validValues.charAt(rndIndex);

Page 279: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

rString.append(rChar);

}

System.out.println(rString.toString());

Assert.assertTrue(rString.length()==100);

Assert.assertTrue(rString.toString().matches("[A-Z]+"));

}

YoucanseethatIassertonthelengthoftheString,andusearegularexpressiontocheckthatthecharactersinthestringarefromA-Zorspacei.e.“[A-Z]+”

IalsouseaStringBuildertohelpmeconstructthestringbyappendingeachoftherandomlygeneratedcharacters.

ChapterSeventeen-Dates&Times

Re-writethetiming@TestmethodusingnanoTime@Test

publicvoidnanoTime(){

longstartTime=System.nanoTime();

for(intx=0;x<10;x++){

System.out.println("CurrentTime"+System.nanoTime());

}

longendTime=System.nanoTime();

System.out.println("TotalTime"+(endTime-startTime));

}

UsecurrentTimeMillistocreateauniquenamewithnonumbersTherearelotsofwaysofimplementingthisexercise.1@Test

2publicvoidcreateAUniqueUserIDAllChars(){

3

4StringinitialUserID="user"+System.currentTimeMillis();

5System.out.println(initialUserID);

6

7StringuserID=initialUserID;

8

9for(intx=0;x<10;x++){

10StringcharReplacement=""+((char)('A'+x));

11StringintToReplace=String.valueOf(x);

12userID=userID.replace(intToReplace,charReplacement);

13}

14

15assertThat(userID.contains("0"),is(false));

16assertThat(userID.contains("1"),is(false));

17assertThat(userID.contains("2"),is(false));

18assertThat(userID.contains("3"),is(false));

19assertThat(userID.contains("4"),is(false));

20assertThat(userID.contains("5"),is(false));

21assertThat(userID.contains("6"),is(false));

22assertThat(userID.contains("7"),is(false));

23assertThat(userID.contains("8"),is(false));

24assertThat(userID.contains("9"),is(false));

Page 280: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

25

26assertThat(initialUserID.length(),is(userID.length()));

27

28System.out.println(userID);

29}

line10-Imadeitsimpleandeasybyusingthefactthat‘A’(achar)canbeaddedtoanintegertogetanewasciicharacter,thencasttheinttoacharandthenconcatenateitwithanemptyStringtocreateacharacterstringthatrepresentsanumber.line11-IconverttheinttoaStringline12-IthenreplacealltheintegerrepresentationsintheStringwiththiscalculatedcharactere.g.

'A'+0wouldequal'A',andIwouldreplaceall0intheStringwith'A''A'+1wouldequal'B',andIwouldreplaceall1intheStringwith'B'etc.

Therestofthecodecontainsassertionstocheckthatnodigitsareinthename.

WritethetoStringtoconsole@Test

publicvoidwriteCalendarToStringToConsole(){

Calendarcal=Calendar.getInstance();

System.out.println(cal.toString());

}

UsetheotherCalendarconstants@Test

publicvoiduseOtherCalendarConstants(){

Calendarcal=Calendar.getInstance();

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

assertThat(cal.get(Calendar.MONTH),is(Calendar.DECEMBER));

assertThat(cal.get(Calendar.YEAR),is(2013));

assertThat(cal.get(Calendar.DAY_OF_MONTH),is(15));

assertThat(cal.get(Calendar.HOUR_OF_DAY),is(23));

assertThat(cal.get(Calendar.MINUTE),is(39));

assertThat(cal.get(Calendar.HOUR),is(11));

assertThat(cal.get(Calendar.AM_PM),is(Calendar.PM));

}

Experimentwithotherconstants@Test

publicvoidexperimentWithCalendarConstants(){

Calendarcal=Calendar.getInstance();

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

assertThat(cal.get(Calendar.DAY_OF_WEEK),is(1));

assertThat(cal.get(Calendar.DAY_OF_WEEK),is(Calendar.SUNDAY));

assertThat(cal.get(Calendar.WEEK_OF_MONTH),is(2));

assertThat(cal.get(Calendar.WEEK_OF_YEAR),is(50));

assertThat(cal.get(Calendar.DAY_OF_YEAR),is(349));

}

Page 281: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

IncrementandDecrementotherFields@Test

publicvoidincrementAndDecrementOtherFields(){

Calendarcal=Calendar.getInstance();

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

cal.add(Calendar.YEAR,-2);

cal.add(Calendar.MONTH,-6);

cal.add(Calendar.DAY_OF_MONTH,-12);

assertThat(cal.get(Calendar.YEAR),is(2011));

assertThat(cal.get(Calendar.MONTH),is(Calendar.JUNE));

assertThat(cal.get(Calendar.DAY_OF_MONTH),is(3));

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

//bumpitforwardto3rdJune2014,

//thenpullitback

cal.add(Calendar.DAY_OF_MONTH,19);

cal.add(Calendar.MONTH,5);

cal.add(Calendar.YEAR,-3);

assertThat(cal.get(Calendar.YEAR),is(2011));

assertThat(cal.get(Calendar.MONTH),is(Calendar.JUNE));

assertThat(cal.get(Calendar.DAY_OF_MONTH),is(3));

}

ConfirmaddMovestheYear@Test

publicvoidrollCalendar(){

Calendarcal=Calendar.getInstance();

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

cal.roll(Calendar.DAY_OF_MONTH,17);

assertThat(cal.get(Calendar.YEAR),is(2013));

assertThat(cal.get(Calendar.MONTH),is(Calendar.DECEMBER));

assertThat(cal.get(Calendar.DAY_OF_MONTH),is(1));

cal.set(2013,Calendar.DECEMBER,15,23,39,54);

cal.add(Calendar.DAY_OF_MONTH,17);

assertThat(cal.get(Calendar.YEAR),is(2014));

assertThat(cal.get(Calendar.MONTH),is(Calendar.JANUARY));

assertThat(cal.get(Calendar.DAY_OF_MONTH),is(1));

}

ChapterEighteen-PropertiesandPropertyFiles

CreateandListaPropertiesobject@Test

publicvoidcanCreateAndListTheProperties(){

Propertiesproperties=newProperties();

properties.setProperty("name","bob");

properties.setProperty("gender","male");

Page 282: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

properties.setProperty("password","paSSw0rd");

assertThat(properties.stringPropertyNames().size(),is(3));

for(Stringkey:properties.stringPropertyNames()){

System.out.println("Key:"+key+""+

"Value:"+properties.getProperty(key));

}

properties.list(System.out);

Assert.assertTrue(properties.containsKey("gender"));

Assert.assertEquals("bob",properties.getProperty("name"));

Assert.assertEquals("Admin",

properties.getProperty("permission","Admin"));

}

StoreandLoadaSavedPropertiesFile@Test

publicvoidcanSaveAndLoadAPropertiesFile()throwsIOException{

StringtempDirectory=System.getProperty("java.io.tmpdir");

StringtempResourceFilePath=tempDirectory+

System.currentTimeMillis()+

System.nanoTime()+

".properties";

Propertiessaved=newProperties();

longnanoTime=System.nanoTime();

longmillis=System.currentTimeMillis();

saved.setProperty("nanoTime",String.valueOf(nanoTime));

saved.setProperty("millis",String.valueOf(millis));

FileOutputStreamoutputFile=

newFileOutputStream(tempResourceFilePath);

saved.store(outputFile,"TimeDataWhenFileWritten");

outputFile.close();

FileReaderpropertyFileReader=

newFileReader(tempResourceFilePath);

Propertiesloaded=newProperties();

try{

loaded.load(propertyFileReader);

}finally{

propertyFileReader.close();

}

assertThat(loaded.getProperty("nanoTime"),

is(String.valueOf(nanoTime)));

assertThat(loaded.getProperty("millis"),

is(String.valueOf(millis)));

newFile(tempResourceFilePath).delete();

Page 283: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

}

ChapterNineteen-Files

CreateaTempFileandVarytheParameters@Test

publicvoidcreateTempFileVaryTheParameters()throwsIOException{

//onwindowsthesefilesarein%TEMP%

Filetemp1=File.createTempFile("temp1",null);

Filetemp2=File.createTempFile("temp2OutFile",".out");

assertThat(temp1.exists(),is(true));

assertThat(temp2.exists(),is(true));

temp1.deleteOnExit();

temp2.deleteOnExit();

}

YoucanseethatIcheatedandusedtheexistsmethodtocheckforexistence,andIusedthedeleteOnExittoremovethecreatedtempfileswhenthecodeexecutioncompletes.

Butnotethat,hadsomethinggonewrongduringtheexecutionandanexceptionthrown,thefilesprobablywouldnothavebeendeleted.Ishouldreallyuseatry/finallyblockwhenworkingwithfiles.

Writeouttheroots@Test

publicvoidwriteOutTheFileListRoots(){

File[]roots=File.listRoots();

Assert.assertTrue(roots.length>0);

for(FileaFile:roots){

System.out.println(aFile.getAbsolutePath());

}

}

CreateaTemporaryFileWithCustomCode@Test

publicvoidcreateATempFileWithCustomCode()throwsIOException{

Stringdirectory=System.getProperty("java.io.tmpdir");

StringfileName="prefix"+System.currentTimeMillis()+".tmp";

FileaTempFile=newFile(directory,fileName);

assertThat(aTempFile.exists(),is(false));

aTempFile.createNewFile();

assertThat(aTempFile.exists(),is(true));

aTempFile.delete();

assertThat(aTempFile.exists(),is(false));

}

Writean@TestmethodToCheckCanonicalConversion

Page 284: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Test

publicvoidwriteATestToCheckCanonicalConversion()throwsIOException{

Fileabsolute1=newFile("C:/1/2/3/4/../../..");

Fileabsolute2=newFile("C:/1/2/../../1");

Filecanonical=newFile("C:/1");

assertThat(canonical.getAbsolutePath(),

is(canonical.getCanonicalPath()));

assertThat(canonical.getAbsolutePath(),

is(absolute1.getCanonicalPath()));

assertThat(canonical.getAbsolutePath(),

is(absolute2.getCanonicalPath()));

assertThat(absolute1.getAbsolutePath().contains(".."),is(true));

assertThat(absolute2.getAbsolutePath().contains(".."),is(true));

}

CheckthattheTempDirectoryisaDirectory@Test

publicvoidcheckThatTheTempDirectoryIsADirectory(){

FiletempDir=newFile(System.getProperty("java.io.tmpdir"));

assertThat(tempDir.isDirectory(),is(true));

assertThat(tempDir.isFile(),is(false));

}

WritetoaPrintWriterthenAppend@Test

publicvoidexerciseWriteToAPrintWriterThenAppend()throwsIOException{

FileoutputFile=File.createTempFile("printWriterPrint",null);

System.out.println("Checkfile"+outputFile.getAbsolutePath());

FileWriterwriter=newFileWriter(outputFile);

BufferedWriterbuffer=newBufferedWriter(writer);

PrintWriterprint=newPrintWriter(buffer);

print.println("AppendPrinttoBufferedWriter");

print.close();

//appendtothefile

writer=newFileWriter(outputFile,true);

buffer=newBufferedWriter(writer);

print=newPrintWriter(buffer);

print.println("===============================");

print.close();

StringlineEnd=System.lineSeparator();

longfileLen=62L+lineEnd.length()+lineEnd.length();

assertThat(outputFile.length(),is(fileLen));

}

CreateaFileandCalculatethelength

Page 285: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Test

publicvoidspaceMethods()throwsIOException{

Filetemp=newFile(System.getProperty("java.io.tmpdir"));

longfreeSpace=temp.getFreeSpace();

longtotalSpace=temp.getTotalSpace();

longusableSpace=temp.getUsableSpace();

FileoutputFile=writeTheTestDataFile(5);

assertThat(outputFile.length(),is(expectedFileSize(5)));

System.out.println("Length"+outputFile.length());

System.out.println("Free"+freeSpace);

System.out.println("Total"+totalSpace);

System.out.println("Usable"+usableSpace);

}

privatelongexpectedFileSize(intlines){

StringlineEnd=System.lineSeparator();

return(("linex".length()+lineEnd.length())*lines);

}

privateFilewriteTheTestDataFile(intlines)throwsIOException{

FileoutputFile=File.createTempFile(

"forReading"+lines+"_",null);

PrintWriterprint=newPrintWriter(

newBufferedWriter(

newFileWriter(outputFile)));

for(intline=0;line<lines;line++){

print.println("line"+lines);

}

print.close();

returnoutputFile;

}

UselistFilestoshowtheTempDirectorycontents@Test

publicvoidlistTempDirectory(){

FiletempDir=newFile(System.getProperty("java.io.tmpdir"));

File[]fileList=tempDir.listFiles();

for(FilefileInList:fileList){

StringoutputString="";

if(fileInList.isDirectory()){

outputString=outputString+"DIR:";

}else{

outputString=outputString+"FIL:";

}

outputString=outputString+fileInList.getName();

System.out.println(outputString);

}

}

OutputAttributesofFilesInTempDirectory

Page 286: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Test

publicvoidlistTempDirectoryAttribs(){

FiletempDir=newFile(System.getProperty("java.io.tmpdir"));

File[]fileList=tempDir.listFiles();

for(FilefileInList:fileList){

StringoutputString="";

if(fileInList.isDirectory()){

outputString=outputString+"DIR:";

}else{

outputString=outputString+"FIL:";

}

if(fileInList.canRead()){

outputString=outputString+"r";

}else{

outputString=outputString+"-";

}

if(fileInList.canWrite()){

outputString=outputString+"w";

}else{

outputString=outputString+"-";

}

if(fileInList.canExecute()){

outputString=outputString+"x";

}else{

outputString=outputString+"-";

}

outputString=outputString+"-"+fileInList.getName();

SimpleDateFormatsdf=newSimpleDateFormat("yMdHH:mm:ss.SSS");

StringlastModified=

sdf.format(newDate(fileInList.lastModified()));

outputString=outputString+"=>"+lastModified;

System.out.println(outputString);

}

}

copyAndmoveaFile@Test

publicvoidcopyFile()throwsIOException{

FilecopyThis=writeTheTestDataFile();

FiletoThis=newFile(copyThis.getCanonicalPath()+".copy");

assertThat(toThis.exists(),is(false));

Files.copy(copyThis.toPath(),toThis.toPath());

assertThat(toThis.exists(),is(true));

assertThat(copyThis.length(),is(toThis.length()));

}

@Test

publicvoidmoveFile()throwsIOException{

Page 287: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

FilemoveThis=writeTheTestDataFile();

FiletoThis=newFile(moveThis.getCanonicalPath()+".moved");

assertThat(moveThis.exists(),is(true));

assertThat(toThis.exists(),is(false));

Files.move(moveThis.toPath(),toThis.toPath(),

REPLACE_EXISTING,ATOMIC_MOVE);

assertThat(toThis.exists(),is(true));

assertThat(moveThis.exists(),is(false));

}

privateFilewriteTheTestDataFile()throwsIOException{

FileoutputFile=File.createTempFile("forReading",null);

PrintWriterprint=newPrintWriter(

newBufferedWriter(

newFileWriter(outputFile)));

for(intlineNumber=1;lineNumber<6;lineNumber++){

print.println("line"+lineNumber);

}

print.close();

returnoutputFile;

}

ChapterTwenty-MathandBigDecimal

ConvinceYourselfofBigDecimalorint@Test

publicvoidconvinceYourselfOfBigDecimalUsage(){

try{

doubletotal=5-0.3-0.47-1.73;

System.out.println("2.5!="+total);

assertThat(total,is(2.5));

fail("Expectedtheasserttofail");

}catch(java.lang.AssertionErrore){}

intinPennies=500-30-47-173;

assertThat(inPennies,is(250));

BigDecimalbdTotal=newBigDecimal("5").

subtract(newBigDecimal("0.30")).

subtract(newBigDecimal(("0.47"))).

subtract(newBigDecimal("1.73"));

assertThat(bdTotal,is(newBigDecimal("2.50")));

}

BasicArithmeticwithBigDecimal@Test

publicvoidbasicArithmeticWithBigDecimal(){

BigDecimalbd=BigDecimal.ZERO;

bd=bd.add(BigDecimal.TEN);

bd=bd.multiply(BigDecimal.valueOf(2L));

bd=bd.subtract((BigDecimal.TEN));

Page 288: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

bd=bd.divide(BigDecimal.valueOf(2L));

assertThat(bd,is(BigDecimal.valueOf(5L)));

}

Onmysystem,theresultofthedoublecalculationcameto"2.5000000000000004"whichwouldnotequal2.5.SoalwaysremembertouseBigDecimalwhencomparingwiththeresultsofexternalsystemsorforfinancialandcurrencytransactions.

CompareTENandONE@Test

publicvoidbigDecimalCompareTenAndOne(){

assertTrue(BigDecimal.TEN.compareTo(BigDecimal.ONE)>0);

assertTrue(BigDecimal.ONE.compareTo(BigDecimal.TEN)<0);

assertTrue(BigDecimal.TEN.compareTo(BigDecimal.TEN)==0);

assertTrue(BigDecimal.TEN.compareTo(BigDecimal.ONE)!=0);

assertTrue(BigDecimal.TEN.compareTo(BigDecimal.ONE)>=0);

assertTrue(BigDecimal.TEN.compareTo(BigDecimal.TEN)>=0);

assertTrue(BigDecimal.TEN.compareTo(BigDecimal.TEN)<=0);

assertTrue(BigDecimal.ONE.compareTo(BigDecimal.TEN)<=0);

}

ChapterTwentyOne-CollectionsRevisited

Removeif(val==0)userSortedList.add(bob);

userSortedList.add(dupebob);

userSortedList.add(rich);

userSortedList.add(dupebob2);

assertEquals(2,userSortedList.size());

userSortedList.add(mrBeer);

assertEquals("MrBeercouldnotbeadded",2,userSortedList.size());

Withouttheval==0linesintheComparatorIcannotaddthemrBeerobjecttotheSortedSet

//if(val==0){

//val=user1.getUsername().compareTo(user2.getUsername());

//}

DisallowDuplicateUserNamesThecodeIcreated:@Test

publicvoidsortedSetWithComparatorForUser(){

Userbob=newUser("Bob","pA55Word");//11

Userdupebob=newUser("Bob","hello");

Userrich=newUser("Richie","RichieRichieRich");//22

Userdupebob2=newUser("Bob","BobsMightyBigBobPassword");

UsermrBeer=newUser("Stafford","sys");//11

SortedSet<User>userSortedList=

newTreeSet<User>(newUserComparatorDisallowDupes());

userSortedList.add(bob);

userSortedList.add(dupebob);

Page 289: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

userSortedList.add(rich);

userSortedList.add(dupebob2);

userSortedList.add(mrBeer);

assertEquals(3,userSortedList.size());

User[]users=newUser[userSortedList.size()];

userSortedList.toArray(users);

assertEquals(bob.getUsername(),users[0].getUsername());

assertEquals(mrBeer.getUsername(),users[1].getUsername());

assertEquals(rich.getUsername(),users[2].getUsername());

}

AndtheassociatedUserComparatorDisallowDupesclass:publicclassUserComparatorDisallowDupesimplementsComparator{

publicintcompare(ObjectoUser1,ObjectoUser2){

Useruser1=(User)oUser1;

Useruser2=(User)oUser2;

if(user1.getUsername().compareTo(user2.getUsername())==0){

return0;

}

intuser1Comparator=user1.getPassword().length()+

user1.getUsername().length();

intuser2Comparator=user2.getPassword().length()+

user2.getUsername().length();

intval=user1Comparator-user2Comparator;

if(val==0){

val=user1.getUsername().compareTo(user2.getUsername());

}

returnval;

}

}

UserclassimplementsComparableThebasicchangesImadetotheUserclassweretotheclassdefinition:publicclassUserimplementsComparable{

ThenIalsoaddedthecompareTomethod:@Override

publicintcompareTo(ObjectoUser2){

Useruser2=(User)oUser2;

if(this.getUsername().compareTo(user2.getUsername())==0){

return0;

}

intuser1Comparator=this.getPassword().length()+

this.getUsername().length();

Page 290: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

intuser2Comparator=user2.getPassword().length()+

user2.getUsername().length();

intval=user1Comparator-user2Comparator;

if(val==0){

val=this.getUsername().compareTo(user2.getUsername());

}

returnval;

}

ThenIcreateda@Testtousedemonstrateit:@Test

publicvoidsortedSetWithComparableUser(){

Userbob=newUser("Bob","pA55Word");//11

Userdupebob=newUser("Bob","hello");

Userrich=newUser("Richie","RichieRichieRich");//22

Userdupebob2=newUser("Bob","BobsMightyBigBobPassword");

UsermrBeer=newUser("Stafford","sys");//11

SortedSet<User>userSortedList=newTreeSet<User>();

userSortedList.add(bob);

userSortedList.add(dupebob);

userSortedList.add(rich);

userSortedList.add(dupebob2);

userSortedList.add(mrBeer);

assertEquals(3,userSortedList.size());

User[]users=newUser[userSortedList.size()];

userSortedList.toArray(users);

assertEquals(bob.getUsername(),users[0].getUsername());

assertEquals(mrBeer.getUsername(),users[1].getUsername());

assertEquals(rich.getUsername(),users[2].getUsername());

}

SeethesortinactionWhenIaddedtheline:System.out.println("Compare"+user1.getUsername()+

"with"+user2.getUsername()+"="+val);

Theoutputfromtheexecutionshowed:1CompareRichiewithBob=11

2CompareStaffordwithBob=17

3CompareStaffordwithRichie=-11

ThismeansthatIonlyreachedthe‘dupe’checkforthreeaddcalls.Alltheothercallstheresultofthecomparisonwasbasedontheduplicateusernamecheck.

AccessValuesinMapinKeyorder

Page 291: Java For Testers - index-of.co.ukindex-of.co.uk/Programming/Java For Testers Learn Java Fundament… · lot of time in the IDE, writing and running small checks and refactoring to

@Test

publicvoidexerciseCanGetAllKeysAsSortedSet(){

Map<String,String>map=newHashMap<>();

map.put("key4","value4");

map.put("key2","value2");

map.put("key1","value1");

map.put("key3","value3");

SortedSet<String>keys=newTreeSet<String>(map.keySet());

intvalSuffix=1;

for(Stringkey:keys){

assertEquals("value"+valSuffix,

map.get(key));

valSuffix+=1;

}

}

IntheabovecodeIaddthevaluesoutoforderintoaMap.NotaSortedMap,soIknowIcan’trelyontheorder.

IconstructaTreeSetfromtheSetreturnedbymap.keySet(),soInowhaveaSortedSetofkeys.

Todemonstratethatthesorthasworked,IpredictthevalueIexpectbyincrementingvalSuffixfrom1to4,theniterateoverthekeystocheckthatthevaluefromthemapisthevalueIpredicted.