-
-
Notifications
You must be signed in to change notification settings - Fork 120
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
Introduce generic assertAnyView function #198
Conversation
I also created some infix extension functions to make it even easier to write. It extends any Matcher<View>, String or Int (resource). I added a `not` operator to Matcher<View>. I documented the behaviour the best I could. I replaced the in-site code with this function, and applied it to other methods of the BaristaVisibilityAssertions that were not doing any magic.
Hi, mimimi here. On the other hand, I don't agree either with the alias for the |
onView(viewMatcher) | ||
.withFailureHandler(spyFailureHandler) | ||
.check(ViewAssertions.matches(condition)) | ||
} catch (firstError: RuntimeException) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do love the implementation with Kategory, it simplifies a lot the code. I'd love it even more if you separate the Try
s in methods, just to improve readability, something like:
tryToAssertView()
.recoverWith { tryToAssertFirstViewOf() }
.getOrElse { spy... }
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know I hate you, right? 🤣
Ok let me see what I can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the second option too but the key here I think is to see how it is implemented, if it adds a lot of complexity I'd discard it but if it doesn't, go for it!
BTW, I invoke some of the usual contributors like @rocboronat @alorma @sergiandreplace to light us up here 👯♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm starting to think the initial double try/catch is the best solution 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, looks complex... So my call would go for the first implementation with Kategory.
Please please please, don't kill me ❤️
Not mimimi at all. I did those things "because I could". Now it's the moment to think if they make sense or not. How about step 3? |
Actually, what I think I like of the infix is that is clearly separates the view finder and the actual condition. In a long line like |
Step 3 is more like the |
So you go for the more espresso-like syntax. |
Let me share an idea: we love magic when interacting with the views, but we must hate magic when asserting. For example, if I assert if a view is displayed or not, if it's not displayed because of a scroll, for me, the test should fail. We want to be happy and friendly with the interactions, but not with the assertions. By the way, |
Hi! After 1.5 months of holidays and work stuff, I'm back to this PR! I'm going to reset myself and just make the simpler version possible of the discussed changes. There's really no need to experiment with cool Kotlin things here. That way nobody can complain that it's too weird of complex. Muahahaha. About your comment @rocboronat: this doesn't add any more magic to assertions than we already have. We won't try to scroll or anything when asserting. The assertions magic is much simpler than interactions. In this case it's documented in the method JavaDoc:
Which is basically what we did for #37, #68 or #46. What this PR does is apply those same conditions to the rest of assertions and keep the code in one place, instead opening a new issue for each assertion that doesn't work as expected and duplicating the code. The name |
I only kept one extension function: withId(R.id.button).magicAssert(not(isDisplayed())) I think it's the more agreeable one. You guys are ok with that? Now, another topic: the naming. As @rocboronat says, "magicAssert" is a very magic name, which is usually bad. What's the alternative? |
It would be cool to think of ways to use the Kotlin stuff to make the tests more readable, but I agree we should probably discuss that in another PR. And yep, it would be better to find a name that actually describes what the method is doing 😆 How about We could also go for something more generic, that just says this "not as strict as a default Espresso check", like |
I like |
Go for |
❗️❗️❗️ Ok, this is the final proposal❗️❗️❗️ I updated the code, the title and the description. Any last complains? Otherwise, let's merge it! |
Thanks everyone! |
TL;DR:
This method allows asserting that any view on the screen matches a certain condition, without getting the infamous Espresso error
AmbiguousViewMatcherException
.Rationale
We say we do magic for things like views below a scroll or duplicated views on screen. But actually that only work for some Assertions and Interactions, not all of them implement it. E.g.: #107 #46
Solution
In this PR I propose to extract the assertion code to one place, and reuse it everywhere it's needed. (The same should be done for Interactions, see #196).
I created a function to be used like this:
assertAnyView(withId(R.id.button), isDisplayed())
We don't usually expose kotlin APIs, but since this method is intended for internal usage I also added an extension function alias:
withId(R.id.button).assertAny(isDisplayed())