Skip to content

Instantly share code, notes, and snippets.

@floriankrueger
Last active December 18, 2015 14:29
Show Gist options
  • Save floriankrueger/5797536 to your computer and use it in GitHub Desktop.
Save floriankrueger/5797536 to your computer and use it in GitHub Desktop.
Just a presentation I did on unit testing in Xcode to wrap up the whole topic and provide a basis for our in-team discussion. It uses the SublimeScreencastDirector plugin by @colinta to be "played". (https://github.com/colinta/SublimeScreencastDirector) Unfortunately, it's in german. But the code examples are kind of international ;)
- clear: 0 # screen 00 : Titel
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [4, 14]
- write_lines:
- 'Unittesting für iOS & OS X'
- goto: [5, 14]
- delay: 500
- write_lines:
- '=========================='
- goto: [7, 14]
- delay: 100
- write_lines:
- 'Eine kleine Einführung'
- clear: 0 # screen 01 : Agenda
- goto: [4, 14]
- write_lines:
- 'Agenda'
- '======'
- goto: [7, 14]
- delay: 500
- write_lines:
- '1. Was ist ein Unittest?'
- '2. Unittesting in Xcode'
- '3. Logic Test vs. Application Test'
- '4. TDD (Test Driven Development)'
- clear: 0 # screen 02 : Was ist ein Unittest?
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Was ist ein Unittest?'
- '====================='
- goto: [3, 2]
- write_lines:
- '"The goal of unit testing is to isolate each'
- 'part of the program and show that the individual'
- 'parts are correct."'
- goto: [7, 2]
- write_lines:
- '"A unit test provides a strict, written contract'
- 'that the piece of code must satisfy."'
- delay: 500
- goto: [10, 2]
- write_lines:
- '~ Quelle: https://en.wikipedia.org/wiki/Unit_testing'
- clear: 0 # screen 03 : Fibonacci Header
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- write: '/* Beispiel A: Eine kleine Beispielklasse */'
- nl
- nl
- delay: 500
- write:
- '// in Fibonacci.h'
- ''
- '@interface Fibonacci : NSObject'
- ''
- '+ (NSUInteger)fibonacci:(NSUInteger)n;'
- ''
- '@end'
- nl
- clear: 0 # screen 04 : Fibonacci Test Suite Teil 1
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- write: '/* Beispiel B: Ein einfacher Unittest */'
- nl
- nl
- delay: 500
- write:
- '// in FibonacciTests.m'
- set_mark: fib1_import
- ''
- '@implementation FibonacciTests'
- set_mark: fib1_tests
- ''
- '@end'
- goto_mark: fib1_import
- write:
- ''
- '#import "Fibonacci.h"'
- goto_mark: fib1_tests
- write:
- ''
- '- (void)testFibonacci10'
- '{'
- ' NSInteger f10 = [Fibonacci fibonacci:10];'
- ' STAssertEquals(f10, 55, nil);'
- '}'
- clear: 0 # screen 04 A : execution log
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- write:
- 'Execution Log'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾'
- nl
- insert: "Test Suite 'All tests' finished at 2013-06-13 13:48:44 +0000. \n"
- delay: 100
- insert: "Executed 1 test, with 0 failures (0 unexpected) in 0.000 (0.001) seconds \n"
- clear: 0 # screen 05 : Erklärung Test Suite Teil 1
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Struktur eines Unittests'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'
- goto: [3, 1]
- write_lines:
- '1. Herstellen aller Voraussetzungen für den Test'
- goto: [4, 1]
- write_lines:
- '2. Aufrufen der getesteten Methode'
- goto: [5, 1]
- write_lines:
- '3. Überprüfen der Resultate'
- goto: [6, 1]
- write_lines:
- '4. Aufräumen'
- goto: [8, 1]
- write: '- 1. und 4. sind im gezeigten Beispiel nicht enthalten.'
- clear: 0 # screen 06 : Arten von Unittests
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Arten von Unittests'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'
- goto: [3, 1]
- write_lines:
- '- Verhaltenstests'
- delay: 500
- goto: [5, 1]
- write_lines:
- ' "Tut der Code das, was er soll?"'
- delay: 500
- goto: [7, 1]
- write_lines:
- '- Stichprobenartig (unter Umständen)'
- '- Sollte Sonderfälle enthalten'
- '- Sollte Randfälle enthalten'
- '- Erwartet niemals Fehler'
- '- Werden bei TDD zuerst geschrieben'
- clear_lines: [5, -1]
- goto: [4, 1]
- write_lines:
- '- Regressiontests'
- delay: 500
- goto: [6, 1]
- write_lines:
- '"Ist ein bug (immernoch) gefixed?"'
- delay: 500
- goto: [8, 1]
- write_lines:
- '- Werden geschrieben, um einen von reporteten Bug nachzustellen.'
- '- Verbleiben auch nach dem Fix im Code um auszuschließen, dass das Problem'
- ' zu einem späteren Zeitpunkt wieder auftritt.'
- clear_lines: [6, -1]
- goto: [5, 1]
- write_lines:
- '- Fehlertests'
- delay: 500
- goto: [7, 1]
- write_lines:
- ' "Was tut der code, wenn er falsch benutzt wird?"'
- delay: 500
- goto: [9, 1]
- write_lines:
- '- falsche/ungültige Eingabewerte oder Ergebnisse'
- '- Overflows, ∞, NaN'
- '- Nil'
- '- Leere Collections'
- '- Unerwartete Typen in Collections'
- '- NSError'
- '- erwartet ggf. Exceptions'
- clear_lines: [7, -1]
- goto: [7, 1]
- write_lines:
- 'Alle diese sind wichtig um die Funktionsfähigkeit des zu testenden Codes'
- 'sicherzustellen.'
- clear: 0 # screen 07 : Erweiterung des Unittests
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- goto: [0, 0]
- write: '/* Beispiel C: Erweiterung der Unittests (Sonderfälle) */'
- nl
- nl
- delay: 500
- write_lines:
- '// in Fibonacci.h'
- ''
- '@interface Fibonacci : NSObject'
- ''
- '+ (NSUInteger)fibonacci:(NSUInteger)n;'
- ''
- '@end'
- nl
- delay: 500
- goto: [12, 0]
- write:
- '// in FibonacciTests.m'
- ''
- '#import "Fibonacci.h"'
- ''
- '@implementation FibonacciTests'
- set_mark: fib2_comment
- ''
- '- (void)testFibonacci10'
- '{'
- ' NSInteger f10 = [Fibonacci fibonacci:10];'
- ' STAssertEquals(f10, 55, nil);'
- '}'
- ''
- '@end'
- goto_mark: fib2_comment
- set_mark: fib2_special_cases
- write:
- ''
- '// Stichprobenartiger Positivtest: fib(10) = 55'
- goto_mark: fib2_special_cases
- write:
- set_mark: fib2_special1_comment
- ''
- '- (void)testFibonacci1'
- '{'
- ' NSInteger f1 = [Fibonacci fibonacci:1];'
- ' STAssertEquals(f1, 1, nil);'
- '}'
- set_mark: fib2_special2_comment
- ''
- '- (void)testFibonacci2'
- '{'
- ' NSInteger f2 = [Fibonacci fibonacci:2];'
- ' STAssertEquals(f2, 1, nil);'
- '}'
- goto_mark: fib2_special1_comment
- write:
- ''
- '// Sonderfall: fib(1) = 1'
- goto_mark: fib2_special2_comment
- write:
- ''
- '// Sonderfall: fib(2) = 1'
- clear: 0 # screen 07 A : execution log
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- write:
- 'Execution Log'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾'
- nl
- insert: "Test Suite 'All tests' finished at 2013-06-13 13:25:59 +0000. \n"
- delay: 100
- insert: "Executed 3 tests, with 0 failures (0 unexpected) in 0.000 (0.001) seconds \n"
- clear: 0 # screen 08 : Randfälle
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- goto: [0, 0]
- write: '/* Beispiel D: Erweiterung der Unittests (Randfälle) */'
- nl
- nl
- delay: 500
- write_lines:
- '// in Fibonacci.h'
- ''
- '@interface Fibonacci : NSObject'
- ''
- '+ (NSUInteger)fibonacci:(NSUInteger)n;'
- ''
- '@end'
- nl
- delay: 500
- goto: [12, 0]
- write:
- '// in FibonacciTests.m'
- ''
- '#import "Fibonacci.h"'
- ''
- '@implementation FibonacciTests'
- set_mark: fib3_special0
- ''
- '/* others */'
- ''
- '@end'
- goto_mark: fib3_special0
- write:
- ''
- '// Sonderfall: fib(<=0) = 0'
- '- (void)testFibonacci0'
- '{'
- ' NSInteger f0 = [Fibonacci fibonacci:0];'
- ' STAssertEquals(f0, 0, nil);'
- ''
- ' NSInteger flt0 = [Fibonacci fibonacci:-1];'
- ' STAssertEquals(flt0, 0, nil);'
- '}'
- clear: 0 # screen 08 A : execution log
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- write:
- 'Execution Log'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾'
- nl
- insert: "Test Suite 'FibonacciTests' started at 2013-06-13 14:06:44 +0000 \n"
- delay: 100
- insert: "Test Case '-[FibonacciTests testFibonacci0]' started. \n"
- delay: 100
- delay: 5000
- write: "(lldb) Thread 1: EXC_BAD_ACCESS (code=2, address=0xbf7fffcc)"
- clear: 0 # screen 09 : Algorithm improvements
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- goto: [0, 0]
- write: '/* Beispiel E: Implementierung der Klasse `Fibonacci` */'
- nl
- nl
- delay: 500
- write:
- '// in Fibonacci.m'
- ''
- '@implementation Fibonacci'
- ''
- '+ (NSInteger)fibonacci:(NSInteger)n'
- '{'
- set_mark: fib4_early_return
- ''
- ' NSInteger fn;'
- ''
- ' switch (n) {'
- ' case 1: {'
- ' fn = 1;'
- ' break;'
- ' }'
- ' case 2: {'
- ' fn = 1;'
- ' break;'
- ' }'
- ' default: {'
- ' fn = [self fibonacci:n - 1] + [self fibonacci:n - 2];'
- ' break;'
- ' }'
- ' }'
- ''
- ' return fn;'
- '}'
- ''
- '@end'
- goto_mark: fib4_early_return
- write:
- ''
- ' if (n <= 0) return 0;'
- clear: 0 # screen 09 A : execution log
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- write:
- 'Execution Log'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾'
- nl
- write:
delay_min: 1
delay_max: 1
write:
- "Test Suite 'All tests' finished at 2013-06-13 13:25:59 +0000."
- "Executed 4 tests, with 0 failures (0 unexpected) in 0.000 (0.001) seconds"
- clear: 0 # screen 10 : Abschluss "Was ist ein Unit Test"
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Warum das Ganze?'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'
- goto: [3, 1]
- write_lines:
- '1. Reduzierung (offensichtlicher) Bugs'
- delay: 500
- goto: [5, 4]
- write_lines:
- 'Wenn für Algorithmen vorher die wichtigsten/problematischsten/meisten'
- 'Fälle identifiziert werden, können offensichtliche Fehler wie der eben'
- 'gezeigte vermieden werden.'
- clear_lines: [5, -1]
- goto: [4, 1]
- write_lines:
- '2. Erleichterung von Refactoring'
- delay: 500
- goto: [6, 4]
- write_lines:
- 'Die innere Implementierung einer Methode kann beliebig verändert werden.'
- 'solang die Schnittstelle identisch bleibt, zeigen die Tests weiterhin, ob'
- 'die neue Implementierung den spezifizierten Anforderungen genügt.'
- clear_lines: [6, -1]
- goto: [5, 1]
- write_lines:
- '3. Reduzierung des Testzeit'
- delay: 500
- goto: [7, 4]
- write_lines:
- 'Ein Unittest ist immer schneller als ein manueller Test.'
- clear_lines: [7, -1]
- goto: [6, 1]
- write_lines:
- '4. Verbesserung des Software Designs (TDD)'
- delay: 500
- goto: [8, 4]
- write_lines:
- 'Durch Definition des Verhaltens einer Methode muss von Vorneherein auf'
- 'saubere Kapselung und Struktur des Codes geachtet werden. Auch eine Art'
- '"Schnittstelle" wird implizit definiert. Betrifft vor allem das Test-'
- 'Driven-Development.'
- clear_lines: [8, -1]
- goto: [9, 0]
- write_lines:
- '"Aber"'
- '______'
- goto: [12, 1]
- write_lines:
- '- Ein Unittest kann manuelles Testen nicht ersetzen.'
- goto: [13, 1]
- write_lines:
- '- Nicht jeder Code / jede Architektur is "Unittest-bar".'
- goto: [14, 1]
- write_lines:
- '- Asynchroner Code ist (meist) nur mit Tricks testbar.'
- goto: [15, 1]
- write_lines:
- '- Unittesting verlangt eiserne Disziplin'
- ' (vor allem wenn die Zeit knapp wird).'
- clear: 0 # screen 11 : Agenda (2)
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [4, 14]
- write_lines:
- 'Agenda'
- '======'
- goto: [7, 14]
- delay: 500
- write_lines:
- '1. Was ist ein Unittest?'
- '2. Unittesting in Xcode'
- '3. Logic Test vs. Application Test'
- '4. TDD (Test Driven Development)'
- delay: 500
- goto: [7, 12]
- select_delta: 1
- insert: '✓'
- clear: 0 # screen 12 : Unittesting in Xcode
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Unittesting in Xcode'
- '===================='
- goto: [3, 1]
- write_lines:
- '- Unittests werden als separates Target in Xcode angelegt.'
- goto: [4, 1]
- write_lines:
- '- Gem. Konvention endet der Name des Targets auf "Tests".'
- goto: [5, 1]
- write_lines:
- '- Jedem Target kann ein oder mehrere Testtargets zugewiesen werden, die'
- ' Testtargets werden dann mit dem Shortcut ⌘+U gestartet.'
- goto: [7, 1]
- write_lines:
- '- Xcode unterscheidet zwischen Logic Tests und Application Tests.'
- ' (dazu später mehr)'
- clear: 0 # screen 13 : Testsuites / Testklassen
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Testsuites / Testklassen'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'
- goto: [3, 1]
- write_lines:
- '- Eine Testsuite besteht aus einer einzelnen Objective-C Klasse.'
- goto: [4, 1]
- write_lines:
- '- Jede dieser Klassen muss von der Klasse "SenTestCase" ableiten.'
- goto: [5, 1]
- write_lines:
- '- Ein Test entspricht einer Methode.'
- goto: [6, 1]
- write_lines:
- '- Jede Methode, welche den Präfix "test" hat, wird als TestCase erkannt'
- ' und ausgeführt.'
- goto: [8, 1]
- write_lines:
- '- Testmethoden haben keine Argumente und geben immer `void` zurück.'
- goto: [9, 1]
- write_lines:
- '- Testmethoden machen `Assertions` um zu bestimmen ob sie den Status'
- ' `Pass` oder `Fail` annehmen.'
- goto: [11, 1]
- write_lines:
- '- Weitere besondere Methoden sind `setUp` und `tearDown`, andere Methoden'
- ' können vom Entwickler als Helfermethoden eingeführt werden.'
- goto: [13, 1]
- write_lines:
- '- Die Methoden setUpTestWithSelector:` und `tearDownTestWithSelector:`'
- ' können zusätzlich für Spezialfälle verwendet werden.'
- goto: [15, 1]
- write_lines:
- '- Headerfiles sind im Prinzip unnötig, da SenTestingKit direkt auf den'
- ' Selektoren einer Klasse arbeitet. Sie sollten aber aus Konsistenzgründen'
- ' dennoch beibehalten werden und können zur Dokumentation von'
- ' Hilfsmethoden nützlich sein.'
- clear: 0 # screen 14 : Beispiel Testsuite Header
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- goto: [0, 0]
- write: '/* Beispiel F1: Eine "vollständige" Testsuite */'
- nl
- nl
- delay: 500
- write:
- '// in ExampleTests.h'
- ''
- '#import <SenTestingKit/SenTestingKit.h>'
- ''
- '@interface ExampleTests : SenTestCase'
- ''
- '@end'
- clear: 0 # screen 15 : Beispiel Testsuite Implementation
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- goto: [0, 0]
- write: '/* Beispiel F2: Eine "vollständige" Testsuite */'
- nl
- nl
- delay: 500
- write:
- '// in ExampleTests.m'
- ''
- '#import "ExampleTests.h"'
- ''
- '@implementation ExampleTests'
- ''
- '+ (void)setUp // set up the whole testsuite before it runs'
- '{'
- ' [super setUp]; NSLog(@"in testsuite setUp");'
- '}'
- ''
- '- (void)setUp // set up each testcase before it runs'
- '{'
- ' [super setUp]; NSLog(@"in testcase setup");'
- '}'
- ''
- '- (void)testExample1'
- '{'
- ' NSLog(@"in testcase `testExample1`");'
- ' STAssertEquals((1+1), 2, @"The compiler isn`t feeling very well today");'
- '}'
- ''
- '- (void)testExample2'
- '{'
- ' NSLog(@"in testcase `testExample2`");'
- ' STAssertTrue(YES, @"Something is seriously wrong here");'
- '}'
- ''
- '- (void)tearDown // clean up each testcase after it has been run'
- '{'
- ' NSLog(@"in testcase tearDown"); [super tearDown];'
- '}'
- ''
- '+ (void)tearDown // clean up after the whole testsuite has been run'
- '{'
- ' NSLog(@"in testsuite tearDown"); [super tearDown];'
- '}'
- ''
- '@end'
- clear: 0 # screen 16 : execution log
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- write:
- 'Execution Log'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾'
- nl
- insert: "2013-06-14 10:54:51.095 Tests[1854:c07] in testsuite setUp \n"
- delay: 100
- insert: "Test Suite 'ExampleTests' started at 2013-06-14 08:54:51 +0000 \n"
- delay: 100
- insert: "Test Case '-[ExampleTests testExample1]' started. \n"
- delay: 100
- insert: "2013-06-14 10:54:51.095 Tests[1854:c07] in testcase setup \n"
- delay: 100
- insert: "2013-06-14 10:54:51.095 Tests[1854:c07] in testcase `testExample1` \n"
- delay: 100
- insert: "2013-06-14 10:54:51.095 Tests[1854:c07] in testcase tearDown \n"
- delay: 100
- insert: "Test Case '-[ExampleTests testExample1]' passed (0.001 seconds). \n"
- delay: 100
- insert: "Test Case '-[ExampleTests testExample2]' started. \n"
- delay: 100
- insert: "2013-06-14 10:54:51.096 Tests[1854:c07] in testcase setup \n"
- delay: 100
- insert: "2013-06-14 10:54:51.096 Tests[1854:c07] in testcase `testExample2` \n"
- delay: 100
- insert: "2013-06-14 10:54:51.096 Tests[1854:c07] in testcase tearDown \n"
- delay: 100
- insert: "Test Case '-[ExampleTests testExample2]' passed (0.000 seconds). \n"
- delay: 100
- insert: "Test Suite 'ExampleTests' finished at 2013-06-14 08:54:51 +0000. \n"
- delay: 100
- insert: "Executed 2 tests, with 0 failures (0 unexpected) in 0.001 (0.001) seconds \n"
- delay: 100
- insert: "2013-06-14 10:54:51.096 Tests[1854:c07] in testsuite tearDown \n"
- clear: 0 # screen 17 : STAsserts
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'STAsserts'
- '‾‾‾‾‾‾‾‾‾'
- goto: [3, 1]
- write_lines:
- '- Mithilfe von STAssert Macros wird die Erfüllung der Erwartungen an'
- ' den Test überprüft.'
- goto: [5, 1]
- write_lines:
- '- Ein Testcase OHNE assert gilt immer als bestanden, solang keine'
- ' Exception auftritt.'
- goto: [8, 1]
- write_lines:
- 'Die folgenden Macros existieren:'
- goto: [10, 1]
- write_lines:
- '- STFail'
- ''
- '- STAssertNil'
- ''
- '- STAssertNotNil'
- ''
- '- STAssertTrue'
- ''
- '- STAssertFalse'
- ''
- '- STAssertEquals'
- '- STAssertEqualObjects'
- '- STAssertEqualsWithAccuracy'
- ''
- '- STAssertThrows'
- '- STAssertThrowsSpecific'
- '- STAssertThrowsSpecificNamed'
- ''
- '- STAssertNoThrow'
- '- STAssertNoThrowSpecific'
- '- STAssertNoThrowSpecificNamed'
- ''
- '- STAssertTrueNoThrow'
- ''
- '- STAssertFalseNoThrow'
- clear: 0 # screen 18 : Agenda (3)
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [4, 14]
- write_lines:
- 'Agenda'
- '======'
- goto: [7, 12]
- delay: 500
- write_lines:
- '✓ 1. Was ist ein Unittest?'
- ' 2. Unittesting in Xcode'
- ' 3. Logic Test vs. Application Test'
- ' 4. TDD (Test Driven Development)'
- delay: 500
- goto: [8, 12]
- select_delta: 1
- insert: '✓'
- clear: 0 # screen 19 : Logic Test vs. Application Test
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Logic Test vs. Application Test'
- '==============================='
- goto: [3, 1]
- write_lines:
- 'Es handelt sich dabei um einen rein konzeptionellen Unterschied'
- goto: [5, 1]
- write_lines:
- '"Logic Tests" sind klassische Unittests:'
- goto: [7, 1]
- write_lines:
- '- Testen einer einzelnen Methode oder Klasse'
- '- Geeignet zum Testen von Algorithmen und Datenstrukturen'
- '- sehr schnell in der Ausführung'
- '- in etwa: "White Box Testing"'
- goto: [13, 1]
- write_lines:
- '"Application Tests" sind eher Integrationstests:'
- ' ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ '
- goto: [15, 1]
- write_lines:
- '- Tested "die App"'
- '- Testen von Zusammenspiel zwischen der View- und Controllerschicht'
- '- Vergleichsweise langsam in der Ausführung'
- '- in etwa: "Black Box Testing"'
- goto: [21, 0]
- write_lines:
- 'Technischer Unterschied'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'
- goto: [23, 1]
- write_lines:
- '- Logic Tests haben keinen Bundle Loader und demnach auch kein'
- ' Application Bundle'
- goto: [25, 1]
- write_lines:
- '- Ein Zugriff auf eine *.xib file, ein *.xcdatamodel u.ä. ist also nicht'
- ' möglich.'
- goto: [30, 0]
- write_lines:
- '> Der Trend geht start dazu über, ausschließlich Application tests zu'
- ' verwenden, da der Nachteil (längere Ausführungszeit) mittlerweile'
- ' kaum noch spürbar ist.'
- clear: 0 # screen 20 : Agenda (4)
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [4, 14]
- write_lines:
- 'Agenda'
- '======'
- goto: [7, 12]
- delay: 500
- write_lines:
- '✓ 1. Was ist ein Unittest?'
- '✓ 2. Unittesting in Xcode'
- ' 3. Logic Test vs. Application Test'
- ' 4. TDD (Test Driven Development)'
- delay: 500
- goto: [9, 12]
- select_delta: 1
- insert: '✓'
- clear: 0 # screen 21 : Logic Test vs. Application Test
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'TDD (Test Driven Development)'
- '============================='
- goto: [3, 1]
- write_lines:
- '- Bei TDD werden zuerst die Tests und dann der Code geschrieben.'
- goto: [4, 1]
- write_lines:
- '- Dabei wird immer nur der Code geschrieben, der die aktuell vorliegenden'
- ' Testfälle mit minimalem Aufwand abdeckt.'
- goto: [6, 1]
- write_lines:
- '- Man beginnt mit einem einzigen Testcase, implementiert die'
- ' geforderte Funktionalität bis der Test erfüllt ist und fügt dann den'
- ' nächsten Test hinzu, bis schließlich die gesamte Testsuite aktiv ist und'
- ' fehlerfrei ausgeführt werden kann.'
- goto: [10, 1]
- write_lines:
- '- Diese Form des Testens wird auch "Red-Green-Testing" genannt.'
- clear: 0 # screen 22 : TDD Example
- set_syntax: 'Packages/Objective-C/Objective-C.tmLanguage'
- goto: [0, 0]
- write: '/* Beispiel G: Test-Driven Fibonacci */'
- nl
- nl
- delay: 500
- write_lines:
- '@implementation TDDFibonacciTests'
- ''
- '- (void)testFibonacci'
- '{'
- ' STAssertTrue([TDDFibonacci fib:0] == 0, nil);'
- '}'
- ''
- '@end'
- ''
- '@implementation TDDFibonacci'
- ''
- '+ (NSInteger)fib:(NSInteger)n'
- '{'
- '}'
- ''
- '@end'
- goto: [6, 60]
- write: '✘'
- goto: [14, 2]
- nl
- write: ' return 0;'
- goto: [6, 60]
- select_delta: 1
- insert: '✔'
- goto: [6, 61]
- nl
- write: ' STAssertTrue([TDDFibonacci fib:1] == 1, nil);'
- goto: [7, 60]
- write: '✘'
- goto: [16, 11]
- select_delta: 1
- insert: '1'
- goto: [6, 60]
- select_delta: 1
- insert: '✘'
- goto: [7, 60]
- select_delta: 1
- insert: '✔'
- goto: [15, 2]
- nl
- write:
- ' if (0 == n) {'
- ' return 0;'
- ' }'
- goto: [6, 60]
- select_delta: 1
- insert: '✔'
- goto: [7, 61]
- nl
- write: ' STAssertTrue([TDDFibonacci fib:2] == 1, nil);'
- goto: [8, 60]
- write: '✔'
- goto: [8, 61]
- nl
- write: ' STAssertTrue([TDDFibonacci fib:3] == 2, nil);'
- goto: [9, 60]
- write: '✘'
- goto: [20, 8]
- write:
- 'else if (n <= 2) {'
- ' return 1;'
- ' }'
- select_lines: [23, 23]
- delete
- goto: [24, 11]
- select_delta: 1
- insert: '2'
- goto: [9, 60]
- select_delta: 1
- insert: '✔'
- goto: [9, 61]
- nl
- write: ' STAssertTrue([TDDFibonacci fib:4] == 3, nil);'
- goto: [10, 60]
- write: '✘'
- goto: [25, 11]
- select_delta: 1
- write: '1 + 1'
- goto: [25, 11]
- select_delta: 1
- write: '[self fib:(n-1)]'
- goto: [25, 30]
- select_delta: 1
- write: '[self fib:(n-2)]'
- goto: [10, 60]
- select_delta: 1
- insert: '✔'
- clear: 0 # screen 23 : Agenda (5)
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [4, 14]
- write_lines:
- 'Agenda'
- '======'
- goto: [7, 12]
- delay: 500
- write_lines:
- '✓ 1. Was ist ein Unittest?'
- '✓ 2. Unittesting in Xcode'
- '✓ 3. Logic Test vs. Application Test'
- ' 4. TDD (Test Driven Development)'
- delay: 500
- goto: [10, 12]
- select_delta: 1
- insert: '✓'
- goto: [11, 6]
- write_lines:
- '[NEW] 5. Unittesting in Xcode 5'
- clear: 0 # screen 24 : Unittesting in Xcode 5
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Unittesting in Xcode 5'
- '======================'
- goto: [3, 1]
- write_lines:
- '- XCTest ersetzt OCUnit (ist aber direkt davon abgeleitet).'
- goto: [4, 1]
- write_lines:
- '- Xcode 5 ist vollständig Rückwärtskompatibel zu OCUnit.'
- goto: [5, 1]
- write_lines:
- '- OCUnit Testcases können automatisch migriert werden.'
- clear: 0 # screen 25 : Integration in Xcode 5
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [0, 0]
- write_lines:
- 'Integration in Xcode 5'
- '‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'
- goto: [3, 1]
- write_lines:
- '- Es existiert ein vollständig neuer Workflow.'
- goto: [4, 1]
- write_lines:
- '- Neuer Testcase Navigator, der alle Testcases im Projekt auflistet und'
- ' deren aktuellen Status anzeigt.'
- goto: [6, 1]
- write_lines:
- '- One-Click Testing: Um einen einzelnen Testcase auszuführen, kann direkt'
- ' neben der Methode im Editor geklickt werden, man bekommt sofortiges'
- ' rot/grün Feedback.'
- goto: [9, 1]
- write_lines:
- '- One-Click Testing: Um eine Testsuite oder alle Tests auszuführen, kann'
- ' neben der entsprechenden Entität im Testcase Navigator geklickt werden.'
- ' Auch hier gibt es via rot/grün Marker sofortiges Feedback.'
- goto: [12, 1]
- write_lines:
- '- Test Failure Breakpoints zum einfacheren Debuggen von Fehlern in'
- ' Unittests. Diese spezielle Form von Breakpoints stoppen exakt BEVOR ein'
- ' Assert fehlschlagen würde.'
- goto: [15, 1]
- write_lines:
- '- Run Again Command: Führt währed des Debugging das zuletzt ausgeführte'
- ' Set an Testcases aus.'
- goto: [17, 1]
- write_lines:
- '- Test Callers: Ein neue Assistant Kategorie, die alle Testcases für eine'
- ' bestimmte API auflistet.'
- goto: [19, 1]
- write_lines:
- '- Continous Integration mit OS X Server möglich: Automatischer Test unter'
- ' verschiedenen Soft- und Hardware Konfigurationen, sowohl auf dem'
- ' Simulator als auch auf dem Device.'
- goto: [22, 1]
- write_lines:
- '- Bis jetzt keine existieren keine Informationen darüber, ob zukünftig'
- ' noch ein Unterschied zwischen Logic- und Applicationtests gemacht wird.'
- clear: 0 # screen 26 : Abschluss
- set_syntax: 'Packages/Text/Plain text.tmLanguage'
- goto: [4, 14]
- write_lines:
- 'Unittesting für iOS & OS X'
- goto: [5, 14]
- delay: 500
- write_lines:
- '=========================='
- goto: [8, 14]
- delay: 100
- write_lines:
- 'Vielen Dank für die Aufmerksamkeit'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment