Quick & Nimble
Reference Resources
- Quick Official Documentation
- Nimble Official Documentation
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 inspec()
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 acontext
should always start withwhen
orgiven
, 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 singleit
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())
}
}