Test

Test

Test Pattern

Unit Test

Every unit test follows this general pattern:

  1. setup some object under test
  2. provide the object under test some input
  3. make assertions on the objects outputs

Skip Tests

You can append skip to the test_function_name in order for Xcode compiler | runtime service to skip those tests in order to be ran and not wasted with that resources accordingly.

Really handy when you're working with flaky tests

Also adding test repetitions for flaky tests in swift.
avanderlee | Flaky tests resolving using Test Repetitions in Xcode

Conditional Skip Testing

You could utilize the various ways to skip testing if certain conditions have been met.

guard let envValue = ProcessInfo.processInfo.environment["IS_CI_SERVER"] else { return }
try XCTSkipIf(envValue == "true")

You could embed this code in Test life cycle methods which is present for setting up code / environment before running the main test case.

  • func setUp() { }
  • func setUpWithError() throws { }

The setUpWithError is the right candidate for skipping tests without adding that skip_logic for every unit tests. You can just include that information in the Test_Class file.
Clean and less verbose.

SO | skip-multi-tests-in-xcode

skipping-tests-in-xcode

setUp

class PPVSSLoaderDelegateTests: XCTestCase {
	var mockVSSDelegate: MockVSSDelegate!

	override func setUp()  {
      mockVSSDelegate = MockVSSDelegate()
    }
}

Teardown

class PPVSSLoaderDelegateTests: XCTestCase {
	var mockVSSDelegate: MockVSSDelegate!

	override func tearDown()  {
      mockVSSDelegate.reset()
    }
}

Warnings

Errors thrown from here are not handled - this appears when you're trying to call a function which can throw an error. Swift needs to either do a try catch to handle the thrown error or mark the test function with throws

func test_whenSomething_ThenBehavior() throws {
	let unwrappedDate = try callUnwrappingFunction() // Warning
}

Unwrapping while Testing

We should be careful to use force unwrapping when handling optionals in tests. if for some reason it's nil the tests are going to crash. that's not a super big deal when running locally but if that happens when running in CI it's going to force a restart of the tests and not give us much to go on as to why the crash occurred. better to treat this case as a test failure rather than crashing so that the tests report the failure and then continue - Test guru - mentor

func test_objectCreation_UsingJSONMapping() {
	let object: ObjectType = getMappedObject(for: TestJSON.Object)!
}

Solution

func test_objectCreation_UsingJSONMapping() throws {
	let object: ObjectType = try XCTUnwrap(getMappedObject(for: TestJSON.Object))
}

Testable

In order to access internal classes to our unit / ui test target, we can utilize the following keyword testable in order to gain elevated access to its internal implementation.

@testable import MainAppModuleName

Note:

  • We still can't access private functions or variables with this.
  • You can resort to private(set) for the properties to make tests which can be just read for unit testing.

how-to-unit-test-private-methods-in-swift

Mirror | Reflection

Reflection is a common programming language feature that enables us to inspect, and work with, the members of a type — dynamically, at runtime.

avanderlee | reflection how mirror works

swiftbysundell | reflection

wiki | reflective programming

// Foo class.
@interface Foo : NSObject
- (void)hello;
@end

// Sending "hello" to a Foo instance without reflection.
Foo *obj = [[Foo alloc] init];
[obj hello];

// Sending "hello" to a Foo instance with reflection.
id obj = [[NSClassFromString(@"Foo") alloc] init];
[obj performSelector: @selector(hello)];

Assertions

– assert()
– precondition()
– assertionFailure()
– preconditionFailure()
– fatalError()

assert(10 > 5, "10 is not less than 5")

swift assertions

Swift by sundell | picking-the-right-way-of-failing-in-swift

Simulators vs emulators

testing-on-real-devices-vs-simulators-vs-emulators

CI / CD

fastlane | run tests

speed-up-ios-ci-using-test-without-building-xctestrun-and-fastlane

Errors

wwdc 20 notes

apple dev | xcTest

apple dev | xcTest setup with error

xctest-setup-and-teardown-are-not-dead-yet

Tools

setup-xcode-and-appium-for-ios-automation-real-device

ios-testing-tools

top-5-ios-testing-frameworks

automated testing solutions

ios-test-automation-challenges-and-solutions