Quick & Nimble

Hero image for Quick & Nimble

Reference Resources

Formatting

  • Test Class should be named as ClassToBeTestedSpec.

For example, we are going to test SignInPresenter.swift.

import Quick
import Nimble

@testable import ExampleModule

final class SignInPresenterSpec: QuickSpec {}
  • Use a single top-level describe block in spec() to tell which class we will test.
final class SignInPresenterSpec: QuickSpec {

    override func spec() {
        describe("a SignInPresenter") {
        }
    }
}
  • Use context to describe a test case. The description of a context should always start with when or given, and be in the form of a grammatically correct sentence.
// Bad
context("submitOTP is successfully called") {
    beforeEach {}
 
    it() {}
}

// Good
context("when submitOTP is successfully called") {
    beforeEach {} 

    it() {}
}
  • Add a line break between contexts.
// Bad
context("when submitOTP is successfully called") {
}
context("when submitOTP is unsuccessfully called") {
}

// Good
context("when submitOTP is successfully called") {
}

context("when submitOTP is unsuccessfully called") {
}

Assertion

  • Add a line break between the first it and other functions
// Bad
context("when submitOTP is successfully called") {
    beforeEach{}
    it("hides keyboard and submit otp") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }
}

// Good
context("when submitOTP is successfully called") {
    beforeEach {} 

    it("hides keyboard") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }
}
  • Only one expect per a single it block.
// Bad
context("when submitOTP is successfully called") {
    beforeEach{}

    it("hides keyboard and submit otp") {
        expect(view.hideKeyboardCalled).to(beTrue())
        expect(interactor.submitOTPWithCalled).to(beTrue())
    }
}

// Good
context("when submitOTP is successfully called") {
    beforeEach {} 

    it("hides keyboard") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }

    it("submits OTP") {
        expect(interactor.submitOTPWithCalled).to(beTrue())
    }
}
  • Add a line break between assertions.
// Bad
context("when submitOTP is successfully called") {
    beforeEach {}
    
    it("hides keyboard") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }
    it("submits OTP") {
        expect(interactor.submitOTPWithCalled).to(beTrue())
    }
}

// Good
context("when submitOTP is successfully called") {
    beforeEach {} 

    it("hides keyboard") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }

    it("submits OTP") {
        expect(interactor.submitOTPWithCalled).to(beTrue())
    }
}

Temporarily disable or focus on an assertion or group

Temporarily disable single or a few cases

To temporarily disable assertion it or even a group like context and describe, simply put x as a prefix of that keyword such as: xit xcontext, xdescribe, etc.

// code in this closure won't run
xdescribe("a SignInPresenter") {
    // some action
}

// code in this closure won't run
xcontext("when submitOTP is successfully called") {
    // some action
}

// code in below closure won't run
xit("hides keyboard") { 
    // some actions
}

context("when submitOTP is successfully called") {
    beforeEach {} 

    it("hides keyboard") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }

    // code in this closure won't run
    xit("submits OTP") {
        // some actions
    }
}

Temporarily focus on single or a few cases

When you need to run only one or a few test cases, it is unnecessary to rerun the whole test suite as that is really time-consuming. You can just run these specific tests by putting f before it, context, describe.

// code in this closure won't run
context("when submitOTP is successfully called") {
    // some actions
}

context("when submitOTP is successfully called") {
    beforeEach {} 

    // code in this closure won't run
    it("hides keyboard") {
        // some actions
    }

    // and only code in this closure will run
    fit("hides keyboard") {
        expect(view.hideKeyboardCalled).to(beTrue())
    }
}