Test-driven development with Java create higher-quality software by writing tests first with solid and hexagonal architecture

Drive development with automated tests and gain the confidence you need to write high-quality software Key Features Get up and running with common design patterns and TDD best practices Learn to apply the rhythms of TDD - arrange, act, assert and red, green, refactor Understand the challenges of imp...

Descripción completa

Detalles Bibliográficos
Otros Autores: Mellor, Alan, author (author)
Formato: Libro electrónico
Idioma:Inglés
Publicado: Birmingham, England : Packt Publishing, Limited [2023]
Edición:1st ed
Materias:
Ver en Biblioteca Universitat Ramon Llull:https://discovery.url.edu/permalink/34CSUC_URL/1im36ta/alma991009714839106719
Tabla de Contenidos:
  • Cover
  • Title Page
  • Copyright and Credit
  • Dedicated
  • Contributors
  • Table of Contents
  • Preface
  • Part 1: How We Got to TDD
  • Chapter 1: Building the Case for TDD
  • Writing code badly
  • Understanding why bad code is written
  • Recognizing bad code
  • Bad variable names
  • Bad function, method, and class names
  • Error-prone constructs
  • Coupling and cohesion
  • Decreasing team performance
  • Diminishing business outcomes
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 2: Using TDD to Create Good Code
  • Designing good quality code
  • Say what you mean, mean what you say
  • Take care of the details in private
  • Avoid accidental complexity
  • Revealing design flaws
  • Analyzing the benefits of writing tests before production code
  • Preventing logic flaws
  • Protecting against future defects
  • Documenting our code
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 3: Dispelling Common Myths about TDD
  • Writing tests slows me down
  • Understanding the benefits of slowing down
  • Overcoming objections to tests slowing us down
  • Tests cannot prevent every bug
  • Understanding why people say tests cannot catch every bug
  • Overcoming objections to not catching every bug
  • How do you know the tests are right?
  • Understanding the concerns behind writing broken tests
  • Providing reassurance that we test our tests
  • TDD guarantees good code
  • Understanding problem-inflated expectations
  • Managing your expectations of TDD
  • Our code is too complex to test
  • Understanding the causes of untestable code
  • Reframing the relationship between good design and simple tests
  • Managing legacy code without tests
  • I don't know what to test until I write the code
  • Understanding the difficulty of starting with testing
  • Overcoming the need to write production code first
  • Summary.
  • Questions and answers
  • Further reading
  • Part 2: TDD Techniques
  • Chapter 4: Building an Application Using TDD
  • Technical requirements
  • Preparing our development environment
  • Installing the IntelliJ IDE
  • Setting up the Java project and libraries
  • Introducing the Wordz application
  • Describing the rules of Wordz
  • Exploring agile methods
  • Reading user stories - the building block of planning
  • Combining agile development with TDD
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 5: Writing Our First Test
  • Technical requirements
  • Starting TDD: Arrange-Act-Assert
  • Defining the test structure
  • Working backward from outcomes
  • Increasing workflow efficiency
  • Defining a good test
  • Applying the FIRST principles
  • Using one assert per test
  • Deciding on the scope of a unit test
  • Catching common errors
  • Asserting exceptions
  • Only testing public methods
  • Preserving encapsulation
  • Learning from our tests
  • A messy Arrange step
  • A messy Act step
  • A messy Assert step
  • Limitations of unit tests
  • Code coverage - an often-meaningless metric
  • Writing the wrong tests
  • Beginning Wordz
  • Summary
  • Questions and answers
  • Chapter 6: Following the Rhythms of TDD
  • Technical requirements
  • Following the RGR cycle
  • Starting on red
  • Keep it simple - moving to green
  • Refactoring to clean code
  • Writing our next tests for Wordz
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 7: Driving Design - TDD and SOLID
  • Technical requirements
  • Test guide - we drive the design
  • SRP - simple building blocks
  • Too many responsibilities make code harder to work with
  • Ability to reuse code
  • Simplified future maintenance
  • Counter-example - shapes code that violates SRP
  • Applying SRP to simplify future maintenance
  • Organizing tests to have a single responsibility.
  • DIP - hiding irrelevant details
  • Applying DI to the shapes code
  • LSP - swappable objects
  • Reviewing LSP usage in the shapes code
  • OCP - extensible design
  • Adding a new type of shape
  • ISP - effective interfaces
  • Reviewing ISP usage in the shapes code
  • Summary
  • Questions and answers
  • Chapter 8: Test Doubles - Stubs and Mocks
  • Technical requirements
  • The problems collaborators present for testing
  • The challenges of testing unrepeatable behavior
  • The challenges of testing error handling
  • Understanding why these collaborations are challenging
  • The purpose of test doubles
  • Making the production version of the code
  • Using stubs for pre-canned results
  • When to use stub objects
  • Using mocks to verify interactions
  • Understanding when test doubles are appropriate
  • Avoiding the overuse of mock objects
  • Don't mock code you don't own
  • Don't mock value objects
  • You can't mock without dependency injection
  • Don't test the mock
  • When to use mock objects
  • Working with Mockito - a popular mocking library
  • Getting started with Mockito
  • Writing a stub with Mockito
  • Writing a mock with Mockito
  • Blurring the distinction between stubs and mocks
  • Argument matchers - customizing behavior of test doubles
  • Driving error handling code with tests
  • Testing an error condition in Wordz
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 9: Hexagonal Architecture -Decoupling External Systems
  • Technical requirements
  • Why external systems are difficult
  • Environmental problems bring trouble
  • Accidentally triggering real transactions from tests
  • What data should we expect?
  • Operating system calls and system time
  • Challenges with third-party services
  • Dependency inversion to the rescue
  • Generalizing this approach to the hexagonal architecture.
  • Overview of the hexagonal architecture's components
  • The golden rule - the domain never connects directly to adapters
  • Why the hexagon shape?
  • Abstracting out the external system
  • Deciding what our domain model needs
  • Writing the domain code
  • Deciding what should be in our domain model
  • Using libraries and frameworks in the domain model
  • Deciding on a programming approach
  • Substituting test doubles for external systems
  • Replacing the adapters with test doubles
  • Unit testing bigger units
  • Unit testing entire user stories
  • Wordz - abstracting the database
  • Designing the repository interface
  • Designing the database and random numbers adapters
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 10: FIRST Tests and the Test Pyramid
  • Technical requirements
  • The test pyramid
  • Unit tests - FIRST tests
  • Integration tests
  • What should an integration test cover?
  • Testing database adapters
  • Testing web services
  • Consumer-driven contract testing
  • End-to-end and user acceptance tests
  • Acceptance testing tools
  • CI/CD pipelines and test environments
  • What is a CI/CD pipeline?
  • Why do we need continuous integration?
  • Why do we need continuous delivery?
  • Continuous delivery or continuous deployment?
  • Practical CI/CD pipelines
  • Test environments
  • Testing in production
  • Wordz - integration test for our database
  • Fetching a word from the database
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 11: Exploring TDD with Quality Assurance
  • TDD - its place in the bigger quality picture
  • Understanding the limits of TDD
  • No more need for manual testing?
  • Manual exploratory - discovering the unexpected
  • Code review and ensemble programming
  • User interface and user experience testing
  • Testing the user interface
  • Evaluating the user experience.
  • Security testing and operations monitoring
  • Incorporating manual elements into CI/CD workflows
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 12: Test First, Test Later, Test Never
  • Adding tests first
  • Test-first is a design tool
  • Tests form executable specifications
  • Test-first provides meaningful code coverage metrics
  • Beware of making a code coverage metric a target
  • Beware of writing all tests upfront
  • Writing tests first helps with continuous delivery
  • We can always test it later, right?
  • Test-later is easier for a beginner to TDD
  • Test-later makes it harder to test every code path
  • Test-later makes it harder to influence the software design
  • Test-later may never happen
  • Tests? They're for people who can't write code!
  • What happens if we do not test during development?
  • Testing from the inside out
  • Testing from the outside in
  • Defining test boundaries with hexagonal architecture
  • Inside-out works well with the domain model
  • Outside-in works well with adapters
  • User stories can be tested across the domain model
  • Summary
  • Questions and answers
  • Further reading
  • Part 3: Real-World TDD
  • Chapter 13: Driving the Domain Layer
  • Technical requirements
  • Starting a new game
  • Test-driving starting a new game
  • Tracking the progress of the game
  • Triangulating word selection
  • Playing the game
  • Designing the scoring interface
  • Triangulating game progress tracking
  • Ending the game
  • Responding to a correct guess
  • Triangulating the game over due to too many incorrect guesses
  • Triangulating response to guess after game over
  • Reviewing our design
  • Summary
  • Questions and answers
  • Further reading
  • Chapter 14: Driving the Database Layer
  • Technical requirements
  • Installing the Postgres database
  • Creating a database integration test.
  • Creating a database test with DBRider.