It’s easy to disable tests in Xcode, but not entirely obvious. A lot of people give Xcode flack in terms of how far behind other IDEs it is with regard to its support for automated testing. I don’t entirely disagree with this. On the other hand, it’s come so far from just five years ago and I’m thankful for that.
Why Disable Tests
You might be wondering, if I’ve spent all this time writing tests, why would I ever want to disable tests in Xcode? I’m not advocating permanently disabling them, instead, I’m advocating disabling them temporarily to speed up your development or to unblock progress. Just this week, I returned to an old project of mine, one that hasn’t had an app store update in over a year. It still uses CocoaPods version 0.33.0, and Swift 1. Needless to say, it needed some work getting it up to speed. (Side note: I have a lot of ammunition for future blog posts on how to NOT let a project get this stale, but we’ll save those for a future camp fire). First, I needed to get the project to actually compile. Second, I needed to get the tests passing. And finally, I needed to update our continuous integration machines and jobs to also compile and successfully run the tests. I had my work cut out for me.
When working with a project this old, sometimes advanced techniques like TDD aren’t immediately useful if you can’t even get the project to simply compile. When working through compilation errors and test failures at a large scale, it’s useful to selectively turn off a subset of the errors or test failures so you can eliminate noise, focus on a piece of the problem, and make progress. You can easily disable tests in Xcode in two ways: disable compilation, and disable test execution. Both of these are scheme changes. Here’s how:
How To Disable Tests
Disable Tests From Building
To simply disable all your tests from building, you can do this in the Scheme editor. From the menu bar, select Product -> Scheme -> Edit Scheme.
In the left hand bar, select Build.
Then in the main pane, you can disable tests from compiling for any action in your project. If you’re project is in a really bad state, you can disable tests from compiling when running your application.
By disabling any of those checkboxes, when you run your application, anything in the associated targets will not be compiled.
Disable Tests From Running
Similarly, you can use the Scheme Editor for selectively turning tests and off. Still in the Scheme Editor, select Test in the left hand bar. Then, in the main pane, you’ll see each target associated with tests. The checkbox will let you enable or disable the tests from being run when you run tests for your project (Command-U, or Product -> Test).
Disabling an entire target may not be as granular as you’d like. In fact, it’s pretty coarse. You can expand any of the targets in that list and see specific test classes, and then selectively enable or disable tests by test class. And if that isn’t granular enough, you can drill one level deeper and then selectively turn tests on or off by test method!
Give it a try.
xcodebuild in Xcode 8
One thing I’m really excited for in Xcode 8 is that
xcodebuild, the command line interface for building Xcode projects, was updated with similar functionality. With
xcodebuild in Xcode 8 you can selectively pick which tests are built and executed. The use case is a little different for this tool.
xcodebuild is often used as part of a continuous integration setup. With the new changes, you no longer need to compile tests to run them.
xcodebuild will be able to run tests previously compiled. This means that you can compile your app and tests on one machine, and then distribute the load of testing it across other machines!
To build you app for testing, but not actually run the tests:
xcodebuild build-for-testing -workspace <path> -scheme <name> -destination <specifier>
Then you can use the produced bundle on different machines to run the tests without compiling! Combine that with the following steps for selectively running tests, and you’ll be able to distribute the execution of your test suite across different machines, in parallel!
To selectively specify which tests to run for
xcodebuild test -workspace <path> -scheme <name> -destination <specifier> -only-testing:TestBundleA/TestSuiteA/TestCaseA -only-testing:TestBundleB/TestSuiteB -only-testing:TestBundleC
You can also specify tests to be skipped:
xcodebuild test -workspace <path> -scheme <name> -destination <specifier> -skip-testing:TestBundleA/TestSuiteA/TestCaseA
Don’t Abuse It
With great power comes great responsibility. Please don’t disable tests in Xcode, either from running or compiling, and leave it that way. That’s like driving without a seatbelt. Only do it if you are working in effort to improve your project. I know that working with a dusty and stale project isn’t the only time that it may be useful to disable tests in Xcode. I’m sure you’ll find your own reasons. I’d love to hear what they are.