Issue 59
Apr 22, 2021

We all write tests. And we always go for 100% coverage. Right?

This week, I'm answering Jordi Bruin's question:

How do you approach writing tests? Do you think of them beforehand?

When writing applications, we often come with a certain mindset related to tests:

1. The production tester
Never writes tests and uses the time to develop more and faster instead. He trusts that issues will be found during regular usage and testing of the app.

2. The minimum tester
Tests only the critical paths of the app or foundational business logic.

3. The 100% coverage seeker
Tests even those static strings for their output, as long as 100% coverage is reached.

4. The Test-Driven-Developer
Writes tests first and implementation after.

----

I don't think that there's a good or a bad version (I likely forgot about many different types of developers), but I think every type has its benefits and reasoning. I've worked at a Digital Agency in which time was tight. Writing tests was not possible w/o delaying the project. Now, at WeTransfer, we've got a lot more time to write tests, but we still don't seek 100% coverage.

In other words, you could say I'm a bit in the middle of 2 and 3. In my opinion, it's always important to write tests as it will help your future self with not (re-)introducing bugs. Yes, writing tests takes time, but it also takes time to fix bugs that you could've prevented with tests.

In my article Unit Test Best Practices, I'm explaining why I think it's not important to reach 100% coverage. Doing so takes time and wouldn't always bring you to a better place.

So, how do you approach writing tests?
Today, I'm refactoring our syncing strategy in the Collect by WeTransfer. Some tests are already in place, while new ones need to be written to cover new scenarios. Code coverage helps me to determine "weak spots" in my code. I can easily find which parts of the logic aren't tested, and I decide for myself which parts I really want to make sure are tested. In other words: "which parts I want to make sure don't break". Unit tests are a great way to give yourself confidence for releasing a new version of your app as you know that your core logic is working as expected.

But do you think about them beforehand?
Not always; it depends! Sometimes, I'm writing tests after finding a certain bug. The fact that the bug could occur means that the tests didn't capture it beforehand. When fixing a bug, I start by writing unit tests reproducing the bug. This helps me both verifying my fix, as well preventing this bug from happening again.

In terms of regular development, I often start by writing the implementation. I'm not a TDD type of developer, as tests would often not run initially, and it just doesn't fit my workflow. However, it does sometimes help to write tests to make it clear for yourself which scenarios your code needs to support. Once again: it totally depends.

----

In the end, in my opinion, there's no golden rule. I'm personally flexible to use the best approach for my current task. If there's one consistent outcome: I always write some tests, and I encourage you to do the same.


Reach out to me on Twitter to tell me what you think or to ask me a question for next week's SwiftLee Weekly.

Enjoy this week's edition!

THIS WEEK'S BLOG POST

I'm often using Core Data in combination with SwiftUI Views or UIView elements in UIKit. By using the Combine framework, we make it easy for ourselves to update linked labels whenever values change in any of our linked NSManagedObject instances. This week's article describes this technique and allows you to use link Core Data publishers to your UI.

TWEET OF THE WEEK

If you’re running into issues when using Charles Proxy with the latest Xcode version, you might find this tip by Simon B. Støvring become handy.

SPONSORED

ViRE is a Visual Regular Expressions tool: Readable Regex • Code Complete / Cheat Sheet • Unit Tests • Powerful Replace System • Step-by-Step Search & Replace • Regex Visual Scheme • Regex History / Playground. ViRE is available on Mac & iPad.

CURATED FROM THE COMMUNITY

CODE

When reading the title, I was really asking myself what the difference would be, but it totally makes sense! Donny Wals opened my eyes that it’s worth making your initializer private if you really want to have a single instance of your object.
I love how Harshil Shah takes us on a journey in recreated the macOS Genie Effect for his app. Articles like this aren’t only valuable for the outcome result and for reading through creating such a solution.
This, for me, is a typical example of something super simple to fix in UIKit, but hard to do in SwiftUI without the right knowledge. Sarun W. explains to us how you can resize an image to fit a container view in SwiftUI.
We’re spoiled with SwiftUI, implementing a lot of Accessibility support by default. However, it’s often not enough, and Majid Jabrayilov explains to us how you can make your app even more accessible.

NEWS

Security becomes more and more important now that our users use mobile apps every day. Google joins over 20 industry stakeholders, including Amazon, and many certified labs, such as NCC Group and Dekra, to develop a very welcome new security standard for mobile apps.

WORKFLOW

Alex Grebenyuk always impresses me with the quality he always delivers through his articles and open-source work. This time, he releases Pulse: A logger and network inspector for Apple platforms. It’s performant, looks great, and well-documented.
I can’t believe I didn’t know this shortcut! I’m using CMD+SHIFT+J all the time, but his little brother has been invisible to me until Dominik Hauser wrote this article.
Two reasons for reading this article by Jeff Johnson: 1. We all sometimes suddenly get an app rejection, even for the same foundation project settings. 2. A rejection doesn’t mean you can’t appeal. If you have a good story, you can disagree and battle your rejection.