Unit testing is used to verify that a single unit of work is behaving as expected. We use XCTest to write unit tests.
Example:
func testAddition() {
let simpleAddition = "5 + 5"
let negativeAddition = "2 + -8"
let doubleNegative = "-7 + -3"
XCTAssertEqual(calculator.evaluate(simpleAddition), 10)
XCTAssertEqual(calculator.evaluate(negativeAddition), -6)
XCTAssertEqual(calculator.evaluate(doubleNegative), -10)
}
Unit testing the default behavior of the Codable
protocol is unnecessary. Only implement unit tests when overriding the default implementation of encode(to: Encoder)
or init(from: Decoder)
. One common occurrence of this is when testing the decoding or encoding of date information from an API. In such cases, you should write unit tests to verify that the Codable
implementation has been written successfully.
UI testing is used to ensure that the interface that is displayed to the user is the one that is expected to be displayed. We use Xcode UI Testing to write UI tests.
Example:
func testEmptyState() {
let emptyStateLabel = app.staticTexts["You don't have any games yet!"]
XCTAssertTrue(emptyStateLabel.exists)
let addAGameButton = app.buttons["Add a game"]
XCTAssertTrue(addAGameButton.exists)
addAGameButton.tap()
waitForExpectations(timeout: 2.0, handler: nil)
let createAGameLabel = app.staticTexts["Create a game"]
XCTAssertTrue(createAGameLabel.exists)
}
Integration testing is used to verify work between multiple entities. Instead of mocking or stubbing dependencies of objects we create, we allow the actual implementations of dependencies to interact with the object that we're testing. This allows us to verify that our objects work together as we expect, and provides an additional layer of confidence on top of unit testing.
Contract testing is used to verify that an API outside of your direct control is behaving as expected. This is often used to verify that information being sent from a server, matches a specification that your application expects. These tests usually require network connections, as you're verifying that the actual environment you're communicating with is behaving properly.
Blackbox testing is performed from the perspective of a user of the application, to verify that functionality the user expects to work does, in fact, work. Always perform blackbox testing on an actual device, to match the environment a user would experience as close as possible.