The test runner exited with code 9 before finishing running tests

Viewed 264

What does code 9 signify ( and how to fix the issue ) when Xcode crashes during the execution of WatchOS tests?

Scenario:

I have an XCTestCase that reads around 100 CSV test resource files. These files are comma-delimited, have approximately 6,000 lines, and have an average size of 64K. During my test case, I read these files into memory, and one my one, I verify that the input file ( after some processing ) matches the output file. Here is some code to demonstrate the flow:

import XCTest
@testable import MyWatch_Extension

class MyTest: XCTestCase {
    

    func testMyAlgo() throws {
        let testingData = discoverAvailableTestFiles(filter: "dataset_1");
        XCTAssertGreaterThan(testingData.count, 0, "have data to process")

        for (_, testingEntry) in testingData.enumerated() {
            var input : [Double] = [];
            var expectations : [Double] = [];
            readInputOutputTestData(entries: &input, fileName: testingEntry +  "_input");
            readInputOutputTestData(entries: &expectations, fileName: testingEntry + "_expected_output");
            
            // do something with the input, and store it into results
            let results = MyAglo().doSomething();

            compareResultsAndExpectations(testingEntry: testingEntry, results: results, expectations: expectations);
        }
    }

    func discoverAvailableTestFiles(filter: String) -> Set<String> {
        let bundle = Bundle(for: type(of: self))
        let paths = bundle.paths(forResourcesOfType: "csv", inDirectory: nil);
        var results = Set<String>()
        for path in paths {
            if (path.contains(filter)) {
                let fileNameSubstring = path[path.index(path.lastIndex(of: "/")!, offsetBy: 1)...]
                let qaFileName = fileNameSubstring[...fileNameSubstring.index(fileNameSubstring.lastIndex(of: "_")!, offsetBy: -1)]
                results.insert(String(qaFileName))
            }
        }
        return results;
    }

    func readInputOutputTestData(entries : inout [Double], fileName : String) {
        let bundle = Bundle(for: type(of: self))
        let path = bundle.path(forResource: fileName, ofType: "csv")!
        do {
            let data = try String(contentsOfFile: path, encoding: .utf8)
            let myStrings = data.components(separatedBy: .newlines);
            for idx in 0..<myStrings.count {
                let parts = myStrings[idx].split(separator: ",");
                if (parts.count > 0) {
                    for part in parts {
                        entries.append((part as NSString).doubleValue);
                    }
                }
            }
        } catch {
            print(error)
        }
    }
    
    func compareResultsAndExpectations(testingEntry: String, results: [Double], expectations: [Double]) {
        print("## testing \(testingEntry)");
        XCTAssertEqual(results.count, expectations.count / 3, "mismatch in data count \(testingEntry)")
        var counter = 0;
        for idx in stride(from: 0, to: expectations.count, by: 3) {
            XCTAssertEqual(results[counter], expectations[idx], accuracy: 0.5, "\(idx + 1) value mismatch")
            counter += 1;
        }
    }

}

When I execute the testMyAlgo testcase, I might read the first 20 files, and I get the error message :

The test runner exited with code 9 before finishing running tests.

If I run each file individually or in smaller batches ( maybe only 20 of them, as opposed to the entire loop of 100 ), everything is fine. This leads me to believe that I am exhausting the memory space of the watch or should be executing the test case differently. Any idea what the problem is, or perhaps, how I should re-structure the test case to get away from this error? ( Maybe free resources or something similar before each test case )

1 Answers

You can create a dumb Xcode project that runs on an iPhone and copy/paste only this test to it. If it runs OK, that means you're exceeding the limits on the watch. If that's the case, you can create a framework with your algorithm and run the tests on the framework, and import the framework on your watch extension

Related