SlideShare a Scribd company logo
Unit Testing in iOS
featuring OCUnit, GHUnit & OCMock
            works for OS X too!




               @hpique
The sad fate of developers who don’t write unit tests
Agenda

• Unit testing
• OCUnit
• GHUnit
• OCMock
• Profit!
unit test
             =
code that tests a single unit
          of code
Hey look! A unit test!
- (void) testColorFromPointAndSize_SizeZero
{
    // Prepare input
    CGSize size = CGSizeZero;
    CGPoint point = CGPointZero;

    // Do something
    UIColor *color = [_viewController colorFromPoint:point andSize:size];

    // Validate output
    STAssertNil(color, @"Color must be nil when size is zero");
}
Reasons not to unit
      test
...
ReasonsExcuses not
    to unit test
Excuses

• “I don’t need it”
• “Deadline is too tight”
• “It’s not applicable for this [project|
  class|method]”

• “Unit testing in Xcode sucks”
Reasons to unit test
• Fix bugs early
• Refine design
• Easier to make changes
• Instant gratification :)
• Useful documentation
• Reduce testing time
quality code and testable
  code are best buds
When?

• After writing code
• Before writing code (TDD)
• After fixing a bug
Definitions
          Test Suite

           SetUp

Test Case Test Case Test Case

          TearDown
Agenda

• Unit testing
• OCUnit
• GHUnit
• OCMock
• Profit!
OCUnit


• De-facto unit testing framework for
  Obj-C

• Xcode provides native support
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
+N
#import <SenTestingKit/SenTestingKit.h>

@interface HelloWorldTests : SenTestCase

@end

@implementation HelloWorldTests

- (void)setUp
{
    [super setUp];

    // Set-up code here.
}

- (void)tearDown
{
    // Tear-down code here.

       [super tearDown];
}

- (void)testExample
{
    STFail(@"Unit tests are not implemented yet in HelloWorldTests");
}

@end
Writing tests with
        OCUnit
• Each Test Suite is a class that inherits
  from SenTestCase

• Each Test Case is a method with prefix
  test

• setUp & tearDown are optional
+U
Console output
2011-12-09 12:43:01.394 HelloWorld[2858:fb03] Applications are expected to have a
root view controller at the end of application launch
Test Suite 'All tests' started at 2011-12-09 11:43:01 +0000
Test Suite '/Users/hermespique/Library/Developer/Xcode/DerivedData/HelloWorld-
ezilismrgmrzecbbsndapbyeczre/Build/Products/Debug-iphonesimulator/
HelloWorldTests.octest(Tests)' started at 2011-12-09 11:43:01 +0000
Test Suite 'HelloWorldTests' started at 2011-12-09 11:43:01 +0000
Test Case '-[HelloWorldTests testExample]' started.
/Users/hermespique/Documents/workspace/HelloWorld/HelloWorldTests/
HelloWorldTests.m:33: error: -[HelloWorldTests testExample] : Unit tests are not
implemented yet in HelloWorldTests
Test Case '-[HelloWorldTests testExample]' failed (0.000 seconds).
Test Suite 'HelloWorldTests' finished at 2011-12-09 11:43:01 +0000.
Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds
Test Suite '/Users/hermespique/Library/Developer/Xcode/DerivedData/HelloWorld-
ezilismrgmrzecbbsndapbyeczre/Build/Products/Debug-iphonesimulator/
HelloWorldTests.octest(Tests)' finished at 2011-12-09 11:43:01 +0000.
Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds
Test Suite 'All tests' finished at 2011-12-09 11:43:01 +0000.
Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.001) seconds
OCUnit Macros
STAssertEqualObjects(a1, a2, description, ...)
STAssertEquals(a1, a2, description, ...)
STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...)
STFail(description, ...)
STAssertNil(a1, description, ...)
STAssertNotNil(a1, description, ...)
STAssertTrue(expr, description, ...)
STAssertTrueNoThrow(expr, description, ...)
STAssertFalse(expr, description, ...)
STAssertFalseNoThrow(expr, description, ...)
STAssertThrows(expr, description, ...)
STAssertThrowsSpecific(expr, specificException, description, ...)
STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...)
STAssertNoThrow(expr, description, ...)
STAssertNoThrowSpecific(expr, specificException, description, ...)
STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...)
Most used macros
STAssertTrue(expr, description, ...)

STAssertFalse(expr, description, ...)

STAssertNil(a1, description, ...)

STAssertNotNil(a1, description, ...)

STAssertEqualObjects(a1, a2, description, ...)

STAssertEquals(a1, a2, description, ...)

STFail(description, ...)

STAssertThrows(expr, description, ...)
Let’s see some code!




github.com/hpique/Unit-Testing-in-iOS-Sample-Code
Agenda

• Unit testing
• OCUnit
• GHUnit
• OCMock
• Profit!
GHUnit
• The other Unit Testing framework for
  Obj-C

• Open-source: github.com/gabriel/gh-
  unit

• GUI!
• No Xcode native support
• Compatible with OCUnit
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
#import <GHUnitIOS/GHUnit.h>

@interface ExampleTest : GHTestCase
@end

@implementation ExampleTest

- (BOOL)shouldRunOnMainThread {
    return NO;
}

- (void)setUpClass {
    // Run at start of all tests in the class
}

- (void)setUp {
    // Run before each test method
}

- (void)tearDown {
    // Run after each test method
}

- (void)tearDownClass {
    // Run at end of all tests in the class
}

- (void)testFoo {
    NSString *a = @"foo";
    GHAssertNotNil(a, nil);
}

@end
If you’re into macros...
GHAssertNoErr(a1, description, ...)           GHAssertEquals(a1, a2, description, ...)
GHAssertErr(a1, a2, description, ...)         GHAbsoluteDifference(left,right)
GHAssertNotNULL(a1, description, ...)         (MAX(left,right)-MIN(left,right))
GHAssertNULL(a1, description, ...)            GHAssertEqualsWithAccuracy(a1, a2,
GHAssertNotEquals(a1, a2, description, ...)   accuracy, description, ...)
GHAssertNotEqualObjects(a1, a2, desc, ...)    GHFail(description, ...)
GHAssertOperation(a1, a2, op,                 GHAssertNil(a1, description, ...)
description, ...)                             GHAssertNotNil(a1, description, ...)
GHAssertGreaterThan(a1, a2,                   GHAssertTrue(expr, description, ...)
description, ...)                             GHAssertTrueNoThrow(expr,
GHAssertGreaterThanOrEqual(a1, a2,            description, ...)
description, ...)                             GHAssertFalse(expr, description, ...)
GHAssertLessThan(a1, a2, description, ...)    GHAssertFalseNoThrow(expr,
GHAssertLessThanOrEqual(a1, a2,               description, ...)
description, ...)                             GHAssertThrows(expr, description, ...)
GHAssertEqualStrings(a1, a2,                  GHAssertThrowsSpecific(expr,
description, ...)                             specificException, description, ...)
GHAssertNotEqualStrings(a1, a2,               GHAssertThrowsSpecificNamed(expr,
description, ...)                             specificException, aName,
GHAssertEqualCStrings(a1, a2,                 description, ...)
description, ...)                             GHAssertNoThrow(expr, description, ...)
GHAssertNotEqualCStrings(a1, a2,              GHAssertNoThrowSpecific(expr,
description, ...)                             specificException, description, ...)
GHAssertEqualObjects(a1, a2,                  GHAssertNoThrowSpecificNamed(expr,
description, ...)                             specificException, aName,
                                              description, ...)
GHUnitAsyncTestCase
#import <GHUnitIOS/GHUnit.h>

@interface AsyncTest : GHAsyncTestCase { }
@end

@implementation AsyncTest

- (void)testURLConnection {
    [self prepare];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://
www.google.com"]];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self startImmediately:YES];

       [self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testURLConnection)];
}

@end
Configure GHUnit
1. Create target
2. Add GHUnitiOS.framework
 2.1.and QuartzCore.framework!
3. Modify Other Linker Flags
4. Change AppDelegate
1. Create target
1. Create target
2. Add
GHUnitiOS.framework
1. Download from github & unzip
2. > cd gh-unit/Project-iOS
3. > make
                    or
Download the latest stable framework from
github downloads
3. Modify Other Link
        Flags

• Add -all_load
• Add -ObjC
4. Change AppDelegate
   1. Remove default AppDelegate
   2. Modify main.m:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil,
@"GHUnitIOSAppDelegate");
    }
}
+B
Let’s see some code!




github.com/hpique/Unit-Testing-in-iOS-Sample-Code
OCUnit vs GHUnit
                     OCUnit           GHUnit

Xcode integration    Built-in         Manual
                     Console        Console
    Results
                    Contextual         GUI
                                   More macros
  Development                      GHAsyncTestCase

                                    Everything,
   Execution        Everything
                                 selection or failed
Using OCUnit tests in
     GHUnit target
  1. Add OCUnit tests to target
  2. Add tested files to target
  3. Add SenTestKit.framework
  4. Add this to Framework Search Paths
     (order matters):
$(SDKROOT)/Developer/Library/Frameworks
$(DEVELOPER_LIBRARY_DIR)/Frameworks
Agenda

• Unit testing
• OCUnit
• GHUnit
• OCMock
• Profit!
mock object
           =
simulated object that
mimics the behavior
  of a real object in
   controlled ways
When to mock an
        object?
• supplies non-deterministic results (ie:
  sensors)

• has states that are difficult to create or
  reproduce (ie: a network error)

• is slow (ie: database)
• does not yet exist or may change behavior
• to avoid writing “test code”
OCMock
• De-facto mocking framework for Obj-C
• Open-source: github.com/erikdoe/
  ocmock

• mock objects on the fly via the
  trampoline pattern

• Complementary with OCUnit & GHUnit
Hey look! Mock objects!
- (void) testHandleGesture
{
    // Prepare input and state
    id viewMock = [OCMockObject partialMockForObject:_viewController.view];
    CGRect viewFrame = CGRectMake(0, 0, 320, 480);
    [[[viewMock stub] andReturnValue:OCMOCK_VALUE(viewFrame)] frame];
    _viewController.view = viewMock;

    UIGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] init];
    id gestureMock = [OCMockObject partialMockForObject:gesture];
    CGPoint gesturePoint = CGPointMake(viewFrame.size.width / 2,
                                       viewFrame.size.height / 2);
    [[[gestureMock stub]
      andReturnValue:OCMOCK_VALUE(gesturePoint)] locationInView:[OCMArg any]];

    // Do something that changes state
    [_viewController handleGesture:gestureMock];

    // Validate state
    UIColor *expectedColor = [UIColor colorWithRed:0.5 green:0.5 blue:0 alpha:1];
    UIColor *color = _viewController.view.backgroundColor;
    [self assertEqualsColor:expectedColor toColor:color];
}
Let’s see some code!




github.com/hpique/Unit-Testing-in-iOS-Sample-Code
Thanks!


 @hpique

More Related Content

KEY
Unit testing en iOS @ MobileCon Galicia
PDF
Stop Making Excuses and Start Testing Your JavaScript
PPTX
Qunit Java script Un
PPTX
Understanding JavaScript Testing
PDF
Understanding JavaScript Testing
PDF
An introduction to Google test framework
PDF
GMock framework
PDF
Server1
Unit testing en iOS @ MobileCon Galicia
Stop Making Excuses and Start Testing Your JavaScript
Qunit Java script Un
Understanding JavaScript Testing
Understanding JavaScript Testing
An introduction to Google test framework
GMock framework
Server1

What's hot (20)

PPTX
Code generation for alternative languages
PDF
Unit Testing: Special Cases
PDF
Introduction to web programming for java and c# programmers by @drpicox
PPTX
Migrating to JUnit 5
PDF
Android testing
PDF
Adventures In JavaScript Testing
PPT
Introduzione al TDD
PDF
Agile Swift
PDF
Agile Android
DOCX
Algoritmos sujei
PPTX
Secret unit testing tools no one ever told you about
PDF
ReactJS for Programmers
PDF
33rd Degree 2013, Bad Tests, Good Tests
PDF
Voxxed Days Vilnius 2015 - Having fun with Javassist
PDF
Redux for ReactJS Programmers
PPTX
Static code analysis: what? how? why?
PDF
Python testing using mock and pytest
PPT
2012 JDays Bad Tests Good Tests
PDF
How to fake_properly
PPTX
Club of anonimous developers "Refactoring: Legacy code"
Code generation for alternative languages
Unit Testing: Special Cases
Introduction to web programming for java and c# programmers by @drpicox
Migrating to JUnit 5
Android testing
Adventures In JavaScript Testing
Introduzione al TDD
Agile Swift
Agile Android
Algoritmos sujei
Secret unit testing tools no one ever told you about
ReactJS for Programmers
33rd Degree 2013, Bad Tests, Good Tests
Voxxed Days Vilnius 2015 - Having fun with Javassist
Redux for ReactJS Programmers
Static code analysis: what? how? why?
Python testing using mock and pytest
2012 JDays Bad Tests Good Tests
How to fake_properly
Club of anonimous developers "Refactoring: Legacy code"
Ad

Similar to Unit testing in iOS featuring OCUnit, GHUnit & OCMock (20)

ODP
Grails unit testing
PDF
멀티플랫폼 앱 개발과 테스팅
PDF
Describe's Full of It's
PPTX
In search of JavaScript code quality: unit testing
PPT
Junit and testNG
PDF
Test driven development
PPTX
Testing basics for developers
ODP
Good Practices On Test Automation
PDF
MT_01_unittest_python.pdf
PPTX
Full Stack Unit Testing
PDF
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
PPTX
Unit testing patterns for concurrent code
PDF
Javascript tdd byandreapaciolla
PDF
Golang dot-testing-lite
PDF
Testing, Performance Analysis, and jQuery 1.4
PPTX
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
PPT
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
PDF
Unit Testing - The Whys, Whens and Hows
PDF
Developer Test - Things to Know
PPTX
Junit_.pptx
Grails unit testing
멀티플랫폼 앱 개발과 테스팅
Describe's Full of It's
In search of JavaScript code quality: unit testing
Junit and testNG
Test driven development
Testing basics for developers
Good Practices On Test Automation
MT_01_unittest_python.pdf
Full Stack Unit Testing
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Unit testing patterns for concurrent code
Javascript tdd byandreapaciolla
Golang dot-testing-lite
Testing, Performance Analysis, and jQuery 1.4
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Unit Testing - The Whys, Whens and Hows
Developer Test - Things to Know
Junit_.pptx
Ad

More from Robot Media (7)

PDF
Android In-app Billing @ Droidcon Murcia
KEY
Android in-app billing @ Google DevFest Barcelona 2012
KEY
Tracking social media campaigns @ editech
KEY
The Language of Interactive Children's Books @ toc bologna
KEY
Android In-App Billing @ Droidcon 2011
KEY
Android In-App Billing @ Barcelona GTUG
PPT
Droid Comic Viewer: El Ecosistema Android
Android In-app Billing @ Droidcon Murcia
Android in-app billing @ Google DevFest Barcelona 2012
Tracking social media campaigns @ editech
The Language of Interactive Children's Books @ toc bologna
Android In-App Billing @ Droidcon 2011
Android In-App Billing @ Barcelona GTUG
Droid Comic Viewer: El Ecosistema Android

Recently uploaded (20)

PDF
Encapsulation theory and applications.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PPTX
Cloud computing and distributed systems.
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
A Presentation on Artificial Intelligence
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPT
Teaching material agriculture food technology
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Understanding_Digital_Forensics_Presentation.pptx
Encapsulation theory and applications.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Cloud computing and distributed systems.
Encapsulation_ Review paper, used for researhc scholars
Chapter 3 Spatial Domain Image Processing.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto
A Presentation on Artificial Intelligence
MYSQL Presentation for SQL database connectivity
Agricultural_Statistics_at_a_Glance_2022_0.pdf
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Teaching material agriculture food technology
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Per capita expenditure prediction using model stacking based on satellite ima...
Network Security Unit 5.pdf for BCA BBA.
Understanding_Digital_Forensics_Presentation.pptx

Unit testing in iOS featuring OCUnit, GHUnit & OCMock

  • 1. Unit Testing in iOS featuring OCUnit, GHUnit & OCMock works for OS X too! @hpique
  • 2. The sad fate of developers who don’t write unit tests
  • 3. Agenda • Unit testing • OCUnit • GHUnit • OCMock • Profit!
  • 4. unit test = code that tests a single unit of code
  • 5. Hey look! A unit test! - (void) testColorFromPointAndSize_SizeZero { // Prepare input CGSize size = CGSizeZero; CGPoint point = CGPointZero; // Do something UIColor *color = [_viewController colorFromPoint:point andSize:size]; // Validate output STAssertNil(color, @"Color must be nil when size is zero"); }
  • 6. Reasons not to unit test
  • 7. ...
  • 8. ReasonsExcuses not to unit test
  • 9. Excuses • “I don’t need it” • “Deadline is too tight” • “It’s not applicable for this [project| class|method]” • “Unit testing in Xcode sucks”
  • 10. Reasons to unit test • Fix bugs early • Refine design • Easier to make changes • Instant gratification :) • Useful documentation • Reduce testing time
  • 11. quality code and testable code are best buds
  • 12. When? • After writing code • Before writing code (TDD) • After fixing a bug
  • 13. Definitions Test Suite SetUp Test Case Test Case Test Case TearDown
  • 14. Agenda • Unit testing • OCUnit • GHUnit • OCMock • Profit!
  • 15. OCUnit • De-facto unit testing framework for Obj-C • Xcode provides native support
  • 18. +N
  • 19. #import <SenTestingKit/SenTestingKit.h> @interface HelloWorldTests : SenTestCase @end @implementation HelloWorldTests - (void)setUp { [super setUp]; // Set-up code here. } - (void)tearDown { // Tear-down code here. [super tearDown]; } - (void)testExample { STFail(@"Unit tests are not implemented yet in HelloWorldTests"); } @end
  • 20. Writing tests with OCUnit • Each Test Suite is a class that inherits from SenTestCase • Each Test Case is a method with prefix test • setUp & tearDown are optional
  • 21. +U
  • 22. Console output 2011-12-09 12:43:01.394 HelloWorld[2858:fb03] Applications are expected to have a root view controller at the end of application launch Test Suite 'All tests' started at 2011-12-09 11:43:01 +0000 Test Suite '/Users/hermespique/Library/Developer/Xcode/DerivedData/HelloWorld- ezilismrgmrzecbbsndapbyeczre/Build/Products/Debug-iphonesimulator/ HelloWorldTests.octest(Tests)' started at 2011-12-09 11:43:01 +0000 Test Suite 'HelloWorldTests' started at 2011-12-09 11:43:01 +0000 Test Case '-[HelloWorldTests testExample]' started. /Users/hermespique/Documents/workspace/HelloWorld/HelloWorldTests/ HelloWorldTests.m:33: error: -[HelloWorldTests testExample] : Unit tests are not implemented yet in HelloWorldTests Test Case '-[HelloWorldTests testExample]' failed (0.000 seconds). Test Suite 'HelloWorldTests' finished at 2011-12-09 11:43:01 +0000. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds Test Suite '/Users/hermespique/Library/Developer/Xcode/DerivedData/HelloWorld- ezilismrgmrzecbbsndapbyeczre/Build/Products/Debug-iphonesimulator/ HelloWorldTests.octest(Tests)' finished at 2011-12-09 11:43:01 +0000. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.000) seconds Test Suite 'All tests' finished at 2011-12-09 11:43:01 +0000. Executed 1 test, with 1 failure (0 unexpected) in 0.000 (0.001) seconds
  • 23. OCUnit Macros STAssertEqualObjects(a1, a2, description, ...) STAssertEquals(a1, a2, description, ...) STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) STFail(description, ...) STAssertNil(a1, description, ...) STAssertNotNil(a1, description, ...) STAssertTrue(expr, description, ...) STAssertTrueNoThrow(expr, description, ...) STAssertFalse(expr, description, ...) STAssertFalseNoThrow(expr, description, ...) STAssertThrows(expr, description, ...) STAssertThrowsSpecific(expr, specificException, description, ...) STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) STAssertNoThrow(expr, description, ...) STAssertNoThrowSpecific(expr, specificException, description, ...) STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...)
  • 24. Most used macros STAssertTrue(expr, description, ...) STAssertFalse(expr, description, ...) STAssertNil(a1, description, ...) STAssertNotNil(a1, description, ...) STAssertEqualObjects(a1, a2, description, ...) STAssertEquals(a1, a2, description, ...) STFail(description, ...) STAssertThrows(expr, description, ...)
  • 25. Let’s see some code! github.com/hpique/Unit-Testing-in-iOS-Sample-Code
  • 26. Agenda • Unit testing • OCUnit • GHUnit • OCMock • Profit!
  • 27. GHUnit • The other Unit Testing framework for Obj-C • Open-source: github.com/gabriel/gh- unit • GUI! • No Xcode native support • Compatible with OCUnit
  • 29. #import <GHUnitIOS/GHUnit.h> @interface ExampleTest : GHTestCase @end @implementation ExampleTest - (BOOL)shouldRunOnMainThread { return NO; } - (void)setUpClass { // Run at start of all tests in the class } - (void)setUp { // Run before each test method } - (void)tearDown { // Run after each test method } - (void)tearDownClass { // Run at end of all tests in the class } - (void)testFoo { NSString *a = @"foo"; GHAssertNotNil(a, nil); } @end
  • 30. If you’re into macros... GHAssertNoErr(a1, description, ...) GHAssertEquals(a1, a2, description, ...) GHAssertErr(a1, a2, description, ...) GHAbsoluteDifference(left,right) GHAssertNotNULL(a1, description, ...) (MAX(left,right)-MIN(left,right)) GHAssertNULL(a1, description, ...) GHAssertEqualsWithAccuracy(a1, a2, GHAssertNotEquals(a1, a2, description, ...) accuracy, description, ...) GHAssertNotEqualObjects(a1, a2, desc, ...) GHFail(description, ...) GHAssertOperation(a1, a2, op, GHAssertNil(a1, description, ...) description, ...) GHAssertNotNil(a1, description, ...) GHAssertGreaterThan(a1, a2, GHAssertTrue(expr, description, ...) description, ...) GHAssertTrueNoThrow(expr, GHAssertGreaterThanOrEqual(a1, a2, description, ...) description, ...) GHAssertFalse(expr, description, ...) GHAssertLessThan(a1, a2, description, ...) GHAssertFalseNoThrow(expr, GHAssertLessThanOrEqual(a1, a2, description, ...) description, ...) GHAssertThrows(expr, description, ...) GHAssertEqualStrings(a1, a2, GHAssertThrowsSpecific(expr, description, ...) specificException, description, ...) GHAssertNotEqualStrings(a1, a2, GHAssertThrowsSpecificNamed(expr, description, ...) specificException, aName, GHAssertEqualCStrings(a1, a2, description, ...) description, ...) GHAssertNoThrow(expr, description, ...) GHAssertNotEqualCStrings(a1, a2, GHAssertNoThrowSpecific(expr, description, ...) specificException, description, ...) GHAssertEqualObjects(a1, a2, GHAssertNoThrowSpecificNamed(expr, description, ...) specificException, aName, description, ...)
  • 31. GHUnitAsyncTestCase #import <GHUnitIOS/GHUnit.h> @interface AsyncTest : GHAsyncTestCase { } @end @implementation AsyncTest - (void)testURLConnection { [self prepare]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http:// www.google.com"]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; [self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testURLConnection)]; } @end
  • 32. Configure GHUnit 1. Create target 2. Add GHUnitiOS.framework 2.1.and QuartzCore.framework! 3. Modify Other Linker Flags 4. Change AppDelegate
  • 35. 2. Add GHUnitiOS.framework 1. Download from github & unzip 2. > cd gh-unit/Project-iOS 3. > make or Download the latest stable framework from github downloads
  • 36. 3. Modify Other Link Flags • Add -all_load • Add -ObjC
  • 37. 4. Change AppDelegate 1. Remove default AppDelegate 2. Modify main.m: int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, @"GHUnitIOSAppDelegate"); } }
  • 38. +B
  • 39. Let’s see some code! github.com/hpique/Unit-Testing-in-iOS-Sample-Code
  • 40. OCUnit vs GHUnit OCUnit GHUnit Xcode integration Built-in Manual Console Console Results Contextual GUI More macros Development GHAsyncTestCase Everything, Execution Everything selection or failed
  • 41. Using OCUnit tests in GHUnit target 1. Add OCUnit tests to target 2. Add tested files to target 3. Add SenTestKit.framework 4. Add this to Framework Search Paths (order matters): $(SDKROOT)/Developer/Library/Frameworks $(DEVELOPER_LIBRARY_DIR)/Frameworks
  • 42. Agenda • Unit testing • OCUnit • GHUnit • OCMock • Profit!
  • 43. mock object = simulated object that mimics the behavior of a real object in controlled ways
  • 44. When to mock an object? • supplies non-deterministic results (ie: sensors) • has states that are difficult to create or reproduce (ie: a network error) • is slow (ie: database) • does not yet exist or may change behavior • to avoid writing “test code”
  • 45. OCMock • De-facto mocking framework for Obj-C • Open-source: github.com/erikdoe/ ocmock • mock objects on the fly via the trampoline pattern • Complementary with OCUnit & GHUnit
  • 46. Hey look! Mock objects! - (void) testHandleGesture { // Prepare input and state id viewMock = [OCMockObject partialMockForObject:_viewController.view]; CGRect viewFrame = CGRectMake(0, 0, 320, 480); [[[viewMock stub] andReturnValue:OCMOCK_VALUE(viewFrame)] frame]; _viewController.view = viewMock; UIGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] init]; id gestureMock = [OCMockObject partialMockForObject:gesture]; CGPoint gesturePoint = CGPointMake(viewFrame.size.width / 2, viewFrame.size.height / 2); [[[gestureMock stub] andReturnValue:OCMOCK_VALUE(gesturePoint)] locationInView:[OCMArg any]]; // Do something that changes state [_viewController handleGesture:gestureMock]; // Validate state UIColor *expectedColor = [UIColor colorWithRed:0.5 green:0.5 blue:0 alpha:1]; UIColor *color = _viewController.view.backgroundColor; [self assertEqualsColor:expectedColor toColor:color]; }
  • 47. Let’s see some code! github.com/hpique/Unit-Testing-in-iOS-Sample-Code