XCTest test reporting

Using the XCTest (or XCUITest) test framework? Follow the instructions below to report results. If you are not using XCTest please see the Swift docs for integrating with a lower-level library.

An alternative way to report results if you do not want to follow the instructions below is to utilize the JUnit XML output from XCTest but the method below is recommended because you can also upload files that way.


Add the tesults-xctest-observer package as a dependency to your project. Search for tesults-xctest-observer in Xcode to find the package.


Ensure you install version 1.0.6 or higher. You can verify the version you have installed by checking package dependencies.


If you see a build error related to XCTest not being found, ensure the 'Enable Testing Search Paths' option is set to Yes for your app target.



You are required to register the tesults-xctests-observer at the startup of your tests as described in the overview section for XCTestsObservationCenter. Specifically this requires creating a new Swift class that at a minimum does the following:

//  Start.swift
//  iphone-app

import Foundation
import XCTest
@testable import tesults_xctest_observer

class Start : NSObject {
  override init () {
    XCTestObservationCenter.shared.addTestObserver(TesultsXCTestObserver(target: "token"))

The 'token' value above should be replaced with your Tesults target token. If you have lost your token you can regenerate one from the config menu.

Now set the NSPrincipalClass key in your Info.plist to the class you created to register the observer:


Basic configuration complete

When you run your XCTest/XCUITest test cases now the Tesults observer will be registered and upload results to the target in your project that your token value maps to.

If Tesults upload does not take place check your terminal output in Xcode to see whether there is an error message related to not being able to find the NSPrincipalClass you specified. This error must be resolved. A couple of things to check. First ensure your NSPrincipalClass is in the Compile Sources list of Build Phases for your target:


If the above is correct, then you likey have an issue with the name itself. This needs to be the name of your target followed by a dot and the name of the class you are using as your NSPrincipalClass.


Files generated by tests

Attach files during a test using the tesults-xctests-observer file function (example below). Files attached this way will be automatically uploaded to Tesults for reporting.

Example of tesults-xctests-observer test code attaching files. Any files attached in this way in your tests will be automatically uploaded to Tesults.
import tesults_xctest_observer

// Run this code inside a test function otherwise replace the
// 'self' reference with a reference to the running test

TesultsXCTestObserver.file(testCase: self, path: "full/path/to/file/screenshot.png")
TesultsXCTestObserver.file(testCase: self, path: "full/path/to/file/log.txt")

Caution: If uploading files the time taken to upload is entirely dependent on your network speed. Typical office upload speeds of 100 - 1000 Mbps should allow upload of even hundreds of files quite quickly, just a few seconds, but if you have slower access it may take hours. We recommend uploading a reasonable number of files for each test case. The upload method blocks at the end of a test run while uploading test results and files. When starting out test without files first to ensure everything is setup correctly.

TesultsXCTestObserver parameters



Required arg to upload to Tesults, if this arg is not provided the reporter does not attempt upload, effectively disabling it. Get your target token from the configuration menu in the Tesults web interface.

TesultsXCTestObserver(target: "token")



Use this to report a build version or name for reporting purposes.


Use this to report the build result, must be one of [pass, fail, unknown].


Use this to report a build description for reporting purposes.


Use this to report a build failure reason.

Example with all parameters supplied
    target: "token",
    buildName: "1.0.0",
    buildDescription: "build description here",
    buildResult: "fail",
    buildReason: "Failure reason here"

Result Interpretation

Result interpretation is not currently supported by this integration. If you are interested in support please contact help@tesults.com.

Consolidating parallel test runs

If you execute multiple test runs in parallel or serially for the same build or release and results are submitted to Tesults within each run, separately, you will find that multiple test runs are generated on Tesults. This is because the default behavior on Tesults is to treat each results submission as a separate test run. This behavior can be changed from the configuration menu. Click 'Results Consolidation By Build' from the Configure Project menu to enable and disable consolidation by target. Enabling consolidation will mean that multiple test runs submitted with the same build name will be consolidated into a single test run.

Dynamically created test cases

If you dynamically create test cases, such as test cases with variable values, we recommend that the test suite and test case names themselves be static. Provide the variable data information in the test case description or other custom fields but try to keep the test suite and test name static. If you change your test suite or test name on every test run you will not benefit from a range of features Tesults has to offer including test case failure assignment and historical results analysis. You need not make your tests any less dynamic, variable values can still be reported within test case details.

Proxy servers

Does your corporate/office network run behind a proxy server? Contact us and we will supply you with a custom API Library for this case. Without this results will fail to upload to Tesults.

Have questions or need help? Contact us