How can you learn and practice test-driven development (TDD), or refactoring, or working with legacy code? I can explain the principles. But the question that comes back is, “But what do I actually do?”
That’s what code katas are for. They’re not tutorials. They’re exercises, designed to help you grow in your technical agility. I’ll introduce you to some that are specifically for Swift programmers. Then try doing one today!
What’s a Code Kata?
How do professional athletes stay on top of their game? They practice. How about professional musicians? Practice, practice, practice.

“Kata” is a Japanese martial arts term for choreographed patterns of movement. They’re also called “forms.” Both beginners and masters practice these detailed patterns over and over. The movements eventually come without thought, because your body knows what to do.
A “code kata” applies this idea to coding. It’s a self-contained exercise you can repeat. Every time you repeat it, you’ll learn something new. At first, you’ll work to learn one approach to solving a problem. As you repeat the same approach, your learning will shift toward muscle memory.
Swift code katas: At first, you’ll work to learn one approach to solving a problem. As you repeat the same approach, your learning will shift toward muscle memory.
Then you can tackle the same problem but with different approaches. A common style during the annual Global Day of Coderetreat is to repeat a problem while adding different coding constraints. For example, how much coding can you do using only keyboard shortcuts? Or can you write code without using conditionals? …A physical analogy would be running with extra weights, or fighting with one hand.
Doing self-contained exercises like this is the best way to practice coding. They’re outside of your production code, so there’s no worry of breaking anything. You’ll throw away what you try because you’re going to repeat the coding kata later. The goal is to gain mastery over coding tools and techniques.
Practice.
So let’s look at some exercises for Swift programmers. But first, here are a few pro tips.
Code Kata Pro Tips
Use a Scratchpad
Before you start: Make sure you have a piece of paper and something to write with. An index card or sticky note is all the space you need.
Why? Because TDD is a discipline of doing one thing at a time. When you notice something to clear up, don’t dive straight into it. Write it down for later, and stay focused on whatever you’re working on now.
When you complete a task, revisit your list. Clear up the code, and cross the entries off your list.
In the Bowling Game example, this scratchpad is actually shown in the slides. In the upper-left corners, you’ll see boxes like this:

When you see this, write it down on your scratchpad. I mean it: write it down. This will help reinforce good TDD habits.
Daily Practice
When you’re working on a new code kata, I’d recommend going through the entire exercise, once through.
Then we can follow Marlena Compton’s advice in Learning TDD with Exercises, by doing 15 minutes a day. Set a timer. Stop when you get to 15 minutes. The next day, continue from where you stopped. Try making it a small part of your daily routine.
Use Templates
Apple fills its Xcode templates with useless cruft. They also fail to add other things that would actually help. Try using my test file templates and test-oriented code snippets.

In the spirit of using different constraints, work through a TDD kata or legacy code kata without them. Then do it again, using my templates. See if they change the experience.
Refactoring Swift Katas
Before diving into test-driven development, experience what it’s like to work in code that has tests. Learn how to do some refactoring.
These exercises focus on sections of code that have unit tests. The goal is to move in small steps.
Refactor in Small Steps: Move Field
https://github.com/jonreid/RefactorSmallSteps
Experience the Move Field refactoring by following the steps described in the accompanying post When You Refactor, Are You Using Small Steps? The first step is to move strings from the view controller into the view model—so that the view model can use them.
Refactor in Small Steps, Continued: Move Logic
https://github.com/jonreid/RefactorSmallStepsContinued
This is the a continuation of the example above. Having done the Move Field refactoring to put the strings into the view model, the next step is to move the conditional logic. Follow the steps in the accompanying post Refactoring: How Do You Clear Up a Mess, Safely?
Many of One
https://github.com/jonreid/ManyOfOne
This is a Swift version of an exercise by Llewellyn Falco. He identifies an important step to use when you want to go from one thing to many. The in-between step most people miss is to use “many of one.” Start using an aggregate type such as an array—but have the array contain only that one item, at first.
Parrot Refactoring Kata
https://github.com/emilybache/Parrot-Refactoring-Kata
Is it an African parrot, a European parrot, or a Norwegian Blue? Clean up this code by applying these two refactorings in order:
Refactor a View Controller (Book Example)
Most of part 3 of my book iOS Unit Testing by Example is about refactoring a single view controller. The view controller is messy, but there are accompanying tests. Once the code is ready, follow the steps described in the book:
- Do some initial clean-up, turning messy MVC (model view controller) code into clear MVC code.
- Refactor to MVVM (model view view-model).
- Refactor to MVP (model view presenter).
Refactor a View Controller (Video Example)
https://github.com/jonreid/RefactoringViewController
Take this fully-tested iOS view controller written in MVC. Play around with refactoring it in different ways, such as:
- Refactor to MVVM.
- Refactor to Null Object pattern.
- Refactor to MVP.
TDD Swift Katas
Here are Swift code katas about TDD. The focus is on test-driven evolutionary design.
Bowling Game
The idea is to score a game of bowling. Follow along with slides, coding each step:
In my version of the Bowling Game slides, green lines show code that we just added. Red lines show code that we’re about to remove. For example, here we added the last line, and are about two remove the two lines above it:

Let me call out some specific slides…
Slide 12: Set up Xcode to show test code and production code side-by-side, mimicking the slide. Do this as follows:
- Swift: Click the test file so it shows on the left. Option-click the implementation file so it shows on the right.
- Objective-C: Click the test file so it shows on the left. Option-click the .h file so it shows on the right. Shift-option-click the .m file and double-click the “+” in the bottom right. On the right side, you should have .h above and .m below.
You may prefer to use tabs instead, and that’s fine. The goal is to see the code side-by-side, or switch between them so fast that it doesn’t matter.
Slide 23: Select the two circled lines, then use the context menu to Refactor → Extract. (If Xcode refuses, do it by hand. Or, try AppCode which has better automated refactoring.)
Slide 40: You have various options to rename loop variable “i” using Xcode:
- Do it by hand.
- Use “Refactor → Rename” observing how long it takes to index and animate.
- Select its first appearance and do Edit All in Scope. This is available through the menus, or in a pop-up menu that appears when you hover over a selection, as shown here:

Try each option to see how they affect your “flow.” And one more option is to try AppCode.
Name Normalizer
https://github.com/jlangr/name-normalizer
The challenge is to input a name in standard English order, returning the name normalized for use in a bibliography.
This is a “TDD paint by numbers” exercise: the tests are written for you. Initially, they’re all disabled. Enable them one-by-one, and follow the remaining two steps of the TDD Waltz:
- Write enough production code to pass the test.
- Refactor the code so it expresses the domain. (In this exercise, leave the test code alone.)
You can see one possible final solution in the “all-solutions” branch (though not the steps to get there). I also offer 75-minute mob programming sessions of this exercise on PubMob.
Time-of-Day Greeter
I walk through this kata in the last chapter of my book, iOS Unit Testing by Example.
Make code to greet someone by name, according to the time of day:
- 5:00 am – 11:59 am: Good morning.
- 12:00 pm – 4:59 pm: Good afternoon.
- 5:00 pm – 4:59 am: Good evening.
So if we provide the name “Lauren” and the time is 4:15 p.m., it should return, “Good afternoon, Lauren.” Allow for the possibility that there is no name.
Collection of TDD Katas
https://github.com/brandtdaniels/tdd-kata
Brandt Daniels has assembled a collection of katas for practicing TDD in Swift. Besides the Bowling Game, these include:
- Game of Life
- Password Verifier (within the Refactoring folder)
- String Calculator
- Interactions (follow up to String Calculator)
You can see possible solutions in the “developers/brandtdaniels” branch.
Legacy Code Swift Katas
In the real world, we often face legacy code: that is, code written without tests. Since testability wasn’t a concern, adding tests afterwards is challenging. We usually need to make careful changes to make it testable.
In the following code katas, you will face a glob of untested code. Your challenge:
- Bring the code fully under test without changing its behavior.
- Refactor the tests to better express the behavior.
- Then lean on those tests to improve the design of the code.
Gilded Rose
https://github.com/emilybache/GildedRose-Refactoring-Kata
Real life is messy and hard to model. There are items for sale at the Gilded Rose inn, and the requirements are varied.
Once you have the code tested and cleared up, add a new feature: “Conjured” items should degrade in Quality twice as fast as normal items.
Trip Service
https://github.com/sandromancuso/trip-service-kata
Imagine a social networking website for travelers:
- You need to be logged in to see content
- You need to be a friend to see someone else’s trips
Some of the code makes calls to things we shouldn’t actually invoke during unit testing. These are stubbed out to throw exceptions. Can you use only automated refactoring tools to make it possible to replace these parts during testing? Hint: subclass and override.
Expense Report
https://github.com/christianhujer/expensereport
There is a functioning code that outputs an expense report. But it has no unit tests. Like the Gilded Rose, the challenge is to add a new feature. The code in this exercise isn’t as obviously horrible as the Gilded Rose. Instead, the code looks pretty normal. So it’s full of common code smells you may not detect at first glance.
Baby Steps Timer
https://github.com/dtanzer/babystepstimer
This app helps you take “baby steps” while doing TDD. The idea is that you should be in Red (that is, have failing tests) for no longer than 2 minutes.
This is a real, functioning app. There's a view controller with buttons. There's a timer that plays sounds and changes the color. Since this is full of iOS specifics, it’s more challenging than the other legacy code katas. So I’d try one of the others first.
And Many More
The Parrot Kata and the Gilded Rose are just two of many, many katas that Emily Bache hosts, for a variety of languages.
Are there other Swift code katas that you like? Please let me know so I can add them to the list.
Hi Jon,
I really enjoyed the Bowling Game kata, and I appreciate the work you’ve done to explain the mechanics of doing TDD in Xcode. Also, thanks for making the improved template available.
On Slide 38, why do you immediately recognize the flaw in the design and refactor it then and there? At that point in the project, the design seems perfectly suitable for the tests that have been written, and a new test (like testOneStrike) would highlight the flaw and force the refactoring.
Robert,
I’ll try to explain Slide 38, but need to back up. testOneSpare was introduced back on Slide 29, as a failing test. In the process of trying to think about what to code to get it to pass, we discovered deficiencies in the design. So we comment out testOneSpare in order to concentrate on refactoring — wearing one hat at a time.
As of Slide 36, the refactoring has been proved successful. So I re-enable testOneSpare, and run it to see that it’s still a failing test.
On Slide 38, I’m back at the point of trying to code something that’ll pass testOneSpare. This is the second try. Again, I discover a deficiency in the design. So once again, I switch hats by commenting out the test, concentrating on tweaking the design (refactoring) in a way that doesn’t break the previous tests.
This illustrates the principle of wearing one hat a time. Either you’re coding to get a new test to pass, or you’re refactoring. But don’t do both at the same time. We’re basically walking on stilts: Lift one, or the other, but not both. :) By keeping one foot grounded, so to speak, we reduce the risk of falling over.
Does that makes sense?
Hello Jon.
Thanks for Bowling Game exercise. It’s awesome! I practised it yesterday and have some thoughts:
– Apple template looks almost like yours now (XCode 5), and it’s easier to use it than run yours (I couldn’t manage it to work – tests wasn’t being run)
– Last test was successful without any changes in code (code from previous test was enough) – is that ok or I missed something?
If you want I can send you detailed description what went different than in yours PDF so you can update it for XCode 5.
Have a nice lecture here in Poland. Sad that I missed opportunity to be there. :(
Daniel
Daniel, I’m glad you found it helpful.
– Yes, Apple’s latest template finally addresses my concern. You no longer need my template, unless you want to use the older SenTestingKit.
– The last test is a surprise: it basically shows that there’s nothing left to do! But it’s hard to tell without a test to prove it.
Polish hospitality is wonderful! I had a great time, and look forward to going back.
Hi Jon! I’m just starting this using the Bowling Game Swift version…I noticed on slide 11 it says “Select Objective-C as the language.”, but it should say Swift.
I finished going through it and here’s what I noticed could be tightened up, if you want. ;)
Slide 11
– It should say “Select Swift as the language” instead of Objective-C. (error)
Slide 12
– there is a minus sign in front of fun testGutterGame() that I think is leftover from Obj-C? (error)
Slide 15
– the return line in func score() doesn’t need the semicolon (unswifty)
Slide 20
– theScore variable doesn’t require “: Int” since it’s implied in Swift (unswifty)
Slide 27
– the semicolons in the new test should be removed (unswifty)
Slide 28
– the red comment on the bottom should say 16 instead of 20 (error)
Slide 32
– rolls variable doesn’t require “: [Int]” since it’s implied in Swift (unswifty)
– currentRoll doesn’t require “: Int” since it’s implied in Swift (unswifty)
– currentRoll++ should be changed since it’s deprecated very soon in Swift (deprecated)
– Change to:
rolls[currentRoll] = pins
currentRoll += 1
– the return of func score() was changed from theScore to score but that line isn’t green
Slide 47
– the strikeBonus method has a minus sign in front of private func (i.e. -private func) (error)
Many thanks! I hadn’t publicized the Swift version yet, so you got to be the guinea pig. I appreciate the help. Check out the updated version I just uploaded.
Haha excellent! I’ll change the link in my blog post to the new version :)
Did you actually upload it and publish the new version? The one in this post seems to still be the same, and no new posts were released.
I mark the revision date on the second slide. You should see 21 Feb. If not, your cache is playing tricks on you.
I completed cleared my website data and it still says Feb 2, 2016 as the date on slide 2. ? am I losing it or what? ?
https://qualitycoding.org/files/BowlingGame-Swift.pdf
Hi Jon,
Thanks for creating these iOS versions of Uncle Bob’s Bowling Game Kata. I’ve just tried the swift one and I noticed that the following line –
for _ in 1...10 {
on slide 37 (The Third Test) throws an ‘Index out of range’ exception.
It should, of course, be
for _ in 1...9 {
which is the equivalent of the java code from Uncle Bob –
for (int frame = 0; frame < 10; frame++) {
Cheers,
Paul.
I’d probably do
for _ in 1..<10 { }
Actually, the Java goes from 0 to 9. I thought it more intuitive to count frames 1 through 10. If you’re getting an exception, I suspect your array is the wrong size.
You’re right Jon. I’d was accidentally counting the frames from 0 to 10 on my first day
for _ in 0...10 { // Doh!
but, as you say, it makes more sense to count the frames from 1 to 10 (rather than 0 to 9).