Quick & Nimble

Hero image for Quick & Nimble

Formatting

  • Test Class should be named as ClassToBeTestedSpec.

    For example, 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 will be tested.

    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.

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

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

Assertion

  • Add a line break between the first it and other functions

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

    context("when submitOTP is successfully called") {
        beforeEach{}
    
        it("hides keyboard and submit otp") {
            expect(view.hideKeyboardCalled).to(beTrue())
            expect(interactor.submitOTPWithCalled).to(beTrue())
        }
    }
    
    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.

    context("when submitOTP is successfully called") {
        beforeEach {}
          
        it("hides keyboard") {
            expect(view.hideKeyboardCalled).to(beTrue())
        }
        it("submits OTP") {
            expect(interactor.submitOTPWithCalled).to(beTrue())
        }
    }
    
    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

To run only one or a few test cases, it is unnecessary to rerun the whole test suite as that is really time-consuming. To just run these specific tests, put 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())
    }
}

Reference Resources