iOS Unit Testing by Example
XCTest Tips and Techniques Using Swift
by: Jon Reid
Published | 2020-06-22 |
---|---|
Internal code | jrlegios |
Print status | In Print |
Pages | 358 |
User level | Intermediate |
Keywords | iOS, iOS apps, iOS programming, Unit testing, Swift, XCTest, testing view controllers |
Related titles | Test iOS Apps with UI Automation, 978-1-93778-552-9 |
ISBN | 9781680506815 |
Other ISBN |
Channel epub: 9781680507973 Channel PDF: 9781680507980 Kindle: 9781680507959 Safari: 9781680507966 Kindle: 9781680507959 |
BISACs | COM051330 COMPUTERS / Software Development & Engineering / Quality Assurance & TestingCOM051010 COMPUTERS / Programming Languages / GeneralCOM051010 COMPUTERS / Programming Languages / General |
Highlight
Fearlessly change the design of your iOS code with solid unit tests. Use Xcode’s built-in test framework XCTest and Swift to get rapid feedback on all your code — including legacy code. Learn the tricks and techniques of testing all iOS code, especially view controllers (UIViewControllers), which are critical to iOS apps. Learn to isolate and replace dependencies in legacy code written without tests. Practice safe refactoring that makes these tests possible, and watch all your changes get verified quickly and automatically. Make even the boldest code changes with complete confidence.
Description
Manual code and UI testing get slower the deeper your navigation hierarchy goes. It can take several taps just to reach a particular screen, never mind the actual workflow tests. Automatic unit testing offers such rapid feedback that it can change the rules of development. Bring testing to iOS development, even for legacy code. Use XCTest to write unit tests in Swift for all your code.
iOS developers typically reserve unit tests for their model classes alone. But that approach skips most of the code common to iOS apps, especially with UIViewControllers. Learn how to unit test these view controllers to expand your unit testing possibilities. Since good unit tests form the bedrock for safe refactoring, you’re empowered to make bold changes. Learn how to avoid the most common mistakes Swift programmers make with the XCTest framework. Use code coverage to find holes in your test suites. Learn how to identify hard dependencies.
Reshape the design of your code quickly, with less risk and less fear.
Contents and Extracts
- Foundations
- Assert Yourself <b>excerpt</b>
- What Are Unit Tests Anyway?
- Create a Place to Play with Tests
- Write Your First Assertion
- Add a Descriptive Message
- Avoid Conditionals in Tests
- Describe Objects upon Failure
- Test for Equality
- Test Equality with Optionals
- Fudge Equality with Doubles and Floats
- Avoid Redundant Messages
- Choose the Right Assertion
- Key Takeaways
- Activities
- What’s Next?
- Manage Your Test Life Cycles
- Make a New Place to Play
- Start from Test Zero
- Hook Up Tests to Production Code
- Examine Console Output
- Observe Object Life Cycles to Learn the Phases of a Test
- The Wrong Way to Reduce Duplicate Test Code
- Learn How XCTest Manages Test Cases
- Use setUp() and tearDown()
- Key Takeaways
- Activities
- What’s Next?
- Measure Code Coverage and Add Tests
- Make a New Place to Play
- Enable Code Coverage
- Examine Code Coverage Results
- Drill into a Partially Covered Line
- Add Tests for Existing Code
- Cover a Conditional
- Cover a Loop
- Cover Statements in a Sequence
- Avoid Percentage Targets, Embrace Forward Movement
- Key Takeaways
- Activities
- What’s Next?
- Take Control of Application Launch
- Make a New Place to Play
- Observe the Default Behavior
- Learn About the Test Launch Sequence
- Bypass the Normal App Delegate
- Put Up with the Initial View Controller
- Tweak Your Testing App Delegate
- Key Takeaways
- Activities
- What’s Next?
- Load View Controllers
- Make a New Place to Play
- Set Up a Storyboard-Based View Controller for Experiments
- Load a Storyboard-Based View Controller
- Set Up a XIB-Based View Controller for Experiments
- Load a XIB-Based View Controller
- Set Up a Code-Based View Controller for Experiments
- Load a Code-Based View Controller
- Key Takeaways
- Activities
- What’s Next?
- Manage Difficult Dependencies <b>excerpt</b>
- Be Okay with Problem-Free Dependencies
- Identify Difficult Dependencies
- Create Boundaries to Isolate Dependencies
- Make a New Place to Play
- Add Backdoors to Singletons You Own
- Subclass and Override: A Legacy Code Technique
- Inject Instances Through Initializers or Properties
- Inject Closures to Make New Instances
- Key Takeaways
- Activities
- What’s Next?
- Assert Yourself <b>excerpt</b>
- iOS Testing Tips and Techniques
- Testing Outlet Connections
- Make a New Place to Play
- Test Outlet Connections
- Check the Effectiveness of Failure Messages
- Key Takeaways
- Activities
- What’s Next?
- Testing Button Taps (Using Actions) <b>excerpt</b>
- Make a Place to Play with a Button
- Test Button Taps
- Make a Test Helper for Button Taps
- Key Takeaways
- Activities
- What’s Next?
- Testing Alerts
- Make a New Place to Play
- Add the Helper Framework to the Project
- Test Alerts Using the Alert Verifier
- Move the SUT into the Test Fixture
- Add Tests for Alert Buttons
- Key Takeaways
- Activities
- What’s Next?
- Testing Navigation Between Screens
- Make a New Place to Play
- Set Up Code-Based Navigation
- Set Up Segue-Based Navigation
- Test Code-Based Push Navigation
- Test Code-Based Modal Presentation
- Test Segue-Based Push Navigation
- Test Segue-Based Modal Navigation
- Key Takeaways
- Activities
- What’s Next?
- Testing UserDefaults (with Fakes)
- Make a New Place to Play
- Isolate UserDefaults with Dependency Injection
- Extract a Protocol to Support Test Doubles
- Make a Fake Object
- Test UserDefaults
- Key Takeaways
- Activities
- What’s Next?
- Testing Network Requests (with Mocks)
- Make a New Place to Play
- Isolate URLSession with Dependency Injection
- Extract a URLSession Protocol for Test Doubles
- Make a Test Spy
- Design the Test Case
- Promote the Test Spy into a Mock Object
- Improve Mock Object Reporting
- Key Takeaways
- Activities
- What’s Next?
- Testing Network Responses (and Closures)
- Make a New Place to Play
- Parse the Response
- Start with a Fresh Test Spy
- Design the Test Case
- Test Asynchronous Code
- Keep Asynchronous Code in Its Closure
- Test an Error Scenario
- Key Takeaways
- Activities
- What’s Next?
- Testing Text Fields (and Delegate Methods)
- Make a Place to Play
- Test the Outlets
- Test Attributes and Wrangle UIKit Descriptions
- Test Delegate Methods
- Test Input Focus
- Key Takeaways
- Activities
- What’s Next?
- Testing Table Views
- Make a Place to Play
- Test Table Views
- Key Takeaways
- Activities
- What’s Next?
- Testing View Appearance (with Snapshots)
- Make a Place to Play
- Add FBSnapshotTestCase to a Test Target
- Set the Location for Reference Images
- Write a Snapshot Test
- See the Difference in a Snapshot Failure
- Manage Your Snapshot Tests
- Key Takeaways
- Activities
- What’s Next?
- Testing Outlet Connections
- Using Your New Power
- Unleash the Power of Refactoring
- What Is Refactoring?
- Lay Out the Views for Our Practice App
- Add the Code to Our Practice App
- Replace the Difficult Dependency with a Mock Object
- Write the First Tests of the Change Password View Controller
- Test the Cancel Button
- Test the Submit Button
- Test the Text Field Delegate Method
- Refactor to Break Up a Long Function
- Extract a Method with Parameters
- Clean Up a Few More Places
- Key Takeaways
- What’s Next?
- Refactoring: Moving to MVVM
- What Is MVVM?
- Replace String Literals to Use a View Model
- Overwrite Storyboard Labels
- Respond to Changes in the View Model
- Move Logic into the View Model
- Key Takeaways
- What’s Next?
- Refactoring: Moving to MVP
- What Is MVP?
- Set Up the MVP Types
- Extract Methods into the View Commands Protocol
- Move a Function into the Presenter
- Remove the didSet Observer
- Use Refactoring Principles to Reparent a Swift Type
- Move Several Functions to the Presenter
- Extract Password Validation into Its Own Type
- Finish Up the Refactoring to MVP
- Key Takeaways
- What’s Next?
- Test-Driven Development Beckons to You
- What Is TDD?
- Make a New Place to Play with TDD
- Define the Requirements of the Time-of-Day Greeter
- Design the First Failing Test with Bare Production Code
- Make the First Test Pass with “Good Morning”
- Refactor the First Test to Make It More Expressive
- Repeat the TDD Steps for the Second Test
- Add Tests to Expand “Good Afternoon”
- Implement “Good Evening”
- Step Back to Refactor the Method as a Whole
- Add the Name to the Greeting
- Key Takeaways
- What’s Next?
- Unleash the Power of Refactoring