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

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

rockname
December 10, 2018

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

rockname

December 10, 2018
Tweet

More Decks by rockname

Other Decks in Programming

Transcript

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

    ଟ͍ • Mock͸… • ಛʹϥΠϒϥϦ͸࢖͍ͬͯͳ͍ (Φεεϝ͕͋Ε͹ڭ͍͑ͯͩ͘͞) • Mock ObjectΛςετ͝ͱʹఆ͍ٛͯ͠Δ
  2. FizzBuzzؔ਺ͷςετΛॻ͘ • Ҿ਺ʹIntΛऔΓɺ • 3ͷഒ਺ͷ࣌ -> “Fizz” • 5ͷഒ਺ͷ࣌ ->

    “Buzz” • 3ͱ5ͷެഒ਺ͷ࣌ -> “FizzBuzz” • 0ҎԼͷ࣌ -> “out of range” • ͦΕҎ֎ͷ࣌ -> ༩͑ΒΕͨ਺ࣈΛͦͷ··ฦ͢
  3. 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ͳʹ΋ߟ͑ͣʹॻ͍ͨςετ 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. ୯Ұ৚݅ςετ 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. ୯Ұ৚݅ςετ 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. ୯Ұ৚݅ςετ 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. ୯Ұ৚݅ςετ 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. ·ͱΊ • Quick͸RSpecʹΠϯεύΠΞ͞ΕͨBDD Framework • BetterSpecsʹͳΒͬͯॻ͘͜ͱͰɺͦͷϝιουͷ࢓༷͕ཧղ͠ ΍͘͢ͳΔςετΛॻ͚Δ (Spec = Specification

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