intro to test driven development for ios - quality coding · costs and benefits of tdd costs: •...
TRANSCRIPT
Jon Reid http://qualitycoding.org/tdd-workshop/
Intro toTest Driven Development
for iOS
http://www.flickr.com/photos/stefan-w/3337072853
What Are Some Qualities of Clean Code?
•
•
•
•
•
•
•
Write a failing test
Make the test pass
Refactor
The 3 Steps
Uncle Bob’s 3 Laws of TDD1. Write no production
code, except to pass a failing test.
2. Write only enough of a test to demonstrate a failure.(Compiler errors are failures.)
3. Write only enough production code to pass a test.
Tools I Like to Use• AppCode
If you use Xcode 8.2: https://www.jetbrains.com/objc/download/ If you use Xcode 8.3: https://confluence.jetbrains.com/display/OBJC/AppCode+EAP
• Custom Test Templates http://qualitycoding.org/files/XCTest-Templates.zip
• Custom Code Snippets http://qualitycoding.org/files/Snippets.zip
Fizz BuzzCode Kata
• Create a function that will return “Fizz” if its argument is a multiple of 3.
• The function should return “Buzz” if the argument is a multiple of 5.
• If the argument is a multiple of both 3 and 5, it should return “FizzBuzz”.
• Otherwise, it should return the argument in string form.
Bowling Game Code Kata
Write a class that has two methods:
• roll(_ pins: Int) is called each time the player rolls a ball. The argument is the number of pins knocked down.
• score() -> Int is called only at the very end of the game. It returns the total score for that game.
Objective-C and Swift walkthroughs: http://qualitycoding.org/xcode-tdd/
Let’s TDD a View Controller!
1. Increment and decrement a counter (see “View Controller Tricks”)
2. Add persistence via UserDefaults(see “Test Doubles in Swift”)
View Controller Tricks• How to load view controller if you use Storyboards:
let storyboard = UIStoryboard(name: "WHAT", bundle: nil)let sut = storyboard.instantiateViewController( withIdentifier: "SOMETHING") as! MyViewController
• Force any view controller to load its view: _ = sut.view
• Simulate “touch up inside” action on button: sut.button.sendActions(for: .touchUpInside)[sut.button sendActionsForControlEvents:UIControlEventTouchUpInside];
Test Doubles in Swift• Declare a protocol
• Attach to actual class with extension
• Production code: use protocol, not actual class
• Test code: supply test double that conforms to protocol
https://realm.io/news/making-mock-objects-more-useful-try-swift-2017/
Dependency Injection• Favor “Tell, Don’t Ask”
• Pass “stuff it needs” in initializer if possible. …Can use default parameters for “actual objects”
• If initializer isn’t possible, pass via properties. …Can use default values for “actual objects”
• Remember, you can also inject blocks for deferred calls
Costs and Benefits of TDD Costs:
• 15–35% increase in “initial development time”
• Plus slowdown while learning any new discipline
Initial Benefits:
• 40-90% decrease in defect density
• Fewer defects means lower debugging costs (people × time). Should result in nearly same “time to ship”
Ongoing Benefits:
• Code is cleaner due to testability requirement: reduced coupling
• Fully covered code can be safely refactored: agility increase
TDD Level: Easy• Model objects
• Business rules
• Create network request
• Process network response
TDD Level: Advanced• View navigation
• Networking
• Filesystem / Database
• Analytics
TDD Level: Intermediate• View controllers
• Invoke user actions
• Table views
• NSNotifications
TDD Level: Avoid• Actual networking
• Actual filesystem
• Actual database
• Asynchronous calls
http://qualitycoding.org/tdd-workshop/