Run tests, take screenshots, send to the App Store, and more
Part 4 in a series of tutorials on modern app infrastructure:
In the dark old days of app development you needed to build projects, fight with certificates and provisioning profiles, take screenshots across a multiple of devices, and more – all by hand, too.
Fortunately, these days we have Fastlane: a project with the specific aim of saving developer time by automating common tasks. It can take screenshots of your app in any devices you want and at any places you want, it can push new versions of your app out to beta testers or to the App Store, and it can even – gulp! – take most of the pain of provisioning profiles away.
To give you a quick tour around Fastlane, we’re going to upgrade our sample project to use it. If you’ve been following the other parts of this tutorial you should already have a working project ready to try out, but if you’re not you can try checking out our original example project from GitHub – there’s a good chance things won’t be quite the same here, though.
Warning: The example project has been written specifically for this tutorial series, and contains mistakes and problems that we’ll be examining over this tutorial series. If you’re looking for example code to learn from, this is the wrong place.
Before we get started, we need to install two pieces of software: Xcode’s command-line tools and Fastlane itself.
There’s a good chance you already have the command-line tools already, but you can find out just by trying to install them again. Open your Mac’s Terminal program and run this command:
xcode-select --install
You’ll either get back “command line tools are already installed” or you’ll trigger their installation process.
Once that completes, you can install Fastlane with this command:
sudo gem install fastlane -NV
Just like SwiftLint, that will install Fastlane across your whole system so you can use it in any project from now on.
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
We’re going to start with having Fastlane take screenshots for our application. This usually isn’t too annoying to do the first time you try it: you launch your app in a simulator device of your choosing, browse around until you find the part you want, then take the screenshot and file it away.
But then you realize you need five screenshots in your app, potentially across multiple iPhone and iPad models. And when your UI design changes you need to redo those screenshots – “tedious” doesn’t really begin to describe it.
Fastlane can take screenshots for us automatically, and it uses a simple but smart approach: you write UI tests that launch your app and manipulate it however you want, then insert special commands to trigger a screenshot.
To get started, change into your workspace directory – the one where you can see Paraphrase.xcworkspace. Now run the command fastlane init swift
. Fastlane will think for a couple of seconds, then detect Paraphrase.xcworkspace and offer some options for things it can automate.
We’re going to start with screenshots, please press 1 and press enter. Fastlane will begin the process of walking you through the configuration process to automate your screenshot generation, but unless you like confusing yourself I strongly recommend you ignore what it says and read this guide instead.
First, Fastlane will say it’s going to generate two helper files that make its screenshot hooks work. That’s fine, so press enter once to let it continue.
Next it will read through your project configuration to figure out the next steps. Here’s where things can get confusing, so rather than follow Fastlane’s instructions I suggest you follow these instead:
Before we’re done, we need to make two small code changes, so please open ParaphraseUITest.swift from the ParaphraseUITests group. Inside the setUp()
method you should see this:
XCUIApplication().launch()
That kickstarts the UI test system, but we need to adjust that to inject Fastlane’s snapshot system. So, replace that single line with these three:
let app = XCUIApplication()
setupSnapshot(app)
app.launch()
Finally, we need to take our first screenshot. Xcode’s default UI test template file has a testExample()
method that we can use for just this purpose, so please modify testExample()
to this:
func testExample() {
snapshot("0Launch")
}
That’s our Xcode configuration all complete, so go back to the terminal window where Fastlane has been waiting.
Fastlane really wants you to press enter at this point so that it can continue configuring the screenshot system, so press it now.
In theory, you ought to see a prompt saying “Which is your UI Testing scheme?” followed by ParaphraseUITests and Paraphrase as two options. However, in every test run I did while preparing for this article I only ever saw one - just Paraphrase by itself.
Fortunately, this just seems to be a glitch: press Ctrl+C twice to quit Fastlane, and you should be back to your regular shell prompt. Now run fastlane init swift
again and repeat the process again: press 1 to select Automate Screenshots, press Enter to continue, then press Enter to continue again.
This time you should definitely see both ParaphraseUITests and Paraphrase listed, so please enter whichever number you see next to ParaphraseUITests and press enter again.
Here Fastlane will ask whether you want to upload screenshots to iTunes Connect automatically. This is a huge timesaver and highly recommended, but I’ll be declining the offer here because this isn’t a real app.
Once you choose either “y”es or “n”o Fastlane will move further, and say “Installing dependencies for you.”
This is another place where Fastlane seems to diverge from reality just a little – I left my computer alone for 20 minutes and nothing had changed, so don’t despair if you count to 60 and find nothing has happened.
Instead, try press Ctrl+C two or three times until you get back to your terminal. This force quits Fastlane (again!), but it will still have configured your project.
At last we get to the good part: run the command fastlane snapshot
to have Fastlane generate screenshots for your app.
This is not a fast process – largely because Fastlane has to build your app, deploy it to multiple device simulators, then take screenshots as appropriate. As a result now is a good time to make some coffee and stretch your legs – come back in 10 minutes!
Once Fastlane finishes (and it really will take a little while!) look inside your fastlane directory to see a new directory called “screenshots”. This in turn will contain subdirectories for each language you support, which in our case is just en-US. And inside there will be your finished screenshots, with each file named using the device in question and the name used inside your UI test Swift code. For example, you should have iPhone 8-0Launch.png – that’s the screenshot triggered by snapshot("0Launch")
when run on an iPhone 8.
If you want to customize how the snapshot process works, edit the file Snapfile.swift in your fastlane directory – you can edit the list of devices and languages there, and even pass in custom launch arguments to make your app behave in a particular way. I made the Paraphrase app work only with iPhones, so see if you can configure Snapfile.swift so that it generates screenshots only for iPhones.
This was the third part of a short series on upgrading apps to take advantage of modern infrastructure. We’ve only looked at automating screenshots here – a huge timesaving by itself, particularly if you upload them directly to iTunes Connect! – but hopefully you’re already getting an idea of how much time it can save once it’s configured correctly.
If you want to take your snapshot skills further, you should read my guide on how to test your user interface using Xcode – it will help you get your app's state exactly where you want it before taking screenshots.
In the following articles we’ll look at other ways computer automation can help us write better code – stay tuned!
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.