Custom Xcode Build Configurations with a Stubbing example
You probably already have seen that when Xcode creates a new project there are two build configurations: Debug and Release.
In this article, we'll learn how to create a custom build configuration using a network stubbing example to demonstrate how to set it up and how it works.
Recently, we were working on a project where we had a network layer to make requests to our server and a service layer above it to receive the response and where the business logic happens most of the time.
To test the business both the network layer and service layer, in that case, we use mock data to stub our requests for the tests.
There is more than one way that we can do this, including runtime checks with a parameter being passed to the network object, and then at runtime have a conditional check to decide if the response should be stubbed or not.
We always did it that way and it’s a pretty good to handle this problem, never have problems with that approach.
But, in this specific case, we decided to try run this check at compile time, just as a test to see the pros and cons of doing it with compiler flags and custom build configuration.
So, creating a new build configuration… Let's see how to do this
We'll create a new one from our Debug configuration.
Now that we have the custom build configuration, the next step is to set the compiler flags so we can do the flag check.
We just search Active Compilation Conditions and added the TEST flag.
Is very important to a dd this flag on both Project and Target.
Now that we have a new build configuration, we can set it to be the configuration that will be used on every action in any every target on this project.
With the flag added we need now to edit our schema, on the Test action and change the build configuration that it will use.
Just select the Test build configuration for the Test action and now it’s done. Our Test Target now will be built with the Test configuration.
Now let's see how it works on our example:
Since we set the compiler flag on our Test configuration, when Xcode compiles the app for the Test(that we also set to use Test build configuration for test action on our schema) it will compile only the stub code.
With the example that we used the custom build configuration just to set some flags on the compiler for stubbing purposes. But you can modify compiler optimizations, build options, build architectures, static analyzer, LLVM options, linking options and so on … Basically, everything that is in the Build Settings section, you’ll have the option to set a different value for any of your build configurations.
The example we use is an experiment, and we still don’t know if it’s better or not than the runtime approach. I think that is a matter of personal opinion, make sense to me do this at compile time because I found it simpler. But the runtime approach is more flexible, since at any point of your application if want to do one test only at that point, you can just set a parameter on that object. It’s for sure something that should be discussed with the team to use a solution that is best for all of them and for the project.
There are other ways, that make the stubbing with interceptors on the URLSession layer like OHHTTPStubs, where you do not have to do this on your network layer and can do the stubbing only on the test target, making your code cleaner. But that is a subject that we can talk in another article. The main purpose here was to talk about build configurations with a real example.
That's all for this one, hope you like it :)
If I got something wrong or you got some comment or question, please let me know. I will be really happy in receiving your feedback :)
You can find me on twitter at @LucianoPassos11
Thanks for reading :)