Title Page Copyright and Credits Test-Driven Java Development Second Edition Packt Upsell Why subscribe? PacktPub.com Contributors About the authors About the reviewer Packt is searching for authors like you Preface Who this book is for What this book covers To get the most out of this book Download the example code files Download the color images Conventions used Get in touch Reviews Why Should I Care for Test-Driven Development? Why TDD? Understanding TDD Red-Green-Refactor Speed is the key It's not about testing Testing Black-box testing White-box testing The difference between quality checking and quality assurance Better tests Mocking Executable documentation No debugging Summary Tools, Frameworks, and Environments Git Virtual machines Vagrant Docker Build tools The integrated development environment The IDEA demo project Unit-testing frameworks JUnit TestNG Hamcrest and AssertJ Hamcrest AssertJ Code coverage tools JaCoCo Mocking frameworks Mockito EasyMock Extra power for mocks User interface testing Web-testing frameworks Selenium Selenide Behavior-driven development JBehave Cucumber Summary Red-Green-Refactor – From Failure Through Success until Perfection Setting up the environment with Gradle and JUnit Setting up Gradle/Java project in IntelliJ IDEA The Red-Green-Refactor process Writing a test Running all the tests and confirming that the last one is failing Writing the implementation code Running all the tests Refactoring Repeating Tic-Tac-Toe game requirements Developing Tic-Tac-Toe Requirement 1 – placing pieces Test – board boundaries I Implementation Test – board boundaries II Implementation Test – occupied spot Implementation Refactoring Requirement 2 – adding two-player support Test – X plays first Implementation Test – O plays right after X Implementation Test – X plays right after O Requirement 3 – adding winning conditions Test – by default there's no winner Implementation Test – winning condition I Implementation Refactoring Test – winning condition II Implementation Test – winning condition III Implementation Test – winning condition IV Implementation Refactoring Requirement 4 – tie conditions Test – handling a tie situation Implementation Refactoring Code coverage More exercises Summary Unit Testing – Focusing on What You Do and Not on What Has Been Done Unit testing What is unit testing? Why unit testing? Code refactoring Why not use unit tests exclusively? Unit testing with TDD TestNG The @Test annotation The @BeforeSuite, @BeforeTest, @BeforeGroups, @AfterGroups, @AfterTest, and @AfterSuite annotations The @BeforeClass and @AfterClass annotations The @BeforeMethod and @AfterMethod annotations The @Test(enable = false) annotation argument The @Test(expectedExceptions = SomeClass.class) annotation argument TestNG versus JUnit summary Remote-controlled ship requirements Developing the remote-controlled ship Project setup Helper classes Requirement – starting point and orientation Specification – keeping position and direction in memory Implementation Refactoring Requirement – forward and backward moves Specification – moving forward Implementation Specification – moving backward Implementation Requirement – rotating the ship Specification – turning left Implementation Specification – turning right Implementation Requirement – commands Specification – single commands Implementation Specification – combined commands Implementation Requirement – representing spheric maps Specification – planet information Implementation Refactoring Specification – dealing with map boundaries Implementation Requirement – detecting obstacles Summary Design – If It's Not Testable, It's Not Designed Well Why should we care about design? Design principles You Ain't Gonna Need It Don't Repeat Yourself Keep it simple, stupid Occam's razor SOLID principles Connect 4 Requirements Test-last implementation of Connect 4 Requirement 1 – the game's board Requirement 2 – introducing discs Requirement 3 – player shifts Requirement 4 – the game's output Requirement 5 – win conditions (I) Requirement 6 – win condition (II) Requirement 7 – win condition (III) Requirement 8 – win condition (IV) The TDD or test-first implementation Hamcrest Requirement 1 – the game's board Requirement 2 – introducing discs Requirement 3 – player shifts Requirement 4 – the game's output Requirement 5 – win condition (I) Requirement 6 – win condition (II) Requirement 7 – win condition (III) Requirement 8 – win condition (IV) Final considerations Summary Mocking – Removing External Dependencies Mocking Why mocks? Terminology Mock objects Mockito Tic-Tac-Toe v2 requirements Developing Tic-Tac-Toe v2 Requirement 1 – store moves Specification – DB name Implementation Specification – a name for the Mongo collection Implementation Refactoring Specification – adding items to the Mongo collection Implementation Specification – adding operation feedback Implementation Refactoring Specification – error handling Implementation Specification – clear state between games Implementation Specification – drop operation feedback Implementation Specification – error handling Implementation Requirement 2 – store every turn Specification – creating new collection Implementation Specification refactoring Specification – storing current move Implementation Specification – error handling Implementation Specification – alternate players Implementation Exercises Integration tests Tests separation The integration test Summary TDD and Functional Programming – A Perfect Match Setting up the environment Optional – dealing with uncertainty Example of Optional Functions revisited Kata – Reverse Polish Notation Requirements Requirement – handling invalid input Requirement – single operations Requirement – complex operations Streams filter map flatMap reduce Summary BDD – Working Together with the Whole Team Different specifications Documentation Documentation for coders Documentation for non-coders Behavior-driven development Narrative Scenarios The book store BDD story JBehave JBehave runner Pending steps Selenium and Selenide JBehave steps Final validation Summary Refactoring Legacy Code – Making It Young Again Legacy code Legacy code example Other ways to recognize legacy code A lack of dependency injection The legacy code change algorithm Applying the legacy code change algorithm Identifying change points Finding test points Breaking dependencies Writing tests The kata exercise Legacy kata Description Technical comments Adding a new feature Black-box or spike testing Preliminary investigation How to find candidates for refactoring Introducing the new feature Applying the legacy code algorithm Writing end-to-end test cases Automating the test cases Injecting the BookRepository dependency Extract and override call Parameterizing a constructor Adding a new feature Removing the primitive obsession with status as int Summary Feature Toggles – Deploying Partially Done Features to Production Continuous integration, delivery, and deployment Feature Toggles A Feature Toggle example Implementing the Fibonacci service Working with the template engine Summary Putting It All Together TDD in a nutshell Best practices Naming conventions Processes Development practices Tools Summary Leverage TDD by Implementing Continuous Delivery Case study – Awesome Gambling Corp Exploring the codebase Release procedure Deployments to production Conclusions Possible improvements Increasing test coverage Implementing continuous integration Towards continuous delivery Jenkins installation Automating builds First execution What is next? This is just the beginning This does not have to be the end Summary Other Books You May Enjoy Leave a review - let other readers know what you think