Xcode: TEST vs DEBUG preprocessor macros

Viewed 29727

When creating a new project with unit tests, Xcode sets the build configuration to Debug for the Test scheme (same for the Run scheme).

Should I differentiate between Run (Command-R) & Test (Command-U) schemes?

I.e., should I create a new Build Configuration called Test, add a preprocessor macro TEST=1 to it, and use it as the build configuration for the Test scheme instead? Or, should I just keep Run & Test both as Debug?

I come from a Ruby/Rails background, where you usually have test, development, and production environments. It seems to me that Debug is like development and Release is like production, but we're missing a test, which is why I'm thinking it might make sense to add Test.

Comments? Opinions? Suggestions?

I'm specifically asking this because I want to compile something for Test with:

#ifdef TEST
// Do something when I test.
#endif

I don't think it matters if I also compile this for Debug. So, I really could just do:

#ifdef DEBUG
// Do something when I run or test.
#endif

But, I'm really only intending to do it for tests for now. So, that's why I'm thinking I should differentiate between debug & test but am wondering why Xcode doesn't do that for you by default? Does Apple think you shouldn't differentiate between them?

11 Answers

If you create a Test build configuration and then set the "Other Swift Flags" property of your Target to "-DTEST" it will define a TEST macro that will work in your swift code. Make sure you set it in the build settings of your App target so that you can use it in your App's Swift code.

Other Swift Flags setting for DEBUG and TEST

Then with this set, you can test your code like so:

func testMacro() {
   #if !TEST 
       // skipping over this block of code for unit tests
   #endif
}

Updated for Xcode10:

static let isRunningUnitTests: Bool = {
    let environment = ProcessInfo().environment
    return (environment["XCTestConfigurationFilePath"] != nil)
}()
Related