Sleipnir presentation

Download Sleipnir presentation

Post on 19-Aug-2014

47 views

Category:

Engineering

0 download

DESCRIPTION

BDD testing in Swift with Sleipnir

TRANSCRIPT

  • Sleipnir BDD style testing for Swift
  • Who we are Mobile team at railsware.com Open source fans railsware.github.io/
  • Outline What is BDD Testing in Swift - XCTest vs BDD style What Sleipnir is How to use it Questions
  • BDD
  • BDD Behavior Driven Development
  • BDD Behavior Driven Development BDD species that tests of any unit of software should be specied in terms of the desired behaviour of the unit. (from Wiki) ! BDD is all about specications
  • BDD describe("Calculator") { ! describe("#add") { ! it("returns the sum of its arguments") { expect(Calculator().add(1, 2)).to(equal(3)) } } }
  • Testing in Swift
  • 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") } }
  • 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
  • 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")) } } } }
  • Testing in Swift - BDD Test code is a specication of a class: Person name should not be nil Person name should be correct
  • Introducing Sleipnir https://github.com/railsware/Sleipnir
  • What Sleipnir is Mythological steed of Odin, Norse God
  • What Sleipnir is BDD-style framework for Swift
  • 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() } } } }
  • Core principles Not using XCTest Pure Swift BDD testing framework Command line output Seeded random tests invocation
  • How to use it
  • Running specs 1. Create a test target in Xcode 2. Invoke Runner.run() method in main.swift 3. Run test target
  • Running specs Running With Random Seed: 7197 ! ...F...... ! ! FAILURE Some spec should pass: /Path/To/Your/Specs/SomeSpec.swift:27 Expected to equal ! ! Finished in 0.0102 seconds ! 10 examples, 1 failures
  • Setup/Teardown blocks beforeEach { } afterEach { } beforeAll { } afterAll { }
  • 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)) } }
  • Focused specs Focus means Run only focused stuff Useful in a project with a lot of specs
  • Focused specs describe("Some spec") { fit("focused") { // WILL RUN } it("not focused") { // WILL NOT RUN } }
  • Focused specs fdescribe("focused group") { // ... } ! fcontext("focused group") { // ... } fit("focused example") { // ... }
  • Pending specs Pending means Dont run this stuff Useful to denote an example that does not pass yet
  • 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
  • Shared example groups Useful for extracting common specs Allow to run same specs in different context
  • 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()) } }
  • 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))
  • Matchers on collections/strings contain beginWith/endWith beEmpty expect([1,2,3]).to(contain(1,2)) expect("foobar").to(beginWith("foo")) expect([1,2,3]).toNot(beEmpty())
  • Questions? https://github.com/railsware/Sleipnir