nallick / UIUTest_Examples

Examples for the UIUTest test framework
MIT License
1 stars 1 forks source link

Example for testing asychnronous operations #1

Open kublaios opened 2 years ago

kublaios commented 2 years ago

Thank you for this project, it's a great demonstration of the power of the UIUTest library.

I wasn't able to find an example for asserting a condition not immediately, The authenticate method, for example, would most likely make a network call and take a few seconds to dismiss the screen in a real world scenario. In that case, something similar to XCUIElement.waitForExistence(timeout:) would come in handy.

Does UIUTest provide this functionality and it's just not used in the examples, or is it something we need to figure out ourselves?

kublaios commented 2 years ago

cc @Tyler-Keith-Thompson as I came here through your great CucumberSwift library and you said in the docs that you use this library and chose not to mock your network calls.

Tyler-Keith-Thompson commented 2 years ago

Yeah, there's 2 methods that I think are reasonable. One is to use expectations if you can, although that may require tying into your code like a unit test in ways you might find undesirable.

The other method that I know of and have used frequently is to use something like this gist: https://gist.github.com/JARinteractive/7fb33b6b0043f365ddfd

It performs passes of the runloop until a condition is met or a timeout is reached. So you could simply wait for an element that way.

FWIW I think the choice on mocking depends on how you want to use these tests. For example, if you intend to write E2E tests that aren't nearly as brittle when it comes to animations or navigation to a particular screen, UIUTest is fantastic. If you want to mock your network layer and use UIUTest for sociable style unit testing, that's a great use-case as well.

kublaios commented 2 years ago

The other method that I know of and have used frequently is to use something like this gist: gist.github.com/JARinteractive/7fb33b6b0043f365ddfd

That's exactly what I had in mind. I'll go with that, thanks.

For example, if you intend to write E2E tests that aren't nearly as brittle when it comes to animations or navigation to a particular screen, UIUTest is fantastic.

Yep, that's more like my use case than the rest. TBH I'm surprised that this library is not so popular considering the issues with XCUI tests.

Last thing before closing the issue, do you think wait until behavior should be a part of the library?

Tyler-Keith-Thompson commented 2 years ago

@nallick it's certainly your call but my $0.02 is @kublaios has a good point.

A general purpose waiter is probably out of scope but given your hit testing logic I could see UIUTest explicitly creating waiters for common needs. Waiting on "willRespondToUser", or for a view to be findable in the hierarchy, or being enabled (which may be different that responding to hits). That sort of thing makes sense.

If it's possible to do it using expectations that's probably ideal. But if not, something along the lines of the linked gist wouldn't be horribly unreasonable given the library already exposes conveniences for doing passes of the run loop.

nallick commented 2 years ago

A general purpose waiter is probably out of scope but given your hit testing logic I could see UIUTest explicitly creating waiters for common needs. Waiting on "willRespondToUser", or for a view to be findable in the hierarchy, or being enabled (which may be different that responding to hits). That sort of thing makes sense.

Yeah that's fair, although I suppose that implies a general purpose waiter needs to exist first. Apple's answer to this is apparently XCTNSPredicateExpectation (e.g., https://www.avanderlee.com/swift/nspredicate-xctestexpectations/), but that seems to use an overly long poll time so that Apple only recommends it in UI tests. I suppose it wouldn't be too hard to recreate with a user specified polling time.