Do as I say: Write UnitTest

UnitTests vs Playground

Let's do a bit of personal learning. Now that we have fixed one major problem with computing the daily change percentage let's see what it would be like to have a test suite around that simple yet complex function. Do as I say - WRITE those UnitTests.

Let's start with a refresher - How to set up an existing project with a UnitTesting Target. It's TARGET that is the keyword here. Look for a File > New > Target... of type Unit Testing Bundle - that's the ticket.

The next stumbling blocker is the access to the SUT - System Under Test in testing speak. In Xcode, this is achieved by @testable import <TARGET>. Where the target is the name of your App.

Now to get started let's copy the Playground code into a test and run it. We get a nice green diamond with a check mark for passing the test. That should create a virtuous feedback loop in our dopamine receptors.

Yet, that is NOT a proper unit test. It has no assertions.

One of the great things about XCTest is that the order of the Assert parameters does not matter, like some other xUnit-derived frameworks. I never could remember the proper ordering of the actual and expected values. It may be poor form to have both those asserts because they are partially redundant. But I just learned of the sign property and want to use it.

XCTAssertEqual(change.sign, .minus) // Double has the .sign property

XCTAssertEqual(change, 0.02, accuracy: 1/1000)


I use a bogus value of +0.02 when I expect a minus value - just so I can verify that the test is working. Then I changed the assert, adjusted the accuracy value, and remove the print line.


// SUT - the System Under Test

let change = example.computeChangePercentage()

XCTAssertEqual(change.sign, .minus) // Double has the .sign property

XCTAssertEqual(change, -0.02, accuracy: 2/1000)

That's the first test of the suite. The advantage Unit Tests have over the Playground is that one can more easily code several situations and conditions to test.


With those tests in place, we can now write the code that makes ALL tests pass.