Why does this Swift unit test crash when run in parallel with other tests?
Asked Answered
S

1

6

I have a unit test that succeeds when it is run alone but crashes with an EXC_BAD_ACCESS (most of the time) on waitForExpectations when running alongside other tests.

func testStartMonitoring() {

    let mockLocationManager = MockLocationManager()
    let beaconListener = BeaconListener(locationManager: mockLocationManager, uuid: BeaconListenerTests.defaultUUID)

    let e = self.expectation(description: "Expected beacons to be detected")

    //If the listener calls back, the expectation succeeds.
    beaconListener.didReceiveNewRoomInformation = { data in

        //There are three entries in the test data
        XCTAssert(data.count == 3)

        e.fulfill()
    }

    //Start listening
    beaconListener.startListening()

    //Wait up to 15s for a response
    self.waitForExpectations(timeout: 15.0, handler: {error in
        if let error = error {
            print("\(error)")
        }
    })
}

enter image description here enter image description here

  • I have no other async tests
  • The test never fails due to exceeded timeout
  • Since the test only crashes some of the time, I expect that the problem is a race condition somewhere, but I'm unsure where to look.

I've been able to reproduce this with simpler code too:

func testStartMonitoring() {

    let e = self.expectation(description: "Expected beacons to be detected")

    let deadlineTime = DispatchTime.now() + .seconds(1)
    DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
        e.fulfill()
    }

    //Wait up to 15s for a response
    self.waitForExpectations(timeout: 15.0, handler: {error in
    })
}

I ran the tests from the command line and found this extra piece of information:

Error Domain=IDETestOperationsObserverErrorDomain Code=5 "Early unexpected exit, operation never finished bootstrapping - no restart will be attempted" UserInfo={NSLocalizedDescription=Early unexpected exit, operation never finished bootstrapping - no restart will be attempted}

Some other answers indicate that this may be caused by system alerts. This is understandable, I am using location services which requires a permissions alert. However, the devices on which I'm running the tests already have accepted the permissions and therefore shouldn't be showing the alerts.

Sarad answered 14/11, 2016 at 8:39 Comment(6)
testStartMonitoring() doesnot crash in mineWells
@Anish웃, did you run it alongside other tests? That appears to be the crux of the problem.Sarad
Yes...in deed i copied that function in another file and tested the project..Doesn't crash at all..Wells
I'm not sure where to look for the problem then. Any suggestions?Sarad
Here it says as "This method creates a point of synchronization in the flow of a test. Only one waitForExpectations(timeout:handler:) can be active at any given time"Wells
Yes, I saw that, but as I indicate, I only have one async test.Sarad
S
2

I had a similar problem - a set of tests with multiple expectations crashing - and came across your question. It made me realize that its the permissions causing the problem - here for location manager, and speech recognition for me. So I mocked my authorization request class and injected a positive response.

You have to go searching for methods that are calling whatever it is that requires permission - they may or may not be the ones with expectations.

Slash answered 20/8, 2019 at 19:0 Comment(1)
I also encounter this issue when photo permission dialog pops up.Aras

© 2022 - 2024 — McMap. All rights reserved.