Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BDD style testing for Swift with Sleipnir

Railsware
August 14, 2014

BDD style testing for Swift with Sleipnir

Railsware

August 14, 2014
Tweet

More Decks by Railsware

Other Decks in Programming

Transcript

  1. Who we are • Mobile team at railsware.com • Open

    source fans railsware.github.io/
  2. Outline • What is BDD • Testing in Swift -

    XCTest vs BDD style • What Sleipnir is • How to use it • Questions
  3. BDD

  4. BDD Behavior Driven Development • BDD specifies that tests of

    any unit of software should be specified in terms of the desired behaviour of the unit. (from Wiki) ! • BDD is all about specifications
  5. BDD describe("Calculator") { ! describe("#add") { ! it("returns the sum

    of its arguments") { expect(Calculator().add(1, 2)).to(equal(3)) } } }
  6. Testing in Swift - XCTest class BookTest : XCTestCase {

    func testPersonHasName() { let person = Person(name: "John Doe”) ! XCTAssertNotNil(person.name, "name should not be nil") XCTAssertEqual(person.name, "John Doe", "incorrect name") } }
  7. Testing in Swift - XCTest class BookTest : XCTestCase {

    func testPersonHasName() { let person = Person(name: "John Doe”) ! XCTAssertNotNil(person.name, "name should not be nil") XCTAssertEqual(person.name, "John Doe", "incorrect name") } } Does not specify behavior of the `Person` class
  8. Testing in Swift - BDD class PersonSpec : SleipnirSpec {

    var personSpec = describe("Person") { let person = Person(name: "John Doe") context("name") { it("should not be nil") { expect(person.name).toNot(beNil()) } it("should be correct") { expect(person.name).to(equal("John Doe")) } } } }
  9. Testing in Swift - BDD Test code is a specification

    of a class: • Person name should not be nil • Person name should be correct
  10. What Sleipnir is class HorseSpec : SleipnirSpec { var spec

    = describe("Horse") { context("usual") { it("is not awesome") { let usualHorse = UsualHorse() expect(usualHorse.legsCount).to(equal(4)) usualHorse.isAwesome.should.beFalse() } } context("Sleipnir") { it("is awesome") { let sleipnirHorse = Sleipnir() expect(sleipnirHorse.legsCount).to(equal(8)) sleipnirHorse.isAwesome.should.beTrue() } } } }
  11. Core principles • Not using XCTest • Pure Swift BDD

    testing framework • Command line output • Seeded random tests invocation
  12. Running specs 1. Create a test target in Xcode 2.

    Invoke Runner.run() method in main.swift 3. Run test target
  13. Running specs Running With Random Seed: 7197 ! ...F...... !

    ! FAILURE Some spec should pass: /Path/To/Your/Specs/SomeSpec.swift:27 Expected <1> to equal <3> ! ! Finished in 0.0102 seconds ! 10 examples, 1 failures
  14. Setup/Teardown blocks let someSpec = describe("Some spec") { var someArray:

    [Int]? ! beforeEach { someArray = [1, 2, 3] } afterEach { someArray = nil } it("should pass") { expect(someArray).toNot(beNil()) expect(someArray).to(contain(3)) } }
  15. Focused specs describe("Some spec") { fit("focused") { // WILL RUN

    } it("not focused") { // WILL NOT RUN } }
  16. Focused specs fdescribe("focused group") { // ... } ! fcontext("focused

    group") { // ... } fit("focused example") { // ... }
  17. Pending specs xdescribe("Pending group") { it("will not run") { expect(false).to(beTrue())

    } it("is pending", PENDING) } Running With Random Seed: 2428 ! ...P....... ! PENDING Pending group is pending ! ! Finished in 0.0062 seconds ! 11 examples, 0 failures, 1 pending
  18. Shared example groups sharedExamplesFor("some awesome stuff") { (sharedContext : SharedContext)

    in var stuff: Stuff? beforeEach { stuff = sharedContext()["stuff"] as Stuff } it("should be awesome") { expect(stuff.awesome).to(beTrue()) } }
  19. Matchers • equal • beNil • beFalse/beTrue • beGreaterThan/beLessThan expect(3).to(equal(3))

    expect(3).toNot(beNil()) expect(true).to(beTrue()) expect(3).to(beGreaterThan(1))