ios test-driven development

150
iOS Test-Driven Development Experiencing a new way of working

Upload: pablo-villar

Post on 04-Jul-2015

199 views

Category:

Software


0 download

DESCRIPTION

Experiencing a new way of developing

TRANSCRIPT

Page 1: iOS Test-Driven Development

iOS Test-Driven Development

Experiencing a new way of working

Page 2: iOS Test-Driven Development

I’m going to talk about…

• Some definitions

• Some concepts

• Unit Tests

• The TDD cycle

• Some principles

!

• TDD: Pros & Cons

• 3 kind of verifications

• External dependencies

• iOS Tests (practice part!)

• References

Page 3: iOS Test-Driven Development

Some definitions

Page 4: iOS Test-Driven Development

–Wikipedia

Test-driven development (TDD) is a software development process that relies on the

repetition of a very short development cycle. !

- !

Kent Beck, who is credited with having developed or ‘rediscovered' the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.

Page 5: iOS Test-Driven Development

–jayway.com

Test-driven development, or TDD for short, is a simple software development practice where unit tests, small focused test cases, drive the development forward.

!

- !

Test cases are written before any production code. !

Not all the tests are written up front, it’s rather that a small test is written, then a small piece of production code is

written that only allows that test to pass.

Page 6: iOS Test-Driven Development

–Sunetos, Inc.

TDD is an approach to development that uses automated software tests to drive the design and development of an

application iteratively. !

- !

It pushes the developer to focus on one thing at a time, and usually one fairly small thing.

Page 7: iOS Test-Driven Development

Some concepts

Page 8: iOS Test-Driven Development

The idea behind test-driven development is that it makes you think about what the code you are writing

needs to do while you are designing it.

Page 9: iOS Test-Driven Development

As a side effect, we get some safety against breaking things in the future.

OUR work, designing & coding

Page 10: iOS Test-Driven Development

TDD motivates rapid addition of new functionality to your code, because you are free to make any change you want to your code and can rapidly

get feedback on whether the change introduced any problems…

Page 11: iOS Test-Driven Development

TDD motivates rapid addition of new functionality to your code, because you are free to make any change you want to your code and can rapidly

get feedback on whether the change introduced any problems…

… or not!

Page 12: iOS Test-Driven Development

A common mistake in any discipline of software engineering is to only ask about code and test the

“happy path” without specifying or discovering what happens in case of error.

Page 13: iOS Test-Driven Development

A common mistake in any discipline of software engineering is to only ask about code and test the

“happy path” without specifying or discovering what happens in case of error.

That IS NOT GOOD.

Page 14: iOS Test-Driven Development

A common mistake in any discipline of software engineering is to only ask about code and test the

“happy path” without specifying or discovering what happens in case of error.

That IS NOT GOOD.

And, guess what? TDD discourages that.

Page 15: iOS Test-Driven Development

What is the cost of fixing a defect vs. preventing it? !

!

!

Learning and implementing TDD at the beginning is hard.

!

!

!

However, once you make it over the learning curve of TDD, your time-to-market will be the same, but with

many more benefits.

Page 16: iOS Test-Driven Development

TDD changes design from a process of invention

to a process of discovery.

Page 17: iOS Test-Driven Development

TDD changes design from a process of invention

to a process of discovery.

where the developer thinks hard about what a unit code should do and then

implements it

Page 18: iOS Test-Driven Development

TDD changes design from a process of invention

to a process of discovery.

where the developer thinks hard about what a unit code should do and then

implements it

where the developer adds small increments or functionality and then extracts structure

from the working code

Page 19: iOS Test-Driven Development

“Preventing bugs is not a TDD goal. It’s more like a side effect.”

Page 20: iOS Test-Driven Development

Unit Tests

Page 21: iOS Test-Driven Development

What is a Unit Test?

A unit test is a piece of code (usually a method) that invokes another piece of code and checks the correctness of some assumptions afterwards.

A unit test must test a single unit of code, which is usually a method or function within a class.

Page 22: iOS Test-Driven Development

What is a Unit Test?

Unit testing will be performed against a System Under Test (SUT).

SUTTests

If assumptions turn out to be wrong, the test has failed. Otherwise, the test has passed.

Page 23: iOS Test-Driven Development

Properties of a Unit Test

Any unit test should have the following properties:

❖ It should be automated and repeatable.

❖ It should be easy to implement.

❖ Once it’s written, it should remain for future use.

❖ Anyone should be able to run it.

❖ It should run quickly.

Page 24: iOS Test-Driven Development

❖ Verify  that  a  relatively  small  piece  of  code  is  doing  what  is  intended  to  do  !

❖ Narrow  in  scope  !

❖ Easy  to  write  and  execute  !

❖ Intended  for  the  use  of  the  programmer  !

❖ Testers  and  users  downstream  should  benefit  from  seeing  less  bugs  !

❖ Done  in  total  isolation

❖ Demonstrate  that  different  pieces  of  the  system  work  together  !

❖ Can  cover  whole  applications  !

❖ Require  more  effort  to  put  together  !

❖ Intended  for  the  use  of  non-­‐programmers  !

❖ Their  output  is  the  integrated  system  ready  for  System  Testing  !

❖ Done  altogether

UNIT  TESTS INTEGRATION  TESTS

(taken from my previous talk about KIF Integration Tests)

Page 25: iOS Test-Driven Development

Unit tests are usually composed by 3 parts:

1. Preparation // given

// when

// then

these initial conditions…

I execute this code…

I expect this to happen…

2. Execution

3. Verification

Page 26: iOS Test-Driven Development

// givenCounter *counter = [[Counter alloc] init];

[counter increment];

// when

// thenXCTAssertTrue(counter.count == 4, @“3 incremented should give us 4”);

[counter setCount:3];

Unit tests are usually composed by 3 parts:

Page 27: iOS Test-Driven Development

The TDD cycle

Page 28: iOS Test-Driven Development

TDD cycle

Page 29: iOS Test-Driven Development

Red-Green-Refactor approach

Page 30: iOS Test-Driven Development

Write a failing test

Page 31: iOS Test-Driven Development

Write a failing test

Write the simplest

code to pass the test

Page 32: iOS Test-Driven Development

Write a failing test

Write the simplest

code to pass the test

Refactor! to make code

clean

Page 33: iOS Test-Driven Development

Write a failing test

Write the simplest

code to pass the test

Refactor! to make code

clean

Page 34: iOS Test-Driven Development

Write a failing test

Write the simplest

code to pass the test

Refactor! to make code

clean

Both testing and production code

KISS

To make sure we are adding something new

Page 35: iOS Test-Driven Development

1.

Page 36: iOS Test-Driven Development

Write a failing test

To make sure we are adding something new

- (void)testOneIncrementedShouldYieldTwo { // given Counter *counter = [[Counter alloc] init]; [counter setCount:1]; ! // when [counter increment]; ! // then XCTAssertEqual(counter.count, 2, nil); }

1.

Tests SUT

Page 37: iOS Test-Driven Development

@implementation Counter !- (void)increment { !} !@end

Write a failing test

To make sure we are adding something new

1.

Tests SUT

Page 38: iOS Test-Driven Development

@implementation Counter !- (void)increment { !} !@end

Write a failing test

To make sure we are adding something new

Leaving this method empty we will make the test fail.

1.

Tests SUT

Page 39: iOS Test-Driven Development

Write the simplest

code to pass the test

KISS - Keep It Simple, Stupid

@implementation Counter !- (void)increment { !} !@end

2.

Tests SUT

Page 40: iOS Test-Driven Development

Write the simplest

code to pass the test

KISS - Keep It Simple, Stupid

@implementation Counter !- (void)increment { !} !@end

_count = 2;

2.

Tests SUT

Page 41: iOS Test-Driven Development

Write the simplest

code to pass the test

KISS - Keep It Simple, Stupid

@implementation Counter !- (void)increment { !} !@end With this simple line of code,

we are making the test pass.

_count = 2;

2.

Tests SUT

Page 42: iOS Test-Driven Development

Now, you may complain “This implementation is really stupid…”

And, it is!!! …It has to be! !This is because it satisfies in the cleanest way all the tests

we have so far.

Page 43: iOS Test-Driven Development

Now, you may complain “This implementation is really stupid…”

And, it is!!! …It has to be! !This is because it satisfies in the cleanest way all the tests

we have so far.

Page 44: iOS Test-Driven Development

WAIT A SECOND…

Page 45: iOS Test-Driven Development

Wouldn’t it be better if we made the method contain something like “_count ++;”

instead?!!

So that we’d be making sure it’ll pass some future tests we’d have to implement?

Page 46: iOS Test-Driven Development
Page 47: iOS Test-Driven Development

Come on, why not??? !

Explain yourself!

Page 48: iOS Test-Driven Development

“We want to live in the present. Not in the future.” !

Because the present will guide us in ways we might not expect.

And that IS GOOD!

Page 49: iOS Test-Driven Development

4 questions that will help you create the simplest thing that could possibly work

Page 50: iOS Test-Driven Development

The situation:

• You had a failing test.

• You went to production code and made the test pass in the simplest way you thought possible.

• But… Was it really the simplest way?

4 questions that will help you create the simplest thing that could possibly work

Page 51: iOS Test-Driven Development

The answer:

• We need to define what we consider being simple.

• For that, we’ll look at the code we’ve written and ask ourselves the following…

4 questions that will help you create the simplest thing that could possibly work

Page 52: iOS Test-Driven Development

Can I implement the same solution in a way that is…

4 questions that will help you create the simplest thing that could possibly work

Page 53: iOS Test-Driven Development

Can I implement the same solution in a way that is…

4 questions that will help you create the simplest thing that could possibly work

• …more hardcoded…

Page 54: iOS Test-Driven Development

Can I implement the same solution in a way that is…

4 questions that will help you create the simplest thing that could possibly work

• …more hardcoded…

• …closer to the beginning of the method I wrote it in…

Page 55: iOS Test-Driven Development

Can I implement the same solution in a way that is…

4 questions that will help you create the simplest thing that could possibly work

• …more hardcoded…

• …closer to the beginning of the method I wrote it in…

• …less indented (in as “less” scopes as possible, like if’s, loops, try-catch, etc)…

Page 56: iOS Test-Driven Development

Can I implement the same solution in a way that is…

4 questions that will help you create the simplest thing that could possibly work

• …more hardcoded…

• …closer to the beginning of the method I wrote it in…

• …less indented (in as “less” scopes as possible, like if’s, loops, try-catch, etc)…

• …shorter (literally less characters to write) yet still readable…

Page 57: iOS Test-Driven Development

Can I implement the same solution in a way that is…

4 questions that will help you create the simplest thing that could possibly work

• …more hardcoded…

• …closer to the beginning of the method I wrote it in…

• …less indented (in as “less” scopes as possible, like if’s, loops, try-catch, etc)…

• …shorter (literally less characters to write) yet still readable…

…AND STILL MAKE ALL THE TESTS PASS?

Page 58: iOS Test-Driven Development

4 questions that will help you create the simplest thing that could possibly work

Example

@implementation Counter !- (void)increment { !} !@end

test 1 incr = 2

Tests

Page 59: iOS Test-Driven Development

4 questions that will help you create the simplest thing that could possibly work

Example

@implementation Counter !- (void)increment { !} !@end

Tests

test 1 incr = 2

_count = 2;

Page 60: iOS Test-Driven Development

4 questions that will help you create the simplest thing that could possibly work

Example

@implementation Counter !- (void)increment { !} !@end

test 1 incr = 2test 2 incr = 3

Tests

_count = 2;

Page 61: iOS Test-Driven Development

test 1 incr = 2test 2 incr = 3

4 questions that will help you create the simplest thing that could possibly work

Example Tests

_count ++;

@implementation Counter !- (void)increment { !} !@end

Page 62: iOS Test-Driven Development

test 1 incr = 2test 2 incr = 3

4 questions that will help you create the simplest thing that could possibly work

Example Tests

_count ++; if (_count == 1) { _count = 2; } else if (_count == 2) { _count = 3; }

@implementation Counter !- (void)increment { !} !@end

Page 63: iOS Test-Driven Development

test 1 incr = 2test 2 incr = 3

4 questions that will help you create the simplest thing that could possibly work

Example Tests

_count ++; if (_count == 1) { _count = 2; } else if (_count == 2) { _count = 3; } Simpler than

@implementation Counter !- (void)increment { !} !@end

Page 64: iOS Test-Driven Development

3.

Page 65: iOS Test-Driven Development

Refactor! to make code

cleanBoth testing and production code.

3.

Page 66: iOS Test-Driven Development

Refactor! to make code

cleanBoth testing and production code.

We have nothing to refactor so far because our code remains clean…

3.

Page 67: iOS Test-Driven Development

Refactor! to make code

cleanBoth testing and production code.

We have nothing to refactor so far because our code remains clean…

So, we can skip this step.

3.

Page 68: iOS Test-Driven Development

Don’t refactor when you have failing tests.

Page 69: iOS Test-Driven Development

Always start refactoring from a clean state.

Page 70: iOS Test-Driven Development

Make sure all your tests keep passing after refactoring.

Page 71: iOS Test-Driven Development

Some principles

Page 72: iOS Test-Driven Development

The pillars of good tests

Every test you write must be:

1. Trustworthy

2. Maintainable

3. Readable

Page 73: iOS Test-Driven Development

Tips to have trustworthy tests

★ Decide when to remove or change tests.

★ Avoid test logic.

★ Test only one thing.

★ Make tests easy to run.

★ Assure code coverage.

Page 74: iOS Test-Driven Development

Ya Ain’t Gonna Need It

Page 75: iOS Test-Driven Development

Ya Ain’t Gonna Need It

The "YAGNI" principle

Page 76: iOS Test-Driven Development

The "YAGNI" principle

If you write tests that describe what's needed of your app code, and you only write code that passes those tests,

you will never write any code you don’t need.

This encourages production code to be simple, and avoids wasting time writing code that won’t have any

effect later.

A test-driven app should have no unused code, and no (or very little) untested code.

Page 77: iOS Test-Driven Development

The "YAGNI" principle

Remember: If you find yourself thinking during the refactoring stage that there are some changes you could make to have the code support more conditions, stop.

!

Why aren’t those conditions tested for in the test cases? Because those conditions don’t arise in the app.

!

So, don’t waste time adding the support, because… !

!

Page 78: iOS Test-Driven Development

The "YAGNI" principle

Remember: If you find yourself thinking during the refactoring stage that there are some changes you could make to have the code support more conditions, stop.

!

Why aren’t those conditions tested for in the test cases? Because those conditions don’t arise in the app.

!

So, don’t waste time adding the support, because… !

!

YA AIN’T GONNA

NEED IT

Page 79: iOS Test-Driven Development

The "YAGNI" principle

Remember: If you find yourself thinking during the refactoring stage that there are some changes you could make to have the code support more conditions, stop.

!

Why aren’t those conditions tested for in the test cases? Because those conditions don’t arise in the app.

!

So, don’t waste time adding the support, because… !

!

YA AIN’T GONNA

NEED IT

Page 80: iOS Test-Driven Development

Should we test private methods?

Page 81: iOS Test-Driven Development

Should we test private methods…?

To answer that, let's observe the following fact: !

You have already tested your private methods.

Page 82: iOS Test-Driven Development

By following the TDD's red-green-refactor approach, you designed your objects’ public APIs to do the work those

objects need to do. !

With that work specified by the tests, you are free to organize the internal plumbing of your classes as you see fit.

Page 83: iOS Test-Driven Development

Your private methods have already been tested because all you are doing is refactoring behavior that you already have

tests for.

Page 84: iOS Test-Driven Development

You should never end up in a situation where a private method is untested or incompletely tested, because you

create them only when you see an opportunity to clean up the implementation of public methods.

Page 85: iOS Test-Driven Development

This ensures that the private methods exist only to support the classes’ public behavior, and that they must be invoked

during testing because they are definitely being called from public methods.

Page 86: iOS Test-Driven Development

TDD: Pros & Cons

Page 87: iOS Test-Driven Development

✓ A 2005 study found that using TDD meant writing more tests and, in turn, developers who wrote more tests tended to be more productive.

✓ Programmers using pure TDD reported they only rarely felt the need to invoke a debugger.

✓ TDD offers more than just simple validation of correctness, but can also drive the design of a program.

✓ TDD gives the development team, and subsequent users, a greater level of confidence in the code.

TDD benefits

Page 88: iOS Test-Driven Development

✓ Despite the fact that more code is required with TDD because of the testing code, the total code implementation time could be shorter.

✓ TDD can lead to more modularized, flexible and extensible code.

✓ TDD suggests a better modularization, easier reuse and testing of the developed software products.

✓ TDD raises the overall code quality in the projects, which saves time due to a better maintainability and an easier bug-fixing process.

TDD benefits

Page 89: iOS Test-Driven Development

๏ Increase the amount of test code coverage.

๏ Increase the amount of test code coverage relative to the amount of code churn.

๏ Reduce the amount of bug reopening.

๏ Reduce the average bug-fixing time (the time from "bug opened" to "bug closed").

Some TDD goals

Page 90: iOS Test-Driven Development

TDD does not perform sufficient testing in situations where full functional tests are required to determine success or failure due to extensive use of unit tests.

If the developer misinterprets the requirements specification for the module being developed, both the tests and the code will be wrong, as giving a false sense of correctness.

A high number of passing unit tests may bring a false sense of security, result in in fewer additional software testing activities, such as integration testing and compliance testing.

TDD shortcomings

Page 91: iOS Test-Driven Development

Overtesting can consume time both to write the excessive tests, and later, to rewrite the tests when requirements change.

Hard learning curve. Very difficult at the beginning due to drastic changes which are involved in the process.

TDD shortcomings

Page 92: iOS Test-Driven Development

Team progress and output measured with and without tests

source: The Art Of Unit Testing - Roy Osherove

Real case of a Pilot Project

That’s why it’s important to emphasize that, although unit testing can increase the amount of time it takes to implement a feature, the time balances out over the product’s release cycle because of increased quality and maintainability.

Page 93: iOS Test-Driven Development

Is TDD worth it?

(taken from Jon Reid’s blog “Quality Coding”)

Page 94: iOS Test-Driven Development

3 kind of verifications

Page 95: iOS Test-Driven Development

System Under Test

Page 96: iOS Test-Driven Development

SUT

Page 97: iOS Test-Driven Development

messageSUT

Page 98: iOS Test-Driven Development

message

return valueSUT

Page 99: iOS Test-Driven Development

message

return valueSUT

- (id)calculateSomethingFromArg:(id)arg;

Page 100: iOS Test-Driven Development

message

return value

Return Value Verification

SUT

- (id)calculateSomethingFromArg:(id)arg;

Page 101: iOS Test-Driven Development

SUT

- (void)doSomething;

Page 102: iOS Test-Driven Development

SUT

- (void)doSomething;

initial state

Page 103: iOS Test-Driven Development

SUT

- (void)doSomething;

initial state

message

Page 104: iOS Test-Driven Development

SUT

- (void)doSomething;

initial state

message

state accessor

result state

Page 105: iOS Test-Driven Development

State Verification

SUT

- (void)doSomething;

initial state

message

state accessor

result state

Page 106: iOS Test-Driven Development

State Verification

SUT

- (void)doSomething;

initial state

message

state accessor

result state

State-based testing (also called state verification) determines whether the exercised method worked correctly by examining the SUT after the method is exercised.

Page 107: iOS Test-Driven Development

SUTDependent

object

Page 108: iOS Test-Driven Development

SUTmessage Dependent

object

Page 109: iOS Test-Driven Development

SUTmessage Dependent

object

Page 110: iOS Test-Driven Development

SUTmessage Fake

object

Page 111: iOS Test-Driven Development

Interaction Verification

SUTmessage Fake

object

(a.k.a. Behavior Verification)

Page 112: iOS Test-Driven Development

Interaction Verification

SUTmessage Fake

object

(a.k.a. Behavior Verification)

Interaction testing is testing how an object sends input to or receives input from other objects—how that object interacts with other objects.

Page 113: iOS Test-Driven Development

3 kind of verifications

Page 114: iOS Test-Driven Development

Working with external dependencies

Page 115: iOS Test-Driven Development

What is an external dependency?

Real ObjectSUT

CollaboratorClass

?request something

expect a value back

HOW?

We shouldn’t care

External dependency

An external dependency is an object in your system that your code under test interacts with, and over

which you have no control.

Page 116: iOS Test-Driven Development

External dependencies

• Filesystems

• Managers

• Handlers

• Connections

• Formatters

• Etc

How are we going to deal with an external dependency

when we need to test our SUT?

We need to make sure our external dependency works as we expect, since

we are NOT testing it, but our SUT.

FAKE OBJECTS

Page 117: iOS Test-Driven Development

A fake object is just an object that mimics the behavior of a real object in controlled ways.

!We define how we want the fake object to respond to certain

stimulations, such as method calls.

Fake Objects

Real ObjectSUT

CollaboratorClass

?request something

expect a value back

HOW?

We shouldn’t care

External dependency

Page 118: iOS Test-Driven Development

A fake object is just an object that mimics the behavior of a real object in controlled ways.

!We define how we want the fake object to respond to certain

stimulations, such as method calls.

Fake Objects

Fake ObjectSUT

CollaboratorClass

request something

expect a value back

We tell it what to respond

In such a fast, controllable and

kind of hardcoded way.

Page 119: iOS Test-Driven Development

Fake Objects

Fake ObjectSUT

CollaboratorClass

request something

expect a value back

We tell it what to respond…

Test Class … and then we assert the result.

(AGAINST WHOM…?)

Page 120: iOS Test-Driven Development

Fake Objects

STUBSUT

Test Class

communication

assert against

SUT

Page 121: iOS Test-Driven Development

Fake Objects

MOCKSUT

Test Class

communication

assert against

fake object

Page 122: iOS Test-Driven Development

Fake Objects

If we assert against…

the fake object the object is a mock.FS

T

the system under test the object is just a stub.FS

T

Page 123: iOS Test-Driven Development

Fake Objects

If we assert against…

the fake object the object is a mock.FS

T

the system under test the object is just a stub.FS

T

We can have as many stubs as we need F

F

F

Page 124: iOS Test-Driven Development

Fake Objects

If we assert against…

the fake object the object is a mock.FS

T

We can have at most one mock per test

the system under test the object is just a stub.FS

T

We can have as many stubs as we need F

F

F

F

Page 125: iOS Test-Driven Development

Fake Objects

If we assert against…

the fake object the object is a mock.FS

T

We can have at most one mock per test

the system under test the object is just a stub.FS

T

We can have as many stubs as we need F

F

F

F

We should never assert against two different things within the same test!

T

Page 126: iOS Test-Driven Development

Fake Objects

However, we could end up having a configuration like this one…

FakeSUT

Test

Fake

Fake

Fake

Page 127: iOS Test-Driven Development

Fake Objects

However, we could end up having a configuration like this one…

Where we have multiple stubs, but only one mock.

MockSUT

Test

Stub

Stub

Stub

Page 128: iOS Test-Driven Development

Fake Objects

However, we could end up having a configuration like this one…

Where we have multiple stubs, but only one mock.

MockSUT

Test

Stub

Stub

Stub

Page 129: iOS Test-Driven Development

Fake Objects

How do we build fake objects?

Manually

By using a framework

• OCMock

• OCMockito

• Etc

Page 130: iOS Test-Driven Development

How do we make external dependencies interact with our SUT?

Dependency Injection

C’mon… It ain’t gonna hurt!

THE DEPENDOCTOR

Page 131: iOS Test-Driven Development

✤ Dependency Injection

✤ Design for Testing

Both are important topics on TDD that won’t be explained in this talk because they are too much extensive that they’d require another complete talk to be minimally understood.

Page 132: iOS Test-Driven Development

Time for iOS tests!

Page 133: iOS Test-Driven Development

Objective-C Unit Testing Frameworks

❖ OCUnit!

❖ XCTest (Xcode 5 onwards)

Page 134: iOS Test-Driven Development

Objective-C Unit Testing Frameworks

❖ OCUnit!

❖ XCTest (Xcode 5 onwards)

Integrates with OS X Server CI using Bots

Page 135: iOS Test-Driven Development

Objective-C Unit Testing Frameworks

❖ OCUnit!

❖ XCTest (Xcode 5 onwards)

OCHamcrest

OCMockitoIntegrates with OS X Server

CI using Bots

Page 136: iOS Test-Driven Development

UI tests

@property (strong, nonatomic) IBOutlet UIButton *button;

Page 137: iOS Test-Driven Development

UI tests

@property (strong, nonatomic) IBOutlet UIButton *button;

- (IBAction)buttonPressed:(id)sender;

Page 138: iOS Test-Driven Development

UI tests

@property (strong, nonatomic) IBOutlet UIButton *button;

- (IBAction)buttonPressed:(id)sender;

Test 1: Is outlet hooked up?

Page 139: iOS Test-Driven Development

UI tests

@property (strong, nonatomic) IBOutlet UIButton *button;

- (IBAction)buttonPressed:(id)sender;

Test 1: Is outlet hooked up?

Test 2: Is outlet connected to action?

Page 140: iOS Test-Driven Development

UI tests

@property (strong, nonatomic) IBOutlet UIButton *button;

- (IBAction)buttonPressed:(id)sender;

Test 1: Is outlet hooked up?

Test 2: Is outlet connected to action?

Test 3: Invoke action directly.

Page 141: iOS Test-Driven Development

References

Page 142: iOS Test-Driven Development

Test-Driven iOS Development

by Graham Lee

…for iOS TDD developers

It’s like the holy bible…

2012 Objective-C

Page 143: iOS Test-Driven Development

The Art Of Unit Testing

by Roy Osherove

with Examples in .NET

2009 .NET

Page 144: iOS Test-Driven Development

xUnit Test Patterns

by Gerard Meszaros

Refactoring Test Code

2007 Java

Page 145: iOS Test-Driven Development

Working Effectively With Legacy Code

by Michael Feathers

2005 Java, C++, C

Page 146: iOS Test-Driven Development

http://qualitycoding.org/Jon Reid’s blog

2011 - Actuality

Page 147: iOS Test-Driven Development

http://en.wikipedia.org/wiki/Test-driven_development

Wikipedia

http://en.wikipedia.org/wiki/Mock_object

couldn’t be missing…

Page 148: iOS Test-Driven Development

Other websites and articleshttp://www.jayway.com/2010/01/15/test-driven-development-in-xcode/ !http://www.sunetos.com/items/2011/10/24/tdd-ios-part-1/ !https://www.youtube.com/watch?v=S5MvykD3yiE (iOS Unit Testing Like A Boss by Matt Darnal) !http://www.mockobjects.com/ !http://osherove.com/blog/2010/1/6/tdd-4-questions-that-will-help-you-create-the-simplest-thing.html !http://martinfowler.com/articles/mocksArentStubs.html

Page 149: iOS Test-Driven Development

That’s all, folks! (for now…)

Page 150: iOS Test-Driven Development

I hope you start liking TDD :)

Pablo Villar - April 2014 @ InakaLabs