As far as I know, there is currently no way for Swift code to detect whether or not it is building for or running in a test context, but there are cases in which this is useful information to have:
- You may want to define test-specific code in an executable or package that is compiled out of your build products.
- You may want to define code that produces different results depending on if it's being run in tests or not. For example, you may want to ensure a dependency never hits a live server during a test run.
While there are ways of approximating such a check, they are a bit fraught:
- We can use
RELEASEto prevent test code from compiling into release products, but this requires us to regularly build for release to ensure we aren’t accessing debug-only code from release code. Worse, using debug vs. release for this purpose prohibits us from running tests in release mode.
- We can use the process info (arguments, environment) to check for XCTest-specific configuration to determine if XCTest is running, but these environment variables are private details that differ depending on how XCTest is being run (
xcodebuild test), could change at any time, and in some cases aren’t even set (SwiftWasm’s process info is wiped clean).
If we look to Rust, it provides
cfg(test), which can be used to annotate code as being test-only and queried to determine if code is running in a test configuration.
I’d like to propose Swift introduces a similar mechanism that is enabled in
swift test runs, though I’d like to gather a bit of feedback on what such a syntax should look like.