Testing without Xcode - CMD+U 2016

Testing without Xcode - CMD+U 2016

D200a17dd269fd4001bacb11662dab4b?s=128

Kyle Fuller

July 08, 2016
Tweet

Transcript

  1. 2.
  2. 3.
  3. 4.
  4. 5.
  5. 6.
  6. 7.
  7. 10.
  8. 11.
  9. 12.
  10. 13.

    Agenda • How other communities do testing • How testing

    is done in Swift today • How we can do testing in Swift in the future
  11. 15.

    Testing in Ruby describe '.authenticate' do context 'when logged in'

    do it { is_expected.to respond_with 200 } end end
  12. 16.

    Testing in Ruby $ rspec test.rb Finished in 0.0016 seconds

    (files took 0.2153 seconds to load) 5 examples, 0 failures
  13. 17.

    Testing in C / C++ int main(int argc, const char

    *argv[]) { user_t user = user_alloc("kyle"); // Test User's name assert(user.name == "kyle"); // Test User's priviledges assert(user.is_admin, 0); return 0; }
  14. 18.
  15. 19.

    Testing in C / C++ #define CATCH_CONFIG_MAIN #include "catch.hpp" TEST_CASE(

    "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); }
  16. 21.

    Testing in Swift • assert • XCTest • Quick (uses

    XCTest) • Spectre • Ploughman • Custom testing • CLI tool
  17. 23.
  18. 26.

    struct Person: CustomStringConvertible { let name: String var description: String

    { return name } } let kyle = Person(name: "Kyle") assert(kyle.description == "Kyle", "conforms to CustomStringConvertible")
  19. 29.
  20. 30.

    assert() testing Upsides • Extremely simple • Built into stdlib

    Downsides • Hard to manage • Crashes your process, not all tests are ran
  21. 31.
  22. 32.

    CompileSwift normal x86_64 /Users/kyle/Projects/QueryKit/QueryKit/Tests/SortDescriptorTests.swift cd /Users/kyle/Projects/QueryKit/QueryKit /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c /Users/kyle/Projects/QueryKit/QueryKit/Tests/AttributeTests.swift

    /Users/kyle/Projects/QueryKit/QueryKit/Tests/QueryKitTests.swift -primary-file /Users/kyle/Projects/QueryKit/QueryKit/Tests/SortDescriptorTests.swift ... Test Suite 'All tests' started at 2016-07-08 01:59:05.062 Test Suite 'QueryKitTests.xctest' started at 2016-07-08 01:59:05.063 Test Suite 'AttributeTests' started at 2016-07-08 01:59:05.063 Test Case '-[QueryKitTests.AttributeTests testAscendingSortDescriptor]' started. Test Case '-[QueryKitTests.AttributeTests testAscendingSortDescriptor]' passed (0.002 seconds). Test Case '-[QueryKitTests.AttributeTests testAttributeExpression]' started. Test Case '-[QueryKitTests.AttributeTests testAttributeExpression]' passed (0.001 seconds). Test Suite 'SortDescriptorTests' passed at 2016-07-08 01:59:05.362. Executed 2 tests, with 0 failures (0 unexpected) in 0.001 (0.003) seconds Test Suite 'QueryKitTests.xctest' passed at 2016-07-08 01:59:05.363. Executed 75 tests, with 0 failures (0 unexpected) in 0.240 (0.300) seconds Test Suite 'All tests' passed at 2016-07-08 01:59:05.364. Executed 75 tests, with 0 failures (0 unexpected) in 0.240 (0.302) seconds ** TEST SUCCEEDED **
  23. 35.
  24. 36.

    Test Anywhere Protocol (TAP) ... ok 71 - testTypeSafeOrderBySortDescriptor ok

    72 - testTypeSafeOrderBySortDescriptors ok 73 - testTypeSafeRelatedFilterPredicate ok 74 - testAscendingSortDescriptor ok 75 - testDescendingSortDescriptor 1..75
  25. 37.
  26. 38.

    How does XCTest work? $ xcrun -sdk macosx xctest Usage:

    xctest <path of unit to be tested>
  27. 39.

    import XCTest class PersonTests : XCTestCase { func testCustomStringConvertible() {

    let kyle = Person(name: "Kyle") XCTAssertEqual(kyle.description, "Kyle") } }
  28. 40.

    How does XCTest work without Objective-C? import XCTest extension PersonTests

    { static var allTests : [(String, PersonTests -> () throws -> Void)] { return [ ("testCustomStringConvertible", testCustomStringConvertible), ] } } XCTMain([ testCase(PersonTests.allTests), ])
  29. 41.
  30. 47.
  31. 48.
  32. 49.
  33. 52.
  34. 53.
  35. 57.

    import Quick import Nimble class TableOfContentsSpec: QuickSpec { override func

    spec() { describe("the 'Documentation' directory") { it("has everything you need to get started") { let sections = Directory("Documentation").sections expect(sections).to(contain("Installing Quick")) } } } }
  36. 58.
  37. 59.

    Feature: An array Scenario: Appending to an array Given I

    have an empty array When I add 1 to the array Then I should have 1 item in the array Scenario: Filtering an array Given I have an array with the numbers 1 through 5 When I filter the array for even numbers Then I should have 2 items in the array
  38. 61.

    Given I have an empty array var array: [Int]? =

    nil given("^I have an empty array$") { _ in array = [] }
  39. 62.

    When I add X to the array when("^I add (\\d)

    to the array$") { match in let number = Int(match.groups[1])! array.append(number) }
  40. 63.

    Then I should have X items in the array then("^I

    should have (\\d) items? in the array$") { match in let count = Int(match.groups[1])! try expect(array.count) == count }
  41. 66.

    Feature: Basic Nest compliance Scenario: Success response status code When

    I make a GET request to /hello Then I should have a 200 response Scenario: Response header When I make a GET request to /hello Then I should see the header 'Content-Type' with the value 'text/plain' Scenario: Response body When I make a GET request to /hello Then The contents of the body should be 'Hello World' Scenario: Response body (POST) When I make a POST request with body 'Swift' to /hello Then The contents of the body should be 'Hello Swift'
  42. 67.

    $ NestTestSuite --host http://localhost:8080 Features/*.feature -> Basic Nest compliance ->

    Performing a simple GET request 1 scenarios passed, 0 scenarios failed.
  43. 69.
  44. 70.

    DIY $ swiftc Sources/*.swift -module-name Hello -emit-library -emit-module -o Hello.dylib

    $ swiftc Tests/*.swift -lHello -o run-tests $ ./run-tests
  45. 71.

    DIY - Make (Makefile) Hello.dylib: swiftc Sources/*.swift -module-name Hello -emit-library

    -emit-module -o Hello.dylib run-tests: Hello.dylib swiftc Tests/*.swift -lHello -o run-tests .PHONY: test test: run-tests ./run-tests
  46. 74.

    import PackageDescription let package = Package( name: "Curassow", dependencies: [

    .Package(url: "https://github.com/kylef/Commander.git", majorVersion: 0, minor: 4), ] )
  47. 76.

    import PackageDescription let package = Package( name: "Curassow", testDependencies: [

    .Package(url: "https://github.com/kylef/Spectre.git", majorVersion: 0, minor: 7), ] )
  48. 78.

    LinuxMain.swift import XCTest extension PersonTests { static var allTests :

    [(String, PersonTests -> () throws -> Void)] { return [ ("testCustomStringConvertible", testCustomStringConvertible), ] } } XCTMain([ testCase(PersonTests.allTests), ])
  49. 81.

    swim Goals • swim is compatible with multiple versions of

    Swift (2.x, 3.x, etc) • swim allows you to test your Swift project with third-party testing frameworks. • swim is compatible with common Swift Package Manager libraries. • swim is easy to install (does not depend on Swift)
  50. 83.

    Package.swift let package = Package( name: "Stencil", testDependencies: [ .Package(url:

    "https://github.com/kylef/Spectre", majorVersion: 0), ] ) Terminal $ swim build $ swim test
  51. 88.

    $ swift --version Apple Swift version 2.2.1 $ cd Stencil

    $ swift --version Apple Swift version 3.0-dev
  52. 92.

    $ env SWIFT_VERSION=2.2 swift test --clean $ env SWIFT_VERSION=2.3 swift

    test --clean $ env SWIFT_VERSION=3.0 swift test --clean
  53. 94.

    os: - linux - osx install: - eval "$(curl -sL

    https://github.com/kylef/.../swiftenv-install.sh)"
  54. 97.

    • Early stages for testing OSS Swift • New tools

    are emerging • Swift Package Manager is evolving • Test against all platforms