Home    |    Articles    |    Talks

Clean Git History without Terminal

Git cleanup

Your commits represent and encapsulate your added value to the project you’re working on. They are meant to forever live in the history of your repo. They are your legacy to all the programmers who will work on the project after you.

It’s almost magical when you think about it. For example, you can still find the very first commit from Chris Lattner in the Swift repo. If you have (a lot of) time, you can go commit by commit from this one and re-experience the whole history of the Swift project.

A commit history doesn’t need to tell the true story of the development process with all its hiccups and try-and-errors. I actually think it shouldn’t tell the real story.

A good git history tells an idealized version of the story where we knew exactly what we were doing. Let me show you how to achieve this.

Continue reading ...>

Testing Publishers Synchronously with a Blocking Recorder

Combine publisher blocking recorder

When releasing Combine, Apple didn’t show us what their vision for testing the codebase with Combine was. Surely they must have thought about it.

Fortunately, the authors of Combine didn’t try to reinvent the wheel. The concepts, they built the framework around, are quite similar to the concepts in other reactive frameworks used on iOS. It means we can reuse the knowledge and best practices that evolved in the existing iOS-reactive-framework communities.

Let’s take RxSwift as (probably) the most used reactive framework of the pre-Combine era. It has a convenient set of tools for use in tests. We’ll use it as inspiration for today.

We’re going to build a simple Combine test helper allowing us to record and synchronously assert values produced by a publisher.

Continue reading ...>

iOS Code Review #2: Adding Tests to an Existing App (Networking)

Adding tests to an existing app can be challenging and sometimes intimidating. In this episode of iOS Code Review, I go through the process step-by-step.

You’ll see how to refactor existing code to make it testable by identifying dependencies and side-effects; how to write elementary tests to “lock” the current configuration of simple elements; how to mock network calls using a custom URLProtocol subclass. Finally, I’ll show how to easily mock dependencies using in-line closures.

Don’t forget to submit a project to the next iOS code review using https://vojtastavik.typeform.com/to/Y5p1BU.

Building a Custom XCTAssert for Multiline Strings

XCTest provides a bunch of XCTAssert... functions to be used for assertions in your tests. Sometimes, however, the functionality you need is different from what the built-in assertions can provide. Sometimes, all you really need is a custom XCTest assertion.

Custom multiline assertion

Custom assertions can make your tests more expressive, readable and maintainable by reducing boilerplate. Expressive and readable tests are crucial to understanding what’s happening and why the tests are failing. Having to write less boilerplate code makes people more inclined to writing new tests.

Let’s build a custom XCTAssertEqual overload which will work nicely with multiline strings. You’ll see how easy it is to improve the information value of tests and make the developer’s life more comfortable.

Continue reading ...>

Why You Should Be Using `unowned` More Often

I’ve seen a lot of interesting codebases in the last two months: new clients of Industrial Binaries, submissions for my iOS Code Review series, and also code challenges of the candidates we’re recruiting.

I was surprised how rarely unowned is used in the wild.

Weak everywhere

I think this is a huge missed opportunity. Not using unowned in the right places makes the code harder to maintain and can hide some serious and hard-to-replicate errors.

Continue reading ...>

Mocking Network Calls Using URLProtocol

For many apps, the networking code is one of the most important parts of the whole codebase. Yet it’s also a part which is quite difficult to test properly.

Some people just give up and rely on thorough manual testing. This approach doesn’t really scale well. A medium-sized app can have hundreds of various API requests. Having to test all of them manually makes any future changes and refactoring tedious and dangerous.

URLProtocol Xcode screenshot

Another popular solution you can see in the wild is making real network calls, especially in integration and UI tests. Not great, not terrible ☢️.

Real network calls make tests simple but slower by the order of several magnitudes. It also makes them much less reliable. The success of the tests depends on your current network conditions. Ask yourself if it’s OK that your tests fail when the train you’re working from enters a tunnel.

Can we somehow keep the simplicity of real network calls while making it more reliable and network-conditions independent?

Continue reading ...>

iOS Code Review #1: A Simple Weather App

I decided to try something new and recorded a YouTube video. This is the first video of the iOS Code Review series I’d like to do. In this series I’m going to review iOS projects which you can submit using this form.

I’ll remove all traces of the author or name of the project from the codebase. I’d like to focus solely on the code and show how to improve problematic parts.

Submit a project to the next iOS code review using https://vojtastavik.typeform.com/to/Y5p1BU.

Advanced testing using `Behavior` in Quick

Behavior<Context> is a hidden gem in the Quick testing framework. It was introduced silently in 2017 and it’s not even mentioned in the documentation! Here’s my PR which fixes that. The more I know about it the more I think this should be the way we write specs in Quick.

Behavior Xcode screenshot

So, what’s Behavior? You can think of it as of a better and safer way of defining shared expectation. But that would be very shortsighted. There’s much more!

Continue reading ...>