Foreword xviiPreface xixAcknowledgments xxvAbout the Authors xxviiChapter 1 Why, Who, and What 1Why 1 Agility Progressively Invades Domains Every Day 2 Agility Cannot Work Without TDD 2 TDD in the Database World Is a Challenge 3Who 3 TDD and OOP 4 Applications and Databases 4What 4 Databases Are Objects 5 TDD Works on Classes, Not Objects 5 We Need Classes of Databases 6Summary 7Chapter 2 Establishing a Class of Databases 9The Class's Role in TDD 9 A Reliable Instantiation Process 10 Tests Check Objects 10Classes in Object-Oriented Programming Languages 11 Making Classes Is Easy: Just Make New Objects 11 One Path: Destroy If Necessary 11Classes of Databases 12 Two Paths: Create or Change 12 The Hard Part: Unifying the Two Paths 13 Real Database Growth 13 How About Making Every Database Build Like Production Databases? 14 All DBs Would Follow the Exact Same Path 15Incremental Build 15 Document Each Database Change 15 Identify Current Version 16 Apply Changes in Order as Needed 16Implementation 16 Requirements 16 Pseudocode Database Instantiation Mechanism 17 Pseudocode Input 17Summary 18Chapter 3 A Little TDD 19The Test-First Technique 19 Write the Test 20 Stub Out Enough to See a Failure 22 See the Test Pass 22 Repeat 23Tests as Specifications 24 "Tests Aren't Tests, They Are Specifications" 24 "Tests Aren't Specifications, They Are Tests" 25 Tests Are Executable Specifications 26 Incremental Design 27Building Good Specifications 28 Specify Behavior, Not Structure 28 Drive Design In from Without, Not the Other Way Around 29 Defining the Design Inside Out 30 Defining the Design Outside In 32Summary 34Chapter 4 Safely Changing Design 37What Is Safe? 38 Breaking a Contract Is a Little Bad 38 Losing Data Will Probably Get You Fired 39 Not Changing Design Is Also Dangerous 40Solution: Transition Testing 44 Test-Driving Instantiation 44 Transition Testing Creation 44 Transition Testing Addition 47 Transition Testing Metamorphosis 51 Why Not Use the Public Interface? 56Transition Safeguards 56 Read/Read Transition Tests 56 Run by the Class of Databases on Every Upgrade 60 Backup and Rollback on Fail 60 Making Transition Tests Leverage Transition Safeguards 60Summary 61Chapter 5 Enforcing Interface 63Interface Strength 64 Stronger Coupling Languages 64 Weaker Coupling Languages 65 The Common Thread 66 Coupling to Database Classes 66 The Problem Is Duplication 66Client-Object-Like Enforcement 67 Creating Demand for a DatabaseDesign Class 67Specifying the DatabaseDesign Class 68 Getting Rid of Duplication with Multiple Client Platforms 70 What Happens When Coupling Goes Bad? 71 Eliminating Duplication Between Database Build and Client Code 71 Decoupling Implementation from Design 72Sticking Point: Change 73 Designs Change Over Time 74 Document All Versions of Design 75 Couple to the Correct Version of the Design 77Sticking Point: Coupling 78 Various Clients Couple to Various Versions 78 Having to Change Everything All the Time Is Duplication, Too 79 Introducing the Lens Concept 83 Virtual Lenses 85 The "Current" Lens 89 The "New" Lens 89Summary 93Chapter 6 Defining Behaviors 95A New Group of Problems 96 No Encapsulation 96 Hide Everything 97 Business Logic in the Database 97Knowledge, Information, and Behavior 98 Information 99 Knowledge 102 Behavior 102Outside-In Development 106 Defining the Test 106 Growing Interface 108 Growing Behavior and Structures 109Justification by Specification 111 Work Against Present Requirements, Not Future 111 Build in Increments 112 Limit Access to What Is Specified 112Summary 113Chapter 7 Building for Maintainability 115Never Worry About the Future 116 Look for Opportunities in the Now 116 Design to Information 117 Translate Info and Knowledge with Behavior 121Guard Knowledge with Fervor and Zeal 124 Not Changing Is the Most Dangerous Choice 124 Keep Your Design Natural 126Deal with the Future When It Happens 127 Define New Design 128 Introduce Minimal Changes 129 Get Tests Passing 131 Stop, Think, Refactor 133Summary 136Chapter 8 Error and Remediation 137Kinds of Errors 137 Axis: Is the Error Good or Bad? 138 Axis: Is the Error Released or Not? 140Dealing with Good Errors 142 Just Fix It 142 Document Behavior Now 143 Trace Feature Back to Its Genesis 145Dealing with Bad Errors 146 Unreleased Errors 147 Released Errors 150 Catastrophic Errors 156Summary 157Chapter 9 Design 159Structures Versus Design 160 Structures: Execution Details 160 Tests and Class Information 162What Is Design? 163 Buckets of Concepts 163 Mandatory Part of True TDD 166Composition and Aggregation 167 Composition: One Thing with Multiple Parts 168 Aggregation: Connecting Distinct Things 172Reuse 175 Avoid Developing the Same Thing Twice 175 Reuse by Composition or Aggregation 177Abstraction 178 Identifying Opportunities for Abstraction 178 Encapsulating Behaviors 179 Finding Ways to Allow Variation in Dependencies 185 Dealing with the Time Problem 186Summary 190Chapter 10 Mocking 191Testing Individual Behaviors 191 Why Encapsulate 192 Tests Test Everything Not Under Their Control 193 Controlling Irrelevant Behaviors from Tests 194 Mocking Controls Behaviors 194Mocking in Object-Oriented Programming 195 Setup 195 Decoupling 199 Isolation 202 Integration 202Mocking in Database Design 203 Example Problem 204 Example Solution 205 Composition 208 Aggregation 210 Designing for Testability 210Summary 210Chapter 11 Refactoring 213What Refactoring Is 214 Changing Design Without Changing Behavior 214 In the Context of Passing Tests 215Lower and Higher Risk Design Changes 222 Lower Risk: Changing Class-Level Design 222 Medium Risk: Rearranging Behavior Logic 223 Higher Risk: Altering Knowledge Containers 225 This Is Not an Invitation to Skip Testing 226Summary 226Chapter 12 Legacy Databases 227Promoting to a Class 228 Deducing Initial Version 228 Pinning the Transition Behavior with Tests 231Controlling Coupling 231 Identifying and Locking Down to Existing Uses 232 Encapsulating on Demand 234Controlling Change 235 Test-Driving New Behaviors 235 Pinning Construction on Demand 237 Pinning Behavior on Demand 238 Implementing New Behavior 239Finding Seams and Components 240 Finding Seams 240 Encapsulating Components 243Summary 247Chapter 13 The Facade Pattern 249Encapsulation with a Facade 249 Explanation of Facade Pattern 250 New Test-Driven Facade Database 254 Compositional Alternative 261 To Encapsulate or Not 261Strangling the Old Interface 262 Transferring Changing Behaviors to Facade 262 Removing Access and Features When No Longer Needed 263Test-Driving Behaviors in the Facade Database 264 Exposing Legacy Behaviors 265 Another Way to Do It 265 New Behaviors 266Summary 266Chapter 14 Variations 269Having a Class Is Important-Implementation Is Not 270Scenario: Skipping Steps 270 Problem 271 Solution 272 The Right Amount of Work 273Scenario: Deviations 274 Problem 274 Solution 275 Solution Applied 277Common Solution 281Summary 281Chapter 15 Other Applications 283XML 284 Encapsulation 284 XSD Schemas 284 XSLT Transitions 286 Transition Test XSLT Changes 287File Systems and Other Object Directories 288 Transition Test File System Manipulations 289 Shell Script Transitions 291Data Objects 292 Class Definitions Are Schemas 292 Transition Test the Ugrader Class 294 Code Transitions 296Summary and Send Off 300Index 301
Max Guernsey is currently a Managing Member at Hexagon Software LLC. He has 15 years of experience as a professional software developer. For nearly half that time, he has been blogging, writing, and delivering lectures on the topic of agile and test-driven database development. For much of Max's professional career, he has been a consultant, advising a variety of software companies in many different industries using multiple programming and database technologies. In most of these engagements, he spent months or even years helping teams implement cutting-edge techniques such as test-driven development, object-oriented design, acceptance-test-driven development, and agile planning.Max has always been a "hands-on" consultant, working with teams for long periods of time to help them build both software and skills. This series of diverse, yet deep, engagements helped him gain a unique understanding of the database-related testing and design problems that impede most agile teams. Since 2005, he has been thinking, writing, blogging, lecturing, and creating developer-facing software dedicated to resolving these issues.Max posts regularly on his Twitter account (@MaxGuernseyIII) and his blog ( maxg3prog.blogspot.com).