Often we need to unit test code with side-effects that interact with other parts of your system using abstraction — protocols in Swift. There are many techniques to build that abstraction and verify if our code works as expected: stubbing, spying, dummying etc.
Previously, I made a deep dive into auto-generating a stub placeholder that allows seamless customization of a mock’s function behavior right in a test case. Let’s extend that approach with a spy registration that observes and records side-effects generated during a test case.
How do you assert that your code doesn’t introduce any unexpected cycles that lead to memory leaks? Do you actually verify weak/strong references in unit tests? If you find these questions interesting, let me demonstrate how you can write a concise and self-explanatory Swift test case that verifies correct reference type.
Whether your code keeps a strong or weak reference to some other object is crucial for non-garbage-collected languages like Swift. Even a tiny mistake may lead to a leak, invalid behavior or even crash. Although I don’t see many developers writing them, I believe that verification on a unit…
If you want to configure your iOS/Mac (Swift or Objective-C) build with some alternative variant, there are plenty of different approaches to follow. In general, you can divide them into two clusters: switch it in runtime (e.g. parsing
Info.plist) or compile-time (leveraging Swift Compilation Conditions/Preprocessor Macro or define new target). Obviously, we always prefer the compile-time check but the overhead often may overweight its benefits.
This post will present an alternative way to control a file variant selection based on Xcode Build Rules (in contrast to traditional Xcode targets).
There are plenty of solutions to build a different flavor of…
Often we need to unit test a code with side-effects that interact with other parts of your system by abstraction— protocols in Swift. There are many ways to verify if it works as expected: stubbing, spying, dummying etc. In general, engineers dubbed these forms as mocks, even “test double” is a legit name for that.
FYI, “test double” name comes from “stunt double” in the film industry.
Writing test doubles (like stubs or mocks) is a boring process in Swift and developers often try to generate it automatically by using tools like Sourcery/SwiftyMocky. …
We all love protocol extensions, one of the most powerful element of protocol oriented programming (POP) in Swift. Despite their unquestionable benefits, there are some rare cases where you should avoid them. In this article, let me demonstrate a potential trap that your API consumer may fall into when trying to unit test a code that depends on some protocol extension function.
Quick reminder: method dispatching
In Swift we have three kinds of method dispatching: static, vtable and message dispatching. If you are not familiar with this terms, let me recommend a great post from Riazlab’s. In short, dispatching methods…
There isn’t a lot of articles about error handling in the iOS ecosystem, even this seems to be a non easy and substantial component of each app. Today, I wish to tackle this problem and present my solution towards less disruptive error handling in the iOS app.
To ensure that we are on the same page, by an error I will mean an instance that conforms to Swift’s
Error type and error handling is a reaction to it. These errors may arrive in a synchronous manner (disk operations, invalid argument) or asynchronously (no Internet connection, session token invalidated etc.). First…
Practicing TDD using Xcode IDE can be a bit disruptive. Every time you introduce a small change in the implementation or test file, Xcode rebuilds entire project (fortunately using incremental build) and installs the app on a simulator. Depending which project configuration you have, it may take from a few to dozens of seconds. This article presents a way to bypass this long lasting procedure and automatically run unit test(s) whenever you save your implementation
.swift file. We will leverage new feature of John Holdsworth’s “Injection for Xcode” app — support for auto-testing.
TLDR; InjectionTDD (together with InjectionForXcode) runs unit…
How to test non-called completion handler scenario
Testing completion-handler API happy path scenario is really simple with
XCTestExpectation. Things get complicated if your test case has to verify whether given handler was not called. It is still straightforward if it’s called synchronously after some other event that you emulate. But how about a case where execution is deferred in time? In this article, I will demonstrate you a solution to achieve 100% sure that given completion handler will never be called — fast and reliable.
Let’s talk about unit tests of some asynchronous task that provides completion handler — let’s…
Swift language was designed with a focus on “safe by default” approach (do not confuse with “safe by design” — Swift does not prevents you from doing dangerous actions but only encourages for good practices). One of such incentive is a great support for sum and product data types,
struct, respectively. These types are great to limit number of potential states during compilation time so we don’t have to write any unit tests of cases that should never occur — you definitely prefer to never reach given state, rather than covering it with an obvious unit test.
iOS Engineer at Spotify