sleipnir presentation

32
Sleipnir BDD style testing for Swift

Upload: atermenji

Post on 19-Aug-2014

200 views

Category:

Engineering


0 download

DESCRIPTION

BDD testing in Swift with Sleipnir

TRANSCRIPT

Page 1: Sleipnir presentation

SleipnirBDD style testing for Swift

Page 2: Sleipnir presentation

Who we are• Mobile team at railsware.com

• Open source fans railsware.github.io/

Page 3: Sleipnir presentation

Outline• What is BDD

• Testing in Swift - XCTest vs BDD style

• What Sleipnir is

• How to use it

• Questions

Page 4: Sleipnir presentation

BDD

Page 5: Sleipnir presentation

BDDBehavior Driven Development

Page 6: Sleipnir presentation

BDDBehavior 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

Page 7: Sleipnir presentation

BDDdescribe("Calculator") { ! describe("#add") { ! it("returns the sum of its arguments") { expect(Calculator().add(1, 2)).to(equal(3)) } } }

Page 8: Sleipnir presentation

Testing in Swift

Page 9: Sleipnir presentation

Testing in Swift - XCTestclass 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") } }

Page 10: Sleipnir presentation

Testing in Swift - XCTestclass 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

Page 11: Sleipnir presentation

Testing in Swift - BDDclass 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")) } } } }

Page 12: Sleipnir presentation

Testing in Swift - BDD

Test code is a specification of a class:

• Person name should not be nil

• Person name should be correct

Page 13: Sleipnir presentation

Introducing Sleipnirhttps://github.com/railsware/Sleipnir

Page 14: Sleipnir presentation

What Sleipnir isMythological steed of Odin, Norse God

Page 15: Sleipnir presentation

What Sleipnir isBDD-style framework for Swift

Page 16: Sleipnir presentation

What Sleipnir isclass 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() } } } }

Page 17: Sleipnir presentation

Core principles• Not using XCTest

• Pure Swift BDD testing framework

• Command line output

• Seeded random tests invocation

Page 18: Sleipnir presentation

How to use it

Page 19: Sleipnir presentation

Running specs

1. Create a test target in Xcode

2. Invoke Runner.run() method in main.swift

3. Run test target

Page 20: Sleipnir presentation

Running specsRunning 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

Page 21: Sleipnir presentation

Setup/Teardown blocks

• beforeEach { }

• afterEach { }

• beforeAll { }

• afterAll { }

Page 22: Sleipnir presentation

Setup/Teardown blockslet 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)) } }

Page 23: Sleipnir presentation

Focused specs

Focus means “Run only focused stuff”

Useful in a project with a lot of specs

Page 24: Sleipnir presentation

Focused specsdescribe("Some spec") { fit("focused") { // WILL RUN } it("not focused") { // WILL NOT RUN } }

Page 25: Sleipnir presentation

Focused specsfdescribe("focused group") { // ... } !fcontext("focused group") { // ... } fit("focused example") { // ... }

Page 26: Sleipnir presentation

Pending specs

Pending means “Don’t run this stuff”

Useful to denote an example that does not pass yet

Page 27: Sleipnir presentation

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

Page 28: Sleipnir presentation

Shared example groups

Useful for extracting common specs

Allow to run same specs in different context

Page 29: Sleipnir presentation

Shared example groupssharedExamplesFor("some awesome stuff") { (sharedContext : SharedContext) in var stuff: Stuff? beforeEach { stuff = sharedContext()["stuff"] as Stuff } it("should be awesome") { expect(stuff.awesome).to(beTrue()) } }

Page 30: Sleipnir presentation

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))

Page 31: Sleipnir presentation

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())

Page 32: Sleipnir presentation

Questions?https://github.com/railsware/Sleipnir