O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Test-Driven Java Development - Second Edition

Book Description

This book will teach the concepts of test driven development in Java so you can build clean, maintainable and robust code

About This Book

  • Explore the most popular TDD tools and frameworks and become more proficient in building applications
  • Create applications with better code design, fewer bugs, and higher test coverage, enabling you to get them to market quickly
  • Implement test-driven programming methods into your development workflows

Who This Book Is For

If you're an experienced Java developer and want to implement more effective methods of programming systems and applications, then this book is for you.

What You Will Learn

  • Explore the tools and frameworks required for effective TDD development
  • Perform the Red-Green-Refactor process efficiently, the pillar around which all other TDD procedures are based
  • Master effective unit testing in isolation from the rest of your code
  • Design simple and easily maintainable code by implementing different techniques
  • Use mocking frameworks and techniques to easily write and quickly execute tests
  • Develop an application to implement behavior-driven development in conjunction with unit testing
  • Enable and disable features using feature toggles

In Detail

Test-driven development (TDD) is a development approach that relies on a test-first procedure that emphasizes writing a test before writing the necessary code, and then refactoring the code to optimize it.The value of performing TDD with Java, one of the longest established programming languages, is to improve the productivity of programmers and the maintainability and performance of code, and develop a deeper understanding of the language and how to employ it effectively.

Starting with the basics of TDD and understanding why its adoption is beneficial, this book will take you from the first steps of TDD with Java until you are confident enough to embrace the practice in your day-to-day routine.You'll be guided through setting up tools, frameworks, and the environment you need, and we will dive right into hands-on exercises with the goal of mastering one practice, tool, or framework at a time. You'll learn about the Red-Green-Refactor procedure, how to write unit tests, and how to use them as executable documentation.With this book, you'll also discover how to design simple and easily maintainable code, work with mocks, utilize behavior-driven development, refactor old legacy code, and release a half-finished feature to production with feature toggles.You will finish this book with a deep understanding of the test-driven development methodology and the confidence to apply it to application programming with Java.

Style and approach

An easy-to-follow, hands-on guide to building applications through effective coding practices. This book covers practical examples by introducing different problems, each one designed as a learning exercise to help you understand each aspect of TDD.

Downloading the example code for this book You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

Table of Contents

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