Swiftにおける本当にRSpecライクなテストの書き方 / RSpec-like Test in Swift

070d33664df274636dad3da21c9b21fc?s=47 rockname
December 10, 2018

Swiftにおける本当にRSpecライクなテストの書き方 / RSpec-like Test in Swift

070d33664df274636dad3da21c9b21fc?s=128

rockname

December 10, 2018
Tweet

Transcript

  1. 5.

    iOSͷςετ؀ڥ • ςετϑϨʔϜϫʔΫͱͯ͠ Quick/Nimble Λ࠾༻ • RSpecʹΠϯεύΠΞ͞ΕͨBDD Framework • ΈͯͶ͸ServerͷςετΛRSpecͰॻ͍͍ͯΔͷͰ׳Ε͍ͯΔਓ͕ؒ

    ଟ͍ • Mock͸… • ಛʹϥΠϒϥϦ͸࢖͍ͬͯͳ͍ (Φεεϝ͕͋Ε͹ڭ͍͑ͯͩ͘͞) • Mock ObjectΛςετ͝ͱʹఆ͍ٛͯ͠Δ
  2. 10.

    FizzBuzzؔ਺ͷςετΛॻ͘ • Ҿ਺ʹIntΛऔΓɺ • 3ͷഒ਺ͷ࣌ -> “Fizz” • 5ͷഒ਺ͷ࣌ ->

    “Buzz” • 3ͱ5ͷެഒ਺ͷ࣌ -> “FizzBuzz” • 0ҎԼͷ࣌ -> “out of range” • ͦΕҎ֎ͷ࣌ -> ༩͑ΒΕͨ਺ࣈΛͦͷ··ฦ͢
  3. 11.

    FizzBuzzؔ਺ enum FizzBuzz { static func fizzBuzz(_ number: Int) ->

    String { guard number > 0 else { return "out of range” } switch number { case let n where n % 15 == 0: return "FizzBuzz" case let n where n % 5 == 0: return "Buzz" case let n where n % 3 == 0: return "Fizz" default: return String(number) } } }
  4. 13.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } }
  5. 14.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } ςετର৅ͷϝιου
  6. 15.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } ظ଴͞ΕΔϝιουͷ;Δ·͍
  7. 16.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } 3ͷഒ਺ͷ࣌ -> “Fizz”
  8. 17.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } 5ͷഒ਺ͷ࣌ -> “Buzz”
  9. 18.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } 3ͱ5ͷެഒ਺ͷ࣌ -> “FizzBuzz”
  10. 19.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } 0ҎԼͷ࣌ -> ”out of range”
  11. 20.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } ͦΕҎ֎ͷ࣌ -> ༩͑ΒΕͨ਺ࣈ
  12. 21.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } }
  13. 22.

    ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } } ύοͱݟͯ΋ϝιουͷৼΔ෣͍͕ ཧղ͠ʹ͍͘
  14. 28.

    ୯Ұ৚݅ςετ describe("#fizzBuzz") { it("should return Fizz when given multiples of

    3") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } it("should return Buzz when given multiples of 5") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } it("should return FizzBuzz when given multiples of both 3 and 5") { expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) } ɾ ɾ ɾ
  15. 29.

    ୯Ұ৚݅ςετ describe("#fizzBuzz") { it("should return Fizz when given multiples of

    3") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } it("should return Buzz when given multiples of 5") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } it("should return FizzBuzz when given multiples of both 3 and 5") { expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) } ɾ ɾ ɾ 3ͷഒ਺ͷ࣌ -> “Fizz”
  16. 30.

    ୯Ұ৚݅ςετ describe("#fizzBuzz") { it("should return Fizz when given multiples of

    3") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } it("should return Buzz when given multiples of 5") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } it("should return FizzBuzz when given multiples of both 3 and 5") { expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) } ɾ ɾ ɾ 5ͷഒ਺ͷ࣌ -> “Buzz”
  17. 31.

    ୯Ұ৚݅ςετ describe("#fizzBuzz") { it("should return Fizz when given multiples of

    3") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } it("should return Buzz when given multiples of 5") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } it("should return FizzBuzz when given multiples of both 3 and 5") { expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) } ɾ ɾ ɾ 3ͱ5ͷެഒ਺ͷ࣌ -> “FizzBuzz”
  18. 36.

    ContextΛ࢖͏ describe("#fizzBuzz") { context("when given multiples of 3") { it("should

    return Fizz") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } } context("when given multiples of 5") { it("should return Buzz") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } } ɾ ɾ ɾ
  19. 37.

    ContextΛ࢖͏ describe("#fizzBuzz") { context("when given multiples of 3") { it("should

    return Fizz") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } } context("when given multiples of 5") { it("should return Buzz") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } } ɾ ɾ ɾ 3ͷഒ਺ͷ࣌ -> “Fizz”
  20. 38.

    ContextΛ࢖͏ describe("#fizzBuzz") { context("when given multiples of 3") { it("should

    return Fizz") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) } } context("when given multiples of 5") { it("should return Buzz") { expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) } } ɾ ɾ ɾ 5ͷഒ਺ͷ࣌ -> “Buzz”
  21. 44.

    SubjectΛ࢖͏ describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ
  22. 45.

    SubjectΛ࢖͏ describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ Ҿ਺Λม਺ͱͯ͠ఆٛ subjectΛܭࢉܕϓϩύςΟͱͯ͠એݴ
  23. 46.

    SubjectΛ࢖͏ describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ beforeEach ͰcontextʹԠͨ͡
 ஋Λnumberม਺ʹ୅ೖ
  24. 47.

    SubjectΛ࢖͏ describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ ɹexpectʹ͸subjectͷΈ౉͢
  25. 48.

    SubjectΛ࢖͏ describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ
  26. 50.

    Before class FizzBuzzSpec: QuickSpec { override func spec() { describe("#fizzBuzz")

    { it("should meet all FizzBuzz specifications") { expect(FizzBuzz.fizzBuzz(3)).to(equal("Fizz")) expect(FizzBuzz.fizzBuzz(5)).to(equal("Buzz")) expect(FizzBuzz.fizzBuzz(15)).to(equal("FizzBuzz")) expect(FizzBuzz.fizzBuzz(-1)) .to(equal(“out of range")) expect(FizzBuzz.fizzBuzz(1)).to(equal("1")) } } } }
  27. 51.

    After describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ
  28. 52.

    After describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ Կ͕ (What)
  29. 53.

    After describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ Կ͕ (What) ͍ͭ (When)
  30. 54.

    After describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ ͍ͭ (When) Կ͕ (What) Ͳ͏ͳΔͷ͔ (How)
  31. 55.

    After describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ ͍ͭ (When) Կ͕ (What) Ͳ͏ͳΔͷ͔ (How)
  32. 56.

    After describe("#fizzBuzz") { var number: Int! var subject: String {

    return FizzBuzz.fizzBuzz(number) } context("when given multiples of 3") { beforeEach { number = 3 } it("should return Fizz") { expect(subject).to(equal("Fizz")) } } ɾ ɾ ɾ ͍ͭ (When) Կ͕ (What) Ͳ͏ͳΔͷ͔ (How)
  33. 57.

    ·ͱΊ • Quick͸RSpecʹΠϯεύΠΞ͞ΕͨBDD Framework • BetterSpecsʹͳΒͬͯॻ͘͜ͱͰɺͦͷϝιουͷ࢓༷͕ཧղ͠ ΍͘͢ͳΔςετΛॻ͚Δ (Spec = Specification

    = ࢓༷ॻ) • ͨͩɺ޷͖ݏ͍͸ඞͣ͋ΔͷͰڧ੍͸ྑ͘ͳ͍ 
 (XCTestͰ΋What/When/HowΛҙࣝͨ͠ςετ͸ॻ͚Δ)