How do you know if you're running unit tests when calling swift test

We sometimes need to write code that needs to take a different path when it's running within a unit test. For example:

if runningTests {
   return
} else {
   // do ordinary api calls
}

This is typically done by reading some environment variable like:

if ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil {
    // Code only executes when tests are running
}

This SO post shows a few other solutions.

These work when running tests from within Xcode or from xcodebuild, but they don't seem to work when running tests using swift test.

What's the correct way to detect at runtime if code is running from within a unit test when running swift test?

1 Like

Actually, this does work:

let isRunningUnitTests = NSClassFromString("XCTest") != nil
1 Like

This doesn't work for me. I need nil from NSClassFromString("XCTest") even when running in an XCTest.

1 Like

I think in Swift 5.6 this works properly

#if canImport(XCTest)
  return
#else
  // do ordinary api calls
#endif

The downside being that you don't get compiler support for that else branch unless you're building in release configuration...

1 Like

Is there any way to know with Swift Testing ?

There seems to be an ProcessInfo.processInfo.environment["XCTestSessionIdentifier"] present even though I use Swift Testing and not XCTesting... :thinking:

I guess Swift Testing is just a wrapper around XCTesting...?

Kinda sad it's not a rewrite from the ground up if that's the case.

It seems that processName is always xctest when running unit-tests.

var isRunningUnitTests: Bool {
    ProcessInfo.processInfo.processName == "xctest"
}