SlideShare a Scribd company logo
Unit Testing en iOS
       @hpique
Así terminan los programadores que no hacen unit testing
Agenda

• Unit Testing
• OCUnit
• GHUnit
• Profit!
Unit Testing

Testeo de unidades mínimas de
   código mediante código
- (void)testColorFromHex {
    NSString* colorString = @"#d34f01";

    UIColor* color = [colorString colorFromHex];

    const CGFloat *c = CGColorGetComponents(color.CGColor);
    STAssertEquals(c[0], 211/255.0f, colorString, @"");
    STAssertEquals(c[1], 79/255.0f, colorString, @"");
    STAssertEquals(c[2], 1/255.0f, colorString, @"");
    STAssertEquals(CGColorGetAlpha(color.CGColor), 1.0f,
colorString, @"");
}
Razones para no hacer
     unit testing
...
RazonesExcusas para
no hacer unit testing
Excusas
Excusas

• “No lo necesito”
Excusas

• “No lo necesito”
• “El plazo es muy ajustado”
Excusas

• “No lo necesito”
• “El plazo es muy ajustado”
• “No aplica para este proyecto”
Excusas

• “No lo necesito”
• “El plazo es muy ajustado”
• “No aplica para este proyecto”
• “Unit testing en XCode apesta”
Razones para sí hacer
    unit testing
Razones para sí hacer
    unit testing
• Corregir bugs antes
Razones para sí hacer
    unit testing
• Corregir bugs antes
• Refinar el diseño
Razones para sí hacer
    unit testing
• Corregir bugs antes
• Refinar el diseño
• Facilitar cambios
Razones para sí hacer
    unit testing
• Corregir bugs antes
• Refinar el diseño
• Facilitar cambios
• Documentación útil
Razones para sí hacer
    unit testing
• Corregir bugs antes
• Refinar el diseño
• Facilitar cambios
• Documentación útil
• Reducir tiempo de testeo
¿Cuándo?
¿Cuándo?

• Lo antes posible (TDD)
¿Cuándo?

• Lo antes posible (TDD)
• En paralelo
¿Cuándo?

• Lo antes posible (TDD)
• En paralelo
• Al corregir bugs
Definiciones
            Test Suite

             SetUp

Test Case   Test Case    Test Case

            TearDown
Agenda

• Unit Testing
• OCUnit
• GHUnit
• Profit!
OCUnit


• Framework de Unit Testing para Obj-C
• Único framework de testeo integrado
  nativamente en XCode
+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
Escribiendo unit tests
     con OCUnit
• Cada Test Suite es una clase que hereda de
  SenTestCase

• Cada Test Case debe ser un método con el
  prefijo test

• setUp y tearDown son opcionales
+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, ...)
OCUnit 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, ...)
Agenda

• Unit Testing
• OCUnit
• GHUnit
• Profit!
GHUnit

• Framework de Unit Testing para Obj-C
• Open-source: github.com/gabriel/gh-unit
• GUI!
• Compatible con OCUnit
#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
GHUnit 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
Configurar GHUnit

1. Crear target
2. Agregar GHUnitiOS.framework
3. Modificar Other Linker Flags
4. Cambiar de AppDelegate
1. Crear target
1. Crear target
2. Agregar
GHUnitiOS.framework
• Primero debemos hacer build del framework
1. Descargar de github y descomprimir
2. > cd gh-unit/Project-iOS
3. > make
3. Modificar Other Link
         Flags

• Agregar -all_load
• Agregar -objC
4. Cambiar de
          AppDelegate
int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc,
argv, nil, @"GHUnitIOSAppDelegate");
    }
}
+B
OCUnit vs GHUnit
                    OCUnit           GHUnit
Integración con
                    Built-in          Manual
    XCode
                  Contextual /
  Resultados                      Consola / GUI
                   Consola
                                   Más macros
Programación
                                 GHAsyncTestCase
                                 Todo, selección o
  Ejecución          Todo
                                     fallidos
¡Gracias!


  @hpique

More Related Content

What's hot

Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
Test-driven JavaScript Development - OPITZ CONSULTING -  Tobias Bosch - Stefa...Test-driven JavaScript Development - OPITZ CONSULTING -  Tobias Bosch - Stefa...
Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
OPITZ CONSULTING Deutschland
 
Easy Button
Easy ButtonEasy Button
Easy Button
Adam Dale
 
Voxxed Days Vilnius 2015 - Having fun with Javassist
Voxxed Days Vilnius 2015 - Having fun with JavassistVoxxed Days Vilnius 2015 - Having fun with Javassist
Voxxed Days Vilnius 2015 - Having fun with Javassist
Anton Arhipov
 
Clean code via dependency injection + guice
Clean code via dependency injection + guiceClean code via dependency injection + guice
Clean code via dependency injection + guice
Jordi Gerona
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
Anton Arhipov
 
Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
Rafael Winterhalter
 
0003 es5 핵심 정리
0003 es5 핵심 정리0003 es5 핵심 정리
0003 es5 핵심 정리
욱래 김
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
Sergey Platonov
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
Jay Harris
 
Adventures In JavaScript Testing
Adventures In JavaScript TestingAdventures In JavaScript Testing
Adventures In JavaScript Testing
Thomas Fuchs
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
jeresig
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVE
Uehara Junji
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
Andrea Francia
 
Live Updating Swift Code
Live Updating Swift CodeLive Updating Swift Code
Live Updating Swift Code
Bartosz Polaczyk
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
Anton Arhipov
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能について
Uehara Junji
 
Maze
MazeMaze
Maze
yito24
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
Thierry Wasylczenko
 
Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9
Andrey Zakharevich
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
Thierry Wasylczenko
 

What's hot (20)

Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
Test-driven JavaScript Development - OPITZ CONSULTING -  Tobias Bosch - Stefa...Test-driven JavaScript Development - OPITZ CONSULTING -  Tobias Bosch - Stefa...
Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
Voxxed Days Vilnius 2015 - Having fun with Javassist
Voxxed Days Vilnius 2015 - Having fun with JavassistVoxxed Days Vilnius 2015 - Having fun with Javassist
Voxxed Days Vilnius 2015 - Having fun with Javassist
 
Clean code via dependency injection + guice
Clean code via dependency injection + guiceClean code via dependency injection + guice
Clean code via dependency injection + guice
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
 
Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
 
0003 es5 핵심 정리
0003 es5 핵심 정리0003 es5 핵심 정리
0003 es5 핵심 정리
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
 
Adventures In JavaScript Testing
Adventures In JavaScript TestingAdventures In JavaScript Testing
Adventures In JavaScript Testing
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVE
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 
Live Updating Swift Code
Live Updating Swift CodeLive Updating Swift Code
Live Updating Swift Code
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能について
 
Maze
MazeMaze
Maze
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 

Similar to Unit testing en iOS @ MobileCon Galicia

In search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingIn search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testing
Anna Khabibullina
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
Christoffer Noring
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
Richárd Kovács
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
Tomek Kaczanowski
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Tomek Kaczanowski
 
Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It's
Jim Lynch
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
Giordano Scalzo
 
Introduction to nsubstitute
Introduction to nsubstituteIntroduction to nsubstitute
Introduction to nsubstitute
Suresh Loganatha
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
Guillaume Laforge
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
jeresig
 
Testing with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifeTesting with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs Life
Peter Gfader
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
Bastian Feder
 
Scala test
Scala testScala test
Scala test
Meetu Maltiar
 
Scala test
Scala testScala test
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle GamesWe Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
Unity Technologies
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
Neil Crosby
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
Giordano Scalzo
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
John Ferguson Smart Limited
 
JavaScript Editions ES7, ES8 and ES9 vs V8
JavaScript Editions ES7, ES8 and ES9 vs V8JavaScript Editions ES7, ES8 and ES9 vs V8
JavaScript Editions ES7, ES8 and ES9 vs V8
Rafael Casuso Romate
 

Similar to Unit testing en iOS @ MobileCon Galicia (20)

In search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingIn search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testing
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It's
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
 
Introduction to nsubstitute
Introduction to nsubstituteIntroduction to nsubstitute
Introduction to nsubstitute
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 
Testing with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifeTesting with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs Life
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Scala test
Scala testScala test
Scala test
 
Scala test
Scala testScala test
Scala test
 
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle GamesWe Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
We Love Performance! How Tic Toc Games Uses ECS in Mobile Puzzle Games
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
JavaScript Editions ES7, ES8 and ES9 vs V8
JavaScript Editions ES7, ES8 and ES9 vs V8JavaScript Editions ES7, ES8 and ES9 vs V8
JavaScript Editions ES7, ES8 and ES9 vs V8
 

More from Robot Media

Android In-app Billing @ Droidcon Murcia
Android In-app Billing @ Droidcon MurciaAndroid In-app Billing @ Droidcon Murcia
Android In-app Billing @ Droidcon Murcia
Robot Media
 
Android in-app billing @ Google DevFest Barcelona 2012
Android in-app billing @ Google DevFest Barcelona 2012Android in-app billing @ Google DevFest Barcelona 2012
Android in-app billing @ Google DevFest Barcelona 2012
Robot Media
 
Tracking social media campaigns @ editech
Tracking social media campaigns @ editechTracking social media campaigns @ editech
Tracking social media campaigns @ editech
Robot Media
 
The Language of Interactive Children's Books @ toc bologna
The Language of Interactive Children's Books @ toc bolognaThe Language of Interactive Children's Books @ toc bologna
The Language of Interactive Children's Books @ toc bologna
Robot Media
 
Android In-App Billing @ Droidcon 2011
Android In-App Billing @ Droidcon 2011Android In-App Billing @ Droidcon 2011
Android In-App Billing @ Droidcon 2011
Robot Media
 
Android In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUGAndroid In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUG
Robot Media
 
Droid Comic Viewer: El Ecosistema Android
Droid Comic Viewer: El Ecosistema AndroidDroid Comic Viewer: El Ecosistema Android
Droid Comic Viewer: El Ecosistema Android
Robot Media
 

More from Robot Media (7)

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

Recently uploaded

Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
Rohit Gautam
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
ThomasParaiso2
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
Claudio Di Ciccio
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 

Recently uploaded (20)

Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 

Unit testing en iOS @ MobileCon Galicia

  • 1. Unit Testing en iOS @hpique
  • 2. Así terminan los programadores que no hacen unit testing
  • 3. Agenda • Unit Testing • OCUnit • GHUnit • Profit!
  • 4. Unit Testing Testeo de unidades mínimas de código mediante código
  • 5. - (void)testColorFromHex { NSString* colorString = @"#d34f01"; UIColor* color = [colorString colorFromHex]; const CGFloat *c = CGColorGetComponents(color.CGColor); STAssertEquals(c[0], 211/255.0f, colorString, @""); STAssertEquals(c[1], 79/255.0f, colorString, @""); STAssertEquals(c[2], 1/255.0f, colorString, @""); STAssertEquals(CGColorGetAlpha(color.CGColor), 1.0f, colorString, @""); }
  • 6. Razones para no hacer unit testing
  • 7. ...
  • 10. Excusas • “No lo necesito”
  • 11. Excusas • “No lo necesito” • “El plazo es muy ajustado”
  • 12. Excusas • “No lo necesito” • “El plazo es muy ajustado” • “No aplica para este proyecto”
  • 13. Excusas • “No lo necesito” • “El plazo es muy ajustado” • “No aplica para este proyecto” • “Unit testing en XCode apesta”
  • 14. Razones para sí hacer unit testing
  • 15. Razones para sí hacer unit testing • Corregir bugs antes
  • 16. Razones para sí hacer unit testing • Corregir bugs antes • Refinar el diseño
  • 17. Razones para sí hacer unit testing • Corregir bugs antes • Refinar el diseño • Facilitar cambios
  • 18. Razones para sí hacer unit testing • Corregir bugs antes • Refinar el diseño • Facilitar cambios • Documentación útil
  • 19. Razones para sí hacer unit testing • Corregir bugs antes • Refinar el diseño • Facilitar cambios • Documentación útil • Reducir tiempo de testeo
  • 21. ¿Cuándo? • Lo antes posible (TDD)
  • 22. ¿Cuándo? • Lo antes posible (TDD) • En paralelo
  • 23. ¿Cuándo? • Lo antes posible (TDD) • En paralelo • Al corregir bugs
  • 24. Definiciones Test Suite SetUp Test Case Test Case Test Case TearDown
  • 25. Agenda • Unit Testing • OCUnit • GHUnit • Profit!
  • 26. OCUnit • Framework de Unit Testing para Obj-C • Único framework de testeo integrado nativamente en XCode
  • 27.
  • 28.
  • 29. +N
  • 30. #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
  • 31. Escribiendo unit tests con OCUnit • Cada Test Suite es una clase que hereda de SenTestCase • Cada Test Case debe ser un método con el prefijo test • setUp y tearDown son opcionales
  • 32. +U
  • 33. 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
  • 34. 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, ...)
  • 35. OCUnit 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, ...)
  • 36. Agenda • Unit Testing • OCUnit • GHUnit • Profit!
  • 37. GHUnit • Framework de Unit Testing para Obj-C • Open-source: github.com/gabriel/gh-unit • GUI! • Compatible con OCUnit
  • 38.
  • 39. #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
  • 40. GHUnit 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, ...)
  • 41. 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
  • 42. Configurar GHUnit 1. Crear target 2. Agregar GHUnitiOS.framework 3. Modificar Other Linker Flags 4. Cambiar de AppDelegate
  • 45. 2. Agregar GHUnitiOS.framework • Primero debemos hacer build del framework 1. Descargar de github y descomprimir 2. > cd gh-unit/Project-iOS 3. > make
  • 46. 3. Modificar Other Link Flags • Agregar -all_load • Agregar -objC
  • 47. 4. Cambiar de AppDelegate int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, @"GHUnitIOSAppDelegate"); } }
  • 48. +B
  • 49. OCUnit vs GHUnit OCUnit GHUnit Integración con Built-in Manual XCode Contextual / Resultados Consola / GUI Consola Más macros Programación GHAsyncTestCase Todo, selección o Ejecución Todo fallidos

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n