DEV Community

Khoa Pham
Khoa Pham

Posted on • Updated on

Given When Then in Swift tests

Spec

Using spec testing framework like Quick is nice, which enables BDD style.

describe("the 'Documentation' directory") {
  it("has everything you need to get started") {
    let sections = Directory("Documentation").sections
    expect(sections).to(contain("Organized Tests with Quick Examples and Example Groups"))
    expect(sections).to(contain("Installing Quick"))
  }

  context("if it doesn't have what you're looking for") {
    it("needs to be updated") {
      let you = You(awesome: true)
      expect{you.submittedAnIssue}.toEventually(beTruthy())
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

But in case you don't want additional frameworks, and want to live closer to Apple SDKs as much as possible, here are few tips.

Naming

This is from the book that I really like The Art of Unit Testing. If you don't mind the underscore, you can follow UnitOfWork_StateUnderTest_ExpectedBehavior structure

func testSum_NegativeNumberAs1stParam_ExceptionThrown()
func testSum_NegativeNumberAs2ndParam_ExceptionThrown()
func testSum_simpleValues_Calculated()
Enter fullscreen mode Exit fullscreen mode

Given When Then

This is from BDD, and practised a lot in Cucumber. You can read more on https://martinfowler.com/bliki/GivenWhenThen.html.

First, add some more extensions to XCTestCase

import XCTest

extension XCTestCase {
  func given(_ description: String, closure: () throws -> Void) throws {
    try closure()
  }

  func when(_ description: String, closure: () throws -> Void) throws {
    try closure()
  }

  func then(_ description: String, closure: () throws -> Void) throws {
    try closure()
  }
}

Enter fullscreen mode Exit fullscreen mode

Then, in order to test, just follow given when then

func testRemoveObject() throws {
  try given("set to storage") {
    try storage.setObject(testObject, forKey: key)
  }

  try when("remove object from storage") {
    try storage.removeObject(forKey: key)
  }

  try then("there is no object in memory") {
    let memoryObject = try? storage.memoryCache.object(forKey: key) as User
    XCTAssertNil(memoryObject)
  }

  try then("there is no object on disk") {
    let diskObject = try? storage.diskCache.object(forKey: key) as User
    XCTAssertNil(diskObject)
  }
}
Enter fullscreen mode Exit fullscreen mode

I find this more interesting than comments. All are code and descriptive. It can also be developed further to throw the description text.

❤️ Support my apps ❤️

❤️❤️😇😍🤘❤️❤️

Top comments (0)