Closed
Description
Idea from #608
https://developer.apple.com/reference/xctest/xctwaiter
https://developer.apple.com/reference/xctest/xctwaiterdelegate
What do these do? Are they better? Worse? Internal and Travis CI both support 10.3, so we can start using these, just no idea what they do.
Activity
jessesquires commentedon Apr 3, 2017
lol
modocache commentedon Apr 17, 2017
I don't think the new API will solve the problem you two mentioned in #608; the new API don't have anything to do with timeouts specifically. Maybe use a macro or configuration value that uses a short timeout locally, and a longer timeout on CI?
As for what the new API do, here's a write-up I posted in an internal Facebook-only group:
1. Enforce the order of expectations
You can call
-[XCTestCase waitForExpectatons:timeout:enforceOrder:]
in order to test not only that your expectations were fulfilled, but also that they were fulfilled in a specific order:2. More flexibility when waiting
Until now, if you waited for an expectation that was not fulfilled, your test would fail -- period. Now, by using the new
XCTWaiter
class with anil
XCTWaiterDelegate
, you may receive a result enum instead:This allows you to write tests for whatever you want -- you can verify that expectations are made in an incorrect order, or that expectations are not fulfilled at all.
3. Verifying an expectation is never called
You may have tests such as the following:
This test verifies that the failure callback is never called, but it must wait in order to make sure the failure callback has the opportunity to be called at all.
You may now use the
-[XCTestExpectation inverted]
property to verify that an expectation is not fulfilled:However, please be careful when verifying the order of inverse expectations. The following test is not capable of passing:
Here XCTest naively tries to prove that first
one
is not fulfilled, and thentwo
is fulfilled. You can't prove a negative, so this test is a paradox. In fact, I wouldn't recommend usingenforceOrder
with any inversed expectations: it doesn't make sense to say "I expect X to not happen, then Y to not happen, then Z to happen," and XCTest behaves in unintuitive ways when faced with such expectations.4. Allowing "over-fulfillment" of expectations
By default, expectations assert if they're fulfilled more than once. Use the new
-[XCTestExpectation expectedFulfillmentCount]
and-[XCTestExpectation assertForOverFulfill]
boolean properties to allow them to be fulfilled more than once, or an unlimited number of times.jessesquires commentedon Apr 17, 2017
@modocache 🙌 🙌 🙌 🙌 🙌
looks like (2) and (3) would allow us to rely less on OCMock
rnystrom commentedon Aug 9, 2017
Should we do this?
modocache commentedon Aug 10, 2017
Up to you. I believe there have been a few additions to the
XCTestExpectation
API since I posted above, which I could go into more if you'd like.However, if you're thinking of migrating in order to prevent CI-only failures, then I don't think the new API will help. You'll still have to be mindful of the fact that CI machines are probably more resource-constrained, and so you'll still have to use a different timeout for async tests on CI than when developing.
@jessesquires mentioned other reasons to do this, like using expectations in order to test that certain code paths are not taken. I think that's reasonable, but then again, is OCMock any less stable than XCTest? Both are pretty much fundamental dependencies for nearly every Cocoa/iOS test suite.
My personal take: one could make the argument that rewriting some of the tests with this new XCTest API is a good idea, but I think most people would agree that there are more impactful things to do with your time.
jessesquires commentedon Aug 10, 2017
Especially since we're already invested in using OCMock, I think there's little to gain here. Close?