As iOS apps become increasingly complex and business-critical, iOS developers must ensure consistently superior code quality. This means adopting best practices for creating and testing iOS apps. Test-Driven Development (TDD) is one of the most powerful of these best practices. Test-Driven iOS Development is the first book 100% focused on helping you successfully implement TDD and unit testing in an iOS environment.
Long-time iOS/Mac developer Graham Lee helps you rapidly integrate TDD into your existing processes using Apple's Xcode 4 and the OCUnit unit testing framework. He guides you through constructing an entire Objective-C iOS app in a test-driven manner, from initial specification to functional product. Lee also introduces powerful patterns for applying TDD in iOS development, and previews powerful automated testing capabilities that will soon arrive on the iOS platform. Coverage includes
Understanding the purpose, benefits, and costs of unit testing in iOS environments
Mastering the principles of TDD, and applying them in areas from app design to refactoring
Writing usable, readable, and repeatable iOS unit tests
Using OCUnit to set up your Xcode project for TDD
Using domain analysis to identify the classes and interactions your app needs, and designing it accordingly
Considering third-party tools for iOS unit testing
Building networking code in a test-driven manner
Automating testing of view controller code that interacts with users
Designing to interfaces, not implementations
Testing concurrent code that typically runs in the background
Applying TDD to existing apps
Preparing for Behavior Driven Development (BDD)
The only iOS-specific guide to TDD and unit testing, Test-Driven iOS Development covers both essential
concepts and practical implementation.
Graham Lee's job title is "Smartphone Security Boffin," a role that requires a good deal of confidence in the code he produces. His first exposure to OCUnit and unit testing came around six years ago, as test lead on a GNUstep-based server application. Before iOS became the main focus of his work, Graham worked on applications for Mac OS X, NeXTSTEP, and any number of UNIX variants. This book is the second Graham has written as part of his scheme to learn loads about computing by trying to find ways to explain it to other people. Other parts of this dastardly plan include speaking frequently at conferences across the world, attending developer meetings near to his home town of Oxford, and volunteering at the Swindon Museum of Computing.
Dedication v Preface xii Acknowledgments xiv About the Author xiv 1 About Software Testing and Unit Testing 1 What Is Software Testing For? 1 Who Should Test Software? 2 When Should Software Be Tested? 6 Examples of Testing Practices 7 Where Does Unit Testing Fit In? 7 What Does This Mean for iOS Developers? 11 2 Techniques for Test-Driven Development 13 Test First 13 Red, Green, Refactor 15 Designing a Test-Driven App 18 More on Refactoring 19 Ya Ain't Gonna Need It 19 Testing Before, During, and After Coding 21 3 How to Write a Unit Test 23 The Requirement 23 Running Code with Known Input 24 Seeing Expected Results 26 Verifying the Results 26 Making the Tests More Readable 28 Organizing Multiple Tests 29 Refactoring 32 Summary 34 4 Tools for Testing 35 OCUnit with Xcode 35 Alternatives to OCUnit 46 Google Toolkit for Mac 46 GHUnit 47 CATCH 48 OCMock 50 Continuous Integration 52 Hudson 53 CruiseControl 57 Summary 58 5 Test-Driven Development of an iOS App 59 Product Goal 59 Use Cases 60 Plan of Attack 63 Getting Started 64 6 The Data Model 67 Topics 67 Questions 73 People 75 Connecting Questions to Other Classes 76 Answers 81 7 Application Logic 87 Plan of Attack 87 Creating a Question 88 Building Questions from JSON 102 8 Networking Code 113 NSURLConnection Class Design 113 StackOverflowCommunicator Implementation 114 Conclusion 125 9 View Controllers 127 Class Organization 127 The View Controller Class 128 TopicTableDataSource and TopicTableDelegate 133 Telling the View Controller to Create a New View Controller 149 The Question List Data Source 158 Where Next 170 10 Putting It All Together 171 Completing the Application's Workflow 171 Displaying User Avatars 185 Finishing Off and Tidying Up 189 Ship It! 199 11 Designing for Test-Driven Development 201 Design to Interfaces, Not Implementations 201 Tell, Don't Ask 203 Small, Focused Classes and Methods 204 Encapsulation 205 Use Is Better Than Reuse 205 Testing Concurrent Code 206 Don't Be Cleverer Than Necessary 207 Prefer a Wide, Shallow Inheritance Hierarchy 208 Conclusion 208 12 Applying Test-Driven Development to an Existing Project 209 The Most Important Test You'll Write Is the First 209 Refactoring to Support Testing 210 Testing to Support Refactoring 212 Do I Really Need to Write All These Tests? 213 13 Beyond Today's Test-Driven Development 215 Expressing Ranges of Input and Output 215 Behavior-Driven Development 216 Automatic Test Case Generation 217 Automatically Creating Code to Pass Tests 219 Conclusion 220 Index 221