I’ve written before on the subject of Behaviour-Driven Development, here and here. I have found it invaluable in answering the question “what should I test?” Focussing on behaviours rather than tests, helped me a great deal. A focus on validating behaviours soon becomes second nature and I found it a lot easier than Test-Driven Development.
Let’s consider an object that is a part of an app you wrote. It has an interface that defines its methods and dependencies. These methods and these dependencies declare contract of your object. They define how it should interact with the rest of your application and what capabilities and functionalities it has. They define its behavior.
And that is what you should be aiming at: testing how your object behaves.
In my first attempts at Behaviour-Driven Development in iOS I used Specta, I love Specta but it had some problems.
It is native to Xcode so whilst it kind of works some things are not great. Like it is difficult to run just one test.
It can be difficult to know which test failed.
It can be kinda buggy
I used obj.io article Real-World Testing with XCTest for guidance, I knew I wanted Behaviour-Driven Tests in XCTest. I really liked the style of Specta tests and being a Ruby Developer they were familiar to RSpec. One piece of advice the article gives is to start all tests with the words “testThatIt”. This small change although it may feel insignificant helps to structure the naming of test and keeps you focussed on being Behaviour-Driven. So I took an existing Specta test class for User Management and converted the wording of the tests to “testThatIt”
should be logged in successfully
should return error when service returns HTTP status code 401
should not accept blank email or password
Split Bigger Test Suites Into Topics
The Real-World Testing with XCTest article had a little snippet of advice in there “if a class gets a bit bigger, we use categories to split up the test by topics.” This advice appealed to me because it is similar to the way that Specta works with contexts and describe blocks. Splitting up test classes by topics wasn’t as easy as I initially thought it would be but didn’t prove too difficult.
I have found it useful to structure the actual tests using an Arrange-Act-Assert pattern, splitting each test into three parts. The Arrange section allows you to set-up the environment, so this may be mocking out network calls or putting in place stub objects. Then the Act section is the thing you want to test, this will typically be one method call. The Assert section validates you got the expected outcome.