Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better IdlingResources #295

Closed
diogosq opened this issue May 6, 2019 · 12 comments
Closed

Better IdlingResources #295

diogosq opened this issue May 6, 2019 · 12 comments

Comments

@diogosq
Copy link

diogosq commented May 6, 2019

It's just a suggestion to add

Based on the old wait / timeout resource talk [241] (#241)

I created an Kotlin extension to wait any assert block with lambda function.Example espresso code if available

fun BaristaVisibilityAssertions.assertTimeout(timeoutSeconds: Int, assert: () -> Unit) {
    val startTime = System.currentTimeMillis()
    val endTime = startTime + TimeUnit.MILLISECONDS.convert(timeoutSeconds.toLong(), TimeUnit.SECONDS)

    do {
        try {
            assert()
            break
        } catch (e: BaristaException) {
            //Not click
            BaristaSleepInteractions.sleep(1, TimeUnit.SECONDS)
        } catch (ae: AssertionFailedError) {
            //Not enable
            BaristaSleepInteractions.sleep(1, TimeUnit.SECONDS)
        }

    } while (System.currentTimeMillis() < endTime)

    // timeout happens
    if (System.currentTimeMillis() > endTime) {
        throw TimeoutException("TIMEOUT:wait for a specific view to click. Waiting during $timeoutSeconds seconds.")
    }
}
@Sloy
Copy link
Member

Sloy commented May 17, 2019

Hi @diogosq! Sorry for not getting back to you sooner.

It's a cool idea, but it looks like a workaround for not using IdlingResources in the right way. I get that sometimes it's hard to integrate them into existing code and workarounds are necessary, but I wouldn't encourage them from Barista.

@Sloy Sloy closed this as completed May 17, 2019
@CarsonRedeye
Copy link

CarsonRedeye commented Mar 17, 2022

I would encourage this to be reviewed. Maybe this could be added as a different project. IMO IdlingResources is not a good API, since it is artificially changing your production code to pass a test. Instead, asserting a timeout on a view becoming visible is testing user experience more directly

@rocboronat
Copy link
Member

But in the case the issuer shows where he just needs to wait for a view to become visible you can just use BaristaSleepInteractions.sleep(5, TimeUnit.SECONDS), can't you?

@CarsonRedeye
Copy link

Yes, but that means the test always waits for the full 5 seconds. The suggestion above only waits 1 second (could be shorter). This can dramatically speed up tests running time.

@rocboronat
Copy link
Member

I don't know... it feels very patchy. Let me think about it but this issue has been open for three years, nobody gave a +1 until today, it smells as a hack you can just copypaste to your project, is easily replacable with a single line Barista currently offers that is 100% reliable...

Take into account that saving a second or two in a test is not the focus of Barista. We want to develop reliable and easy to read tests faster. The method of this issue adds confusion to the reader I think.

The solution we give right now is do A, wait 5 seconds, do B. It's superstraightforward.

@diogosqueiroz
Copy link

If I still remember well, I created this solution for tests that had a query for resources that could have large variations in response time (from 2s to 1min for example).
Not waiting the maximum time for each call guaranteed me more than an hour in a full test round.
That was the need at the time and the solution was very productive and useful for me.

@rocboronat
Copy link
Member

But if you had a query like that, why not using IdlingResources, which is the reliable way to do it?

Barista and its sleep() method is not aimed to replace the regular Espresso IdlingResources. If you have a two seconds animation or something very simple like it it's ok to use the sleep(), but for background tasks you should use the IdlingResources, which work very well.

@diogosqueiroz
Copy link

Please do not misunderstand me. I like the solution with IdlingResource.
But in some cases I didn't have access to the components responsible for the resources to add an IdlingResource.increment/decrement.

@diogosqueiroz
Copy link

My intention was never to replace IdlingResource but to create a slightly cleaner alternative for some specific situations.

@rocboronat
Copy link
Member

Hum, in case your scenario has those untestable things I totally understand you and feel your pain, hehe! But I think adding this to Barista will lead people to avoid using IdlingResources and use this approach instead. If anyone needs it that bad, let them get influenced by your approach and add it directly to their project 😅

@CarsonRedeye
Copy link

CarsonRedeye commented Mar 17, 2022

Fair enough the idea might not be best for the scope of Barista. I may make a repo myself as an add-on. Here's my modification on @diogosq code. It is working very well for me so far. It is much faster to write than dealing with IdlingResources and, as I mentioned, I feel it more closely tests the actual user experience.

fun retryUntilTimeout(duration: Duration = 5.seconds, assert: () -> Unit) {
    val startTime = System.currentTimeMillis()
    val endTime = startTime + duration.inWholeMilliseconds

    var latestException: Throwable? = null
    do {
        try {
            assert()
            break
        } catch (e: Throwable) {
            // Not clicked
            latestException = e
            // Try every half a second until assertion passes. Could be decreased to speed up tests slightly
            BaristaSleepInteractions.sleep(500, TimeUnit.MILLISECONDS)
        }

    } while (System.currentTimeMillis() < endTime)

    if (System.currentTimeMillis() > endTime) {
        throw Throwable("Timed out waiting for assertion to pass. Waited $duration.", cause = latestException)
    }
}

@Sloy
Copy link
Member

Sloy commented Mar 17, 2022

My 2 cents: If your issue is with Idling Resources API, check out https://github.com/americanexpress/busybee. I haven't used it myself, but I would strongly consider it if I had to implement our testing infrastructure again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants