Top Banner
Sleipnir BDD style testing for Swift
32

Sleipnir presentation

Aug 19, 2014

Download

Engineering

atermenji

BDD testing in Swift with Sleipnir
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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