Xcode UI Tests with Embassy and Succulent

How to record and replay APIs request to make UI Tests work.

In the past few days, I’ve been integrating Embassy and Succulent in my UI tests.
If you have the need to run UI tests for an app that relies on API data, this guide might offer you an alternative to mocks / stubs.

The problem(s)

  • The app relies on API data to populate the UI 🌥
  • Using stubs might require to write and maintain a lot of files 😫
  • When using mocks, the logic used in the app might be different than making an actual network call 🤔
  • Using a real api connection is a NO NO, too many variables and failures 🙅‍♂️

The Embassy + Succulent solution

The solution consists in creating a local server where to point your app to (Embassy) and recording or replying network calls (Succulent).

The first time you will run the test, the standard network calls will be made and recorded in a trace file.
The next time, the same network calls will be replayed back automagically. ✨

How cool is that? No more writing mocks, you can even simulate lags and errors and it all runs inside the build machine, inside an XCtest! 🤙

How to use it?

  1. Download and install the Succulent pod, at the time of writing there is no pod on cocoapods.com so you have to downloads the source and add it to your podfile this way:
target “UI Tests” do
inherit! :search_paths
pod ‘Succulent’, :path => ‘Succulent/’

Succulent requires Embassy and it will be installed automatically.

2. Create a new UI Test file and copy / paste the instructions from the Succulent GitHub, you should end up with a file like this:

When launching Succulent, you have the option to specify a base URL, this will make so that all the request including that base url will be recorded, while the others will be ignored.

3. Add the following line in your UI Tests’ target Info.plist:


4. Point your app to your local server. 
To do this inside your main app you have to check if the environment variable “succulentBaseURL” exists and it’s set. 
This indicate the url of your local web server and it’s set in the setUp function you copied from point 2.

if let localServerUrl = ProcessInfo.processInfo.environment[“succulentBaseURL”] {
return URL(string: localServerUrl)!

That’s basically it! 🙌

Now if you write a simple test and play it, Succulent will record the api request and create a .trace file inside the Traces folder in your UI Test target folder.

The next time you run the same test it will check if the file exists and play it back.

You can open .traces files directly from Xcode, see all the network requests and modify them if needed. 😮

Hope it helps, now have some pizza: