Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to let the app know if it's running Unit tests in a pure Swift project?

One annoying thing when running tests in Xcode 6.1 is that the entire app has to run and launch its storyboard and root view controller. In my app this runs some server calls that fetches API data. However, I don't want the app to do this when running its tests.

With preprocessor macros gone, what's the best for my project to be aware that it was launched running tests and not an ordinary launch? I run them normally with command + U and on a bot.

Pseudocode:

// Appdelegate.swift if runningTests() {    return } else {    // do ordinary api calls } 
like image 884
bogen Avatar asked Dec 16 '14 09:12

bogen


People also ask

How do I run a unit test case in Swift?

To create new unit case in iOS, go to File -> New -> File, and then select Unit Test Case Class. Doing so creates a template just like the one you got with your project. In our case, we want to name the file to correspond with the new Pokemon-related data structures we have introduced.

How do I get unit test report in Xcode?

You can find it under the Reports navigator. (View menu > Navigators > Reports or ⌘ - command + 9 ). After you open it, under the latest Test report, you should find a Coverage report, click on that, and it will contain the coverage information of that test run.

How do I add unit tests to an existing Xcode project?

To add a unit test target to an existing Xcode project, choose File > New > Target. Select your app platform (iOS, macOS, watchOS, tvOS) from the top of the New Target Assistant. Select the Unit Testing Bundle target from the list of targets.


2 Answers

Elvind's answer isn't bad if you want to have what used to be called pure "Logic Tests". If you'd still like to run your containing host application yet conditionally execute or not execute code depending on whether tests are run, you can use the following to detect if a test bundle has been injected:

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

I used a conditional compilation flag as described in this answer so that the runtime cost is only incurred in debug builds:

#if DEBUG     if NSProcessInfo.processInfo().environment["XCTestConfigurationFilePath"] != nil {         // Code only executes when tests are running     } #endif 

Edit Swift 3.0

if ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil {     // Code only executes when tests are running } 
like image 57
Michael McGuire Avatar answered Oct 16 '22 22:10

Michael McGuire


I use this in application:didFinishLaunchingWithOptions:

// Return if this is a unit test if let _ = NSClassFromString("XCTest") {     return true } 
like image 35
Jesse Avatar answered Oct 17 '22 00:10

Jesse