Unit Testing in Xcode 8.3.2 with Swift3 Allan Shih
Agenda ● What is Unit Testing? ● Unit Testing in Xcode ● Create a Unit Testing class ● Write a Unit Testing class ● Test Asynchronous Operations ● Faking Objects and Interactions ● Demo ● Reference
What is Unit Testing? ● Unit testing, a testing technique using which individual modules are tested to determine if there are any issues by the developer himself. ● It is concerned with functional correctness of the standalone modules.
Unit Testing - Advantages ● Reduces Defects in the Newly developed features ● Reduces bugs when changing the existing functionality. ● Reduces Cost of Testing as defects are captured in very early phase. ● Improves design and allows better refactoring of code. ● Unit Tests, when integrated with build gives the quality of the build as well.
Unit Tests Main Properties ● Independent ○ Running a Unit Test should not affect another Unit Test run. Execution order is not important. ● Fast ○ A test which takes several seconds to run is not a Unit Test and probably needs a refactor. ● Isolated ○ Unit Test should not depend on external systems. They need to know their collaborators answers.
Create a project with Unit Tests
Creating a Unit Test Target in an existing project 1. Click the test navigator 2. Click the + button 3. Select “New Unit Test Target” 4. Create a Unit Test target
Select a host application
Build Settings > Deployment > iOS Deployment Target
Update CocoaPods ● Update a Podfile, and add test target dependencies: ● Run $ pod update in project directory. ● Open App.xcworkspace and build. target 'ThingMakerMvc' do use_frameworks! pod 'Alamofire', '~> 4.3' target 'ThingMakerMvcTests' do inherit! :search_paths end end
Create a Unit Test Case Class
Select a test target
Default Unit Test Case Class
Run the test class 1. ProductTest or Command-U. This actually runs all test classes. 2. Click the arrow button in the test navigator. 3. Click the diamond button in the gutter.
Unit Test Result
Unit Test Failed
Demo Unit Testing in Xcode
Unit Test Class Structure ● Class Setup/TearDown ○ Executed once when the Unit Test class is initialized, not for every test in the class. Useful to avoid test code duplication at class level. ● Test Setup/TearDown ○ Executed once before and after each executed Unit Test. Useful to avoid test code duplication at test level. ● Test Methods ○ The Unit Test implementation itself. Here is where the test run and validations happens.
Class Setup Example
Test Setup / Tear Down Example @available(iOS 9.0, *) UIViewController.loadViewIfNeeded()
Test Method example
Tests Naming ● Use descriptive test names. It will provide quick feedback when test fails. ● Choose names which in few words says: ○ Method under testing ○ Condition under testing ○ Expected result / behavior
Tests Naming Example ● Good examples ○ testSyncLullabyList_withLullabyManager_return3LullabyItems() ○ testSyncStationList_withIHeartRadioApi_return6StationItems() ● Bad examples ○ testExample1() ○ testExample2() ○ testExample3()
Test Method Organization ● Arrange / Setup ○ Prepare all needed objects/dependencies for test execution. ● Act / Test ○ Test itself it performed, calling one specific method in the system under testing. ● Assert / Verify ○ Method result/behavior verification is performed at the end, using test asserts.
Tests Verification Types ● Return Value / State Verification ○ Verify the result returned for the method under test, no matter which interactions with other objects has been made. Useful and preferred verification in most cases. ● Behavior Verification ○ Verify that all tested method interactions among other collaboration objects are the expected one (generally done using mocks). Useful for some cases where interactions are important (for example a cache implementation).
Return Value Verification
Return Value Verification Example
State Verification
State Verification Example
Behavior Verification
Behavior Verification
Behavior Verification
Behavior Verification Example
XCTAssert Family in XCode 8.3.2 XCTAssert Family Description XCTAssert Asserts that an expression is true. XCTAssertTrue Asserts that an expression is true. XCTAssertFalse Asserts that an expression is false. XCTAssertNil Asserts that an expression is nil. XCTAssertNotNil Asserts that an expression is not nil. XCTAssertEqual Asserts that two expressions have the same value. XCTAssertEqualObjects Asserts that two objects are considered equal.
XCTAssert Family in XCode 8.3.2 XCTAssert Family Description XCTAssertNotEqual Asserts that two expressions do not have the same value. XCTAssertNotEqualObjects Asserts that an expression is true. XCTAssertGreaterThan Asserts that the value of one expression is greater than another. XCTAssertGreaterThanOrEqual Asserts that the value of one expression is greater than or equal to another. XCTAssertLessThan Asserts that the value of one expression is less than another. XCTAssertLessThanOrEqual Asserts that the value of one expression is less than or equal to another.
XCTAssert Family in XCode 8.3.2 XCTAssert Family Description XCTAssertThrowsError Asserts that an expression throws an error. XCTAssertNoThrow Asserts that an expression does not throw an NSException.
XCTAssertEqual example
XCTAssertNotNil Example
XCTAssertThrowsError Example
Demo Write a Unit Testing class
XCTestExpectation ● Define an expectation with a meaningful description. ● Go on with the test setup and exercise phases, calling the asynchronous method and fulfilling the expectation at the end of the callback closure. ● Make the test runner wait for you expectation to be fulfilled, so that the asynchronous operations can be completed and you assertions verified.
XCTestExpectation Example
Fail Faster Example
Demo Test Asynchronous Operations
Asynchronous Tests Problem ● Most apps interact with system or library objects, but you don’t control these objects. ● Tests that interact with these objects can be slow and unrepeatable. ● The singletons made our class hard to test.
Dependency Injection
Dependency Injection ● Extract and Override ○ Create a testing subclass and override the testing method. ● Method Injection ○ Pass a dependency object during a method. ● Property Injection ○ An internal or public property can be modified or replaced. ● Constructor Injection ○ Pass a dependency object during the constructor.
Sync Lullaby with LullabyManager
Extract and Override Example - Create a Mock Class
Extract and Override Example - Verifying Lullaby List
Method Injection Example - Create a property that holds a reference
Method Injection Example - Dependency object can be replaced
Method Injection Example - Use a mock LullabyManager object
Property Injection Example - Create a internal or public property
Property Injection Example - Use a mock LullabyManager object
Constructor Injection Example - Default Constructor
Constructor Injection Example - Dependency object can be replaced
Constructor Injection Example - Use a mock LullabyManager object
Demo Dependency Injection
Test Doubles
Types of Test Doubles ● Stub ○ Fakes a response to method calls of an object. ● Mock ○ Let you check if a method call is performed or if a property is set.
Stub
Stub Example
Mock
Mock Example - Create a Mock Class
Mock Example
Demo Test Doubles
Reference ● About Testing with Xcode - Apple ● Unit Testing in Xcode 7 with Swift - AppCoda ● iOS Unit Testing and UI Testing Tutorial - RayWenderlich ● Test Doubles: Mocks, Stubs, and More - objc ● MCE 2014: Jon Reid - Test Driven Development for iOS ● Waiting in XCTest

Unit testing in xcode 8 with swift

  • 1.
    Unit Testing inXcode 8.3.2 with Swift3 Allan Shih
  • 2.
    Agenda ● What isUnit Testing? ● Unit Testing in Xcode ● Create a Unit Testing class ● Write a Unit Testing class ● Test Asynchronous Operations ● Faking Objects and Interactions ● Demo ● Reference
  • 3.
    What is UnitTesting? ● Unit testing, a testing technique using which individual modules are tested to determine if there are any issues by the developer himself. ● It is concerned with functional correctness of the standalone modules.
  • 4.
    Unit Testing -Advantages ● Reduces Defects in the Newly developed features ● Reduces bugs when changing the existing functionality. ● Reduces Cost of Testing as defects are captured in very early phase. ● Improves design and allows better refactoring of code. ● Unit Tests, when integrated with build gives the quality of the build as well.
  • 5.
    Unit Tests MainProperties ● Independent ○ Running a Unit Test should not affect another Unit Test run. Execution order is not important. ● Fast ○ A test which takes several seconds to run is not a Unit Test and probably needs a refactor. ● Isolated ○ Unit Test should not depend on external systems. They need to know their collaborators answers.
  • 6.
    Create a projectwith Unit Tests
  • 7.
    Creating a UnitTest Target in an existing project 1. Click the test navigator 2. Click the + button 3. Select “New Unit Test Target” 4. Create a Unit Test target
  • 8.
    Select a hostapplication
  • 9.
    Build Settings >Deployment > iOS Deployment Target
  • 10.
    Update CocoaPods ● Updatea Podfile, and add test target dependencies: ● Run $ pod update in project directory. ● Open App.xcworkspace and build. target 'ThingMakerMvc' do use_frameworks! pod 'Alamofire', '~> 4.3' target 'ThingMakerMvcTests' do inherit! :search_paths end end
  • 11.
    Create a UnitTest Case Class
  • 12.
  • 13.
  • 14.
    Run the testclass 1. ProductTest or Command-U. This actually runs all test classes. 2. Click the arrow button in the test navigator. 3. Click the diamond button in the gutter.
  • 15.
  • 16.
  • 17.
  • 18.
    Unit Test ClassStructure ● Class Setup/TearDown ○ Executed once when the Unit Test class is initialized, not for every test in the class. Useful to avoid test code duplication at class level. ● Test Setup/TearDown ○ Executed once before and after each executed Unit Test. Useful to avoid test code duplication at test level. ● Test Methods ○ The Unit Test implementation itself. Here is where the test run and validations happens.
  • 19.
  • 20.
    Test Setup /Tear Down Example @available(iOS 9.0, *) UIViewController.loadViewIfNeeded()
  • 21.
  • 22.
    Tests Naming ● Usedescriptive test names. It will provide quick feedback when test fails. ● Choose names which in few words says: ○ Method under testing ○ Condition under testing ○ Expected result / behavior
  • 23.
    Tests Naming Example ●Good examples ○ testSyncLullabyList_withLullabyManager_return3LullabyItems() ○ testSyncStationList_withIHeartRadioApi_return6StationItems() ● Bad examples ○ testExample1() ○ testExample2() ○ testExample3()
  • 24.
    Test Method Organization ●Arrange / Setup ○ Prepare all needed objects/dependencies for test execution. ● Act / Test ○ Test itself it performed, calling one specific method in the system under testing. ● Assert / Verify ○ Method result/behavior verification is performed at the end, using test asserts.
  • 25.
    Tests Verification Types ●Return Value / State Verification ○ Verify the result returned for the method under test, no matter which interactions with other objects has been made. Useful and preferred verification in most cases. ● Behavior Verification ○ Verify that all tested method interactions among other collaboration objects are the expected one (generally done using mocks). Useful for some cases where interactions are important (for example a cache implementation).
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
    XCTAssert Family inXCode 8.3.2 XCTAssert Family Description XCTAssert Asserts that an expression is true. XCTAssertTrue Asserts that an expression is true. XCTAssertFalse Asserts that an expression is false. XCTAssertNil Asserts that an expression is nil. XCTAssertNotNil Asserts that an expression is not nil. XCTAssertEqual Asserts that two expressions have the same value. XCTAssertEqualObjects Asserts that two objects are considered equal.
  • 35.
    XCTAssert Family inXCode 8.3.2 XCTAssert Family Description XCTAssertNotEqual Asserts that two expressions do not have the same value. XCTAssertNotEqualObjects Asserts that an expression is true. XCTAssertGreaterThan Asserts that the value of one expression is greater than another. XCTAssertGreaterThanOrEqual Asserts that the value of one expression is greater than or equal to another. XCTAssertLessThan Asserts that the value of one expression is less than another. XCTAssertLessThanOrEqual Asserts that the value of one expression is less than or equal to another.
  • 36.
    XCTAssert Family inXCode 8.3.2 XCTAssert Family Description XCTAssertThrowsError Asserts that an expression throws an error. XCTAssertNoThrow Asserts that an expression does not throw an NSException.
  • 37.
  • 38.
  • 39.
  • 40.
    Demo Write a UnitTesting class
  • 41.
    XCTestExpectation ● Define anexpectation with a meaningful description. ● Go on with the test setup and exercise phases, calling the asynchronous method and fulfilling the expectation at the end of the callback closure. ● Make the test runner wait for you expectation to be fulfilled, so that the asynchronous operations can be completed and you assertions verified.
  • 42.
  • 43.
  • 44.
  • 45.
    Asynchronous Tests Problem ●Most apps interact with system or library objects, but you don’t control these objects. ● Tests that interact with these objects can be slow and unrepeatable. ● The singletons made our class hard to test.
  • 46.
  • 47.
    Dependency Injection ● Extractand Override ○ Create a testing subclass and override the testing method. ● Method Injection ○ Pass a dependency object during a method. ● Property Injection ○ An internal or public property can be modified or replaced. ● Constructor Injection ○ Pass a dependency object during the constructor.
  • 48.
    Sync Lullaby withLullabyManager
  • 49.
    Extract and OverrideExample - Create a Mock Class
  • 50.
    Extract and OverrideExample - Verifying Lullaby List
  • 51.
    Method Injection Example- Create a property that holds a reference
  • 52.
    Method Injection Example- Dependency object can be replaced
  • 53.
    Method Injection Example- Use a mock LullabyManager object
  • 54.
    Property Injection Example- Create a internal or public property
  • 55.
    Property Injection Example- Use a mock LullabyManager object
  • 56.
    Constructor Injection Example- Default Constructor
  • 57.
    Constructor Injection Example- Dependency object can be replaced
  • 58.
    Constructor Injection Example- Use a mock LullabyManager object
  • 59.
  • 60.
  • 61.
    Types of TestDoubles ● Stub ○ Fakes a response to method calls of an object. ● Mock ○ Let you check if a method call is performed or if a property is set.
  • 62.
  • 63.
  • 64.
  • 65.
    Mock Example -Create a Mock Class
  • 66.
  • 67.
  • 68.
    Reference ● About Testingwith Xcode - Apple ● Unit Testing in Xcode 7 with Swift - AppCoda ● iOS Unit Testing and UI Testing Tutorial - RayWenderlich ● Test Doubles: Mocks, Stubs, and More - objc ● MCE 2014: Jon Reid - Test Driven Development for iOS ● Waiting in XCTest