Test-Driven Development with Java - Alan Mellor - E-Book

Test-Driven Development with Java E-Book

Alan Mellor

0,0
33,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.
Mehr erfahren.
Beschreibung

Test-driven development enables developers to craft well-designed code and prevent defects. It’s a simple yet powerful tool that helps you focus on your code design, while automatically checking that your code works correctly. Mastering TDD will enable you to effectively utilize design patterns and become a proficient software architect.
The book begins by explaining the basics of good code and bad code, bursting common myths, and why Test-driven development is crucial. You’ll then gradually move toward building a sample application using TDD, where you’ll apply the two key rhythms -- red, green, refactor and arrange, act, assert. Next, you’ll learn how to bring external systems such as databases under control by using dependency inversion and test doubles. As you advance, you’ll delve into advanced design techniques such as SOLID patterns, refactoring, and hexagonal architecture. You’ll also balance your use of fast, repeatable unit tests against integration tests using the test pyramid as a guide. The concluding chapters will show you how to implement TDD in real-world use cases and scenarios and develop a modern REST microservice backed by a Postgres database in Java 17.
By the end of this book, you’ll be thinking differently about how you design code for simplicity and how correctness can be baked in as you go.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 480

Veröffentlichungsjahr: 2023

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Test-Driven Development with Java

Create higher-quality software by writing tests first with SOLID and hexagonal architecture

Alan Mellor

BIRMINGHAM—MUMBAI

Test-Driven Development with Java

Copyright © 2022 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author(s), nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Group Product Manager: Gebin George

Publishing Product Manager: Arvind Sharma

Senior Editor: Nisha Cleetus

Technical Editor: Jubit Pincy

Copy Editor: Safis Editing

Project Coordinator: Manisha Singh

Proofreader: Safis Editing

Indexer: Subalakshmi Govindhan

Production Designer: Shankar Kalbhor

Business Development Executive: Kriti Sharma

Marketing Coordinator: Sonakshi Bubbar

First published: January 2023

Production reference: 1231222

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham

B3 2PB, UK.

ISBN 978-1-80323-623-0

www.packt.com

In memory of my mum, Eva Mellor (1928 – 2022). You saw me start this book but not finish it. If I’m perfectly honest, you wouldn’t have enjoyed it as much as your Georgette Heyer novels.

– Alan Mellor

Contributors

About the author

Alan Mellor is an academy lead at BJSS, training the next generation of consulting software engineers, and the author of Java OOP Done Right: Create object oriented code you can be proud of with modern Java. Alan started with a Sinclair ZX81 computer with 1K of RAM and is very happy to have better computers now. Alan’s work includes industrial control in C, web applications for e-commerce, gaming and banking in Java and Go, and document warehousing in C++. His most visible code is part of Nokia Bounce and the RAF Red Arrows flight simulator if you go back far enough.

I want to thank my wife Stephanie without whose support this book would not have been possible. I’m grateful to everyone who has taught me about software engineering, whether in person or via their books. All my love to Jake and Katy. You two are awesome.

About the reviewers

Jeff Langr has been building software professionally for over 4 decades. He’s recognized as the author of five books on software development, including Modern C++ Programming with Test–Driven Development: Code Better, Sleep Better, Agile in a Flash (with Tim Ottinger), and Agile in a Flash: Speed-learning Agile Software Development. Jeff is also a co-author of the best-selling book Clean Code. He’s written over a hundred published articles and several hundred blog posts on his site (https://langrsoft.com).

Nikolai Avteniev started his professional career at JPMorgan Chase, participated in the Extreme Programming Pilot, and learned how to apply test-driven development and continuous integration. After graduating from NYU with a degree in computer science, he took the experience of building and running an Agile development team to Real Time Risk Systems as one of the founding engineers. Nikolai later joined New York City AdTech start-up Intent Media and then moved on to building software teams and systems at LinkedIn (https://engineering.linkedin.com/blog/2017/08/getting-to-know-nikolai-avteniev).

Additionally, Nikolai teaches software engineering at the City University of New York. Currently, he works at Stripe, helping grow the GDP of the internet safely.

Table of Contents

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

Share Your Thoughts

Download a free PDF copy of this book

Part 1: How We Got to TDD

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

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

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

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

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

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

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

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

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

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

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

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

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

14

Driving the Database Layer

Technical requirements

Installing the Postgres database

Creating a database integration test

Creating a database test with DBRider

Driving out the production code

Implementing the WordRepository adapter

Accessing the database

Implementing GameRepository

Summary

Questions and answers

Further reading

15

Driving the Web Layer

Technical requirements

Starting a new game

Adding required libraries to the project

Writing the failing test

Creating our HTTP server

Adding routes to the HTTP server

Connecting to the domain layer

Refactoring the start game code

Handling errors when starting a game

Fixing the unexpectedly failing tests

Playing the game

Integrating the application

Using the application

Summary

Questions and answers

Further reading

Index

Other Books You May Enjoy

Part 1: How We Got to TDD

In Part 1, we look at how we got to TDD in the software industry. What problems are we trying to fix with TDD? What opportunities does it create?

In the following chapters, we will learn about the benefits that TDD brings to businesses and developers. We’ll review the basics of good code to provide something to aim for when we first start writing our tests. Knowing that teams are sometimes hesitant to start using TDD, we will examine six common objections and how to overcome them.

This part has the following chapters:

Chapter 1, Building the Case for TDDChapter 2, Using TDD to Create Good CodeChapter 3, Dispelling Common Myths about TDD

2

Using TDD to Create Good Code

We’ve seen that bad code is bad news: bad for business, bad for users, and bad for developers. Test-driven development (TDD) is a core software engineering practice that helps us keep bad code out of our systems.

The goal of this chapter is to learn the specifics of how TDD helps us to create well-engineered, correct code, and how it helps us to keep it that way. By the end, we will understand the basic principles behind good code and how TDD helps us create it. It is important for us to understand why TDD works in order to motivate us and so that we have a response to give to colleagues about why we recommend that they use it as well.

In this chapter, we’re going to cover the following main topics:

Designing good quality codeRevealing design flawsPreventing logic flawsProtecting against future defectsDocumenting our code

Designing good quality code

Good quality code