Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com List of Patterns Assertion Message (370): We include a descriptive string argument in each call to an Assertion Method. Assertion Method (362): We call a utility method to evaluate whether an expected outcome has been achieved. Automated Teardown (503): We keep track of all resources that are created in a test and automatically destroy/free them during teardown. Back Door Manipulation (327): We set up the test fi xture or verify the outcome by going through a back door (such as direct database access). Behavior Verifi cation (468): We capture the indirect outputs of the system under test (SUT) as they occur and compare them to the expected behavior. Chained Tests (454): We let the other tests in a test suite set up the test fi xture. Confi gurable Test Double (558): We confi gure a reusable Test Double with the values to be returned or verifi ed during the fi xture setup phase of a test. Creation Method (415): We set up the test fi xture by calling methods that hide the mechanics of building ready-to-use objects behind Intent-Revealing Names. Custom Assertion (474): We create a purpose-built Assertion Method that compares only those attributes of the object that defi ne test-specifi c equality. Data-Driven Test (288): We store all the information needed for each test in a data fi le and write an interpreter that reads the fi le and executes the tests. Database Sandbox (650): We provide a separate test database for each developer or tester. Delegated Setup (411): Each test creates its own Fresh Fixture by calling Creation Methods from within the Test Methods. Delta Assertion (485): We specify assertions based on differences between the pre- and post-exercise state of the SUT. Dependency Injection (678): The client provides the depended-on object to the SUT. Dependency Lookup (686): The SUT asks another object to return the depended-on object before it uses it. Derived Value (718): We use expressions to calculate values that can be derived from other values. Dummy Object (728): We pass an object that has no implementation as an argument of a method called on the SUT. Fake Object (551): We replace a component that the SUT depends on with a much lighter-weight implementation. Four-Phase Test (358): We structure each test with four distinct parts executed in sequence. Fresh Fixture (311): Each test constructs its own brand-new test fi xture for its own private use. Garbage-Collected Teardown (500): We let the garbage collection mechanism provided by the programming language clean up after our test. Generated Value (723): We generate a suitable value each time the test is run. Guard Assertion (490): We replace an if statement in a test with an assertion that fails the test if not satisfi ed. Hard-Coded Test Double (568): We build the Test Double by hard-coding the return values and/or expected calls. Humble Object (695): We extract the logic into a separate, easy-to-test component that is decoupled from its environment. Implicit Setup (424): We build the test fi xture common to several tests in the setUp method. Implicit Teardown (516): The Test Automation Framework calls our clean up logic in the tearDown method after every Test Method. In-line Setup (408): Each Test Method creates its own Fresh Fixture by calling the appropriate constructor methods to build exactly the test fi xture it requires. In-line Teardown (509): We include teardown logic at the end of the Test Method immediately after the result verifi cation. Layer Test (337): We can write separate tests for each layer of the layered architecture. Lazy Setup (435): We use Lazy Initialization of the fi xture to create it in the fi rst test that needs it. Literal Value (714): We use literal constants for object attributes and assertions. Minimal Fixture (302): We use the smallest and simplest fi xture possible for each test. Mock Object (544): We replace an object the SUT depends on with a test-specifi c object that verifi es it is being used correctly by the SUT. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Named Test Suite (592): We defi ne a test suite, suitably named, that contains a set of tests that we wish to be able to run as a group. Parameterized Test (607): We pass the information needed to do fi xture setup and result verifi cation to a utility method that implements the entire test life cycle. Prebuilt Fixture (429): We build the Shared Fixture separately from running the tests. Recorded Test (278): We automate tests by recording interactions with the application and playing them back using a test tool. Scripted Test (285): We automate the tests by writing test programs by hand. Setup Decorator (447): We wrap the test suite with a Decorator that sets up the shared test fi xture before running the tests and tears it down after all the tests are done. Shared Fixture (317): We reuse the same instance of the test fi xture across many tests. Standard Fixture (305): We reuse the same design of the test fi xture across many tests. State Verifi cation (462): We inspect the state of the SUT after it has been exercised and compare it to the expected state. Stored Procedure Test (654): We write Fully Automated Tests for each stored procedure. Suite Fixture Setup (441): We build/destroy the shared fi xture in special methods called by the Test Automation Framework before/after the fi rst/last Test Method is called. Table Truncation Teardown (661): We truncate the tables modifi ed during the test to tear down the fi xture. Test Automation Framework (298): We use a framework that provides all the mechanisms needed to run the test logic so the test writer needs to provide only the test-specifi c logic. Test Discovery (393): The Test Automation Framework discovers all the tests that belong to the test suite automatically. Test Double (522): We replace a component on which the SUT depends with a “test-specifi c equivalent.” Test Enumeration (399): The test automater manually writes the code that enumerates all tests that belong to the test suite. Test Helper (643): We defi ne a helper class to hold any Test Utility Methods we want to reuse in several tests. Test Hook (709): We modify the SUT to behave differently during the test. Test Method (348): We encode each test as a single Test Method on some class. Test Runner (377): We defi ne an application that instantiates a Test Suite Object and executes all the Testcase Objects it contains. Test Selection (403): The Test Automation Framework selects the Test Methods to be run at runtime based on attributes of the tests. Test Spy (538): We use a Test Double to capture the indirect output calls made to another component by the SUT for later verifi cation by the test. Test Stub (529): We replace a real object with a test-specifi c object that feeds the desired indirect inputs into the SUT. Test Suite Object (387): We defi ne a collection class that implements the standard test interface and use it to run a set of related Testcase Objects. Test Utility Method (599): We encapsulate the test logic we want to reuse behind a suitably named utility method. Test-Specifi c Subclass (579): We add methods that expose the state or behavior needed by the test to a subclass of the SUT. Testcase Class (373): We group a set of related Test Methods on a single Testcase Class. Testcase Class per Class (617): We put all the Test Methods for one SUT class onto a single Testcase Class. Testcase Class per Feature (624): We group the Test Methods onto Testcase Classes based on which testable feature of the SUT they exercise. Testcase Class per Fixture (631): We organize Test Methods into Testcase Classes based on commonality of the test fi xture. Testcase Object (382): We create a Command object for each test and call the run method when we wish to execute it. Testcase Superclass (638): We inherit reusable test-specifi c logic from an abstract Testcase Superclass. Transaction Rollback Teardown (668): We roll back the uncommitted test transaction as part of the teardown. Unfi nished Test Assertion (494): We ensure that incomplete tests fail by executing an assertion that is guaranteed to fail. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com xUnit Test Patterns Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com xUnit Test Patterns Refactoring Test Code Gerard Meszaros Upper Saddle River, NJ • Boston • Indianapolis • San Francisco New York • Toronto • Montreal • London • Munich • Paris • Madrid Capetown • Sydney • Tokyo • Singapore • Mexico City Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trade- marks. Where those designations appear in this book, and the publisher was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals. The author and publisher have taken care in the preparation of this book, but make no expressed or implied war- ranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or con- sequential damages in connection with or arising out of the use of the information or programs contained herein. The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales, which may include electronic versions and/or custom covers and content particular to your business, training goals, marketing focus, and branding interests. For more information, please contact: U.S. Corporate and Government Sales (800) 382-3419 corpsales@pearsontechgroup.com For sales outside the United States please contact: International Sales international@pearsoned.com Library of Congress Cataloging-in-Publication Data Meszaros, Gerard. XUnit test patterns : refactoring test code / Gerard Meszaros. p. cm. Includes bibliographical references and index. ISBN-13: 978-0-13-149505-0 (hardback : alk. paper) ISBN-10: 0-13-149505-4 1. Software patterns. 2. Computer software—Testing. I. Title. QA76.76.P37M49 2007 005.1—dc22 2006103488 Copyright © 2007 Pearson Education, Inc. All rights reserved. Printed in the United States of America. This publication is protected by copyright, and per- mission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding permissions, write to: Pearson Education, Inc. Rights and Contracts Department 75 Arlington Street, Suite 300 Boston, MA 02116 Fax: (617) 848-7047 ISBN 13: 978-0-13-149505-0 ISBN 10: 0-13-149505-4 Text printed in the United States on recycled paper at Courier in Westford, Massachusetts. First printing, May 2007 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com This book is dedicated to the memory of Denis Clelland, who recruited me away from Nortel in 1995 to work at ClearStream Consulting and thereby gave me the opportunity to have the experiences that led to this book. Sadly, Denis passed away on April 27, 2006, while I was fi nalizing the second draft. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com This page intentionally left blank Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Contents Visual Summary of the Pattern Language . . . . . . . . . . . . . . . . . . . xvii Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxvii Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix Refactoring a Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xlv PART I. The Narratives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Chapter 1. A Brief Tour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 About This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 The Simplest Test Automation Strategy That Could Possibly Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Development Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Customer Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Unit Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Design for Testability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Test Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Chapter 2. Test Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 About This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 An Introduction to Test Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 What’s a Test Smell? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Kinds of Test Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 What to Do about Smells? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 A Catalog of Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 The Project Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 The Behavior Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 The Code Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 vii Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... Test Execution Other Considerations What’s Next? 12 5 12 5 12 6 12 6 12 8 13 0 13 3 13 3 14 0 14 1 14 3 14 8 14 9 14 9 14 9 15 0 15 0 15 1 Chapter 12 Organizing Our Tests 15 3 About This Chapter 15 3 Basic xUnit Mechanisms 15 3... Methods Where to Put Reusable Verification Logic? What’s Next? 11 4 11 5 11 6 11 7 11 8 11 9 12 0 12 1 12 1 12 1 12 2 12 2 12 3 Chapter 11 Using Test Doubles 12 5 About This Chapter What Are Indirect Inputs and Outputs? Why Do We Care about Indirect... Test Dependencies What’s Next? 15 4 15 5 15 5 15 6 15 6 15 8 15 8 16 0 16 0 16 1 16 2 16 3 16 3 16 4 16 4 16 4 16 5 16 5 Chapter 13 Testing with Databases 16 7 About This Chapter Testing with Databases Why Test with Databases? ... 10 7 10 7 10 8 10 9 11 0 11 1 11 1 11 2 11 3 11 3 xi Contents Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Reducing Test Code Duplication Expected Objects Custom Assertions Outcome-Describing Verification Method Parameterized and Data-Driven Tests ... Pattern Language The Patterns Test Automation Strategy Patterns xUnit Basics Patterns Test Automation Strategy Recorded Test Scripted Test Data-Driven Test Test Discovery Test Execution Test Automation Framework Test Runner Test Enumeration Test Automation Framework Test Selection Test Case Object SUT Interaction Strategy Test Suite Object Test Fixture Strategy Minimal Fixture Layer Test Test Definition... 16 8 16 9 17 1 17 2 17 2 17 3 17 3 17 4 Chapter 14 A Roadmap to Effective Test Automation 17 5 About This Chapter Test Automation Difficulty Roadmap to Highly Maintainable Automated Tests Exercise the Happy Path Code Verify Direct Outputs of the Happy Path 17 5 17 5 17 6 17 7 17 8 xiii... Indirect Testing Mystery Guest And more! Test Code Duplication Test Logic In Production Robust Test Easy to Write/Maintain Obscure Test Hard-to -Test Code Self-Checking Tests as Safety Net Conditional Test Logic Simple Test Improve Quality Expressive Tests Reduce Risk Separation of Concerns Bug Repellent Do No Harm Behavior Smells Erratic Test Assertion Roulette Unrepeatable Test Interacting Tests Test. .. Optimize Test Execution and Maintenance What’s Next? 17 8 17 9 18 0 18 1 PART II The Test Smells 18 3 Chapter 15 Code Smells 18 5 Obscure Test Conditional Test Logic Hard-to -Test Code ... Derived Value Dummy Object Database Patterns Fake Database Table Truncation Teardown Lazy Teardown Test- Specific Subclass Subclassed Test Double Test Double Test Spy Mock Object Test Double Construction Confiugrable Test Double Hard -Coded Test Double Test Helper Parameterized Test Literal Value Automated Teardown Test Double Patterns Dummy Object Utility Method Location Test Utility Method Table Truncation... Verification Method Test Organization Patterns GarbageCollected Teardown Testcase Class Structure Testcase Class per Class Named Test Suite Testcase Class per Fixture Testcase Class per Feature Test Code Reuse Testcase Class Transaction Rollback Teardown Finder Method Testcase Superclass Creation Method Custom Assertion Verification Method Fake Object Test Stub Object Mother Value Patterns Generated . Gerard. XUnit test patterns : refactoring test code / Gerard Meszaros. p. cm. Includes bibliographical references and index. ISBN -13 : 978-0 -13 -14 9505-0 (hardback : alk. paper) ISBN -10 : 0 -13 -14 9505-4 . Language Code Smells Obscure Test Eager Test General Fixture Indirect Testing Mystery Guest And more! Conditional Test Logic Hard-to -Test Code Test Code Duplication Test Logic In Production Erratic Test Unrepeatable. more! Conditional Test Logic Hard-to -Test Code Test Code Duplication Test Logic In Production Erratic Test Unrepeatable Test Interacting Tests Test Run War Resource Optimism And more! Fragile Test Fragile