-
Notifications
You must be signed in to change notification settings - Fork 4
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
ANDROID-13796 Roborazzi screenshot tests #296
Conversation
build.gradle
Outdated
@@ -27,6 +28,7 @@ buildscript { | |||
plugins { | |||
id 'org.jetbrains.kotlin.android' version '1.5.21' apply false | |||
id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' apply false | |||
id "io.github.takahirom.roborazzi" version '1.5.0' apply false |
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.
just to be sure, the plugin and the library use different versions?
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.
ups, no, good catch, I should have used 1.4.0 in here 0e78b6e As in 1.5.0 I saw that roborazzi also creates compare.png images when there is no difference and that would break the report we do.
Luckily the lib is going to add it's own html reports so we won't have that problem in future releases from 1.7.0 on.
@Config(qualifiers = RobolectricDeviceQualifiers.Pixel5) | ||
open class ScreenshotsTest { | ||
fun compareScreenshot( | ||
node: SemanticsNodeInteraction, | ||
brand: Brand? = null, | ||
darkTheme: Boolean = false, | ||
extra: String = "", | ||
) { | ||
node.captureRoboImage(screenshotName(brand, darkTheme, extra)) | ||
} | ||
|
||
fun compareScreenshot( | ||
node: ViewInteraction, | ||
brand: Brand? = null, | ||
darkTheme: Boolean = false, | ||
extra: String = "", | ||
) { | ||
node.captureRoboImage(screenshotName(brand, darkTheme, extra)) | ||
} | ||
|
||
private fun screenshotName(brand: Brand?, darkTheme: Boolean, extra: String) = ScreenshotUtils.getScreenshotName( | ||
brand = brand, | ||
extra = if (darkTheme) "_dark$extra" else extra | ||
) | ||
} |
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.
totally personal preference, but since those methods doesn't require anything from the class I would move them to pure functions to have as less inheritance as possible
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.
Which ones? The compareScreenshot() ones I like them to be here as it forces the test to inherit from ScreenshotsTest in order to see them and this way we are applying the global config qualifiers. If they weren't here we would probably forget to extend from ScreenshotsTest and that qualifiers would not be applied to that tests so it would be more human error prone. In other words, as it's done now we avoid many possible errors that we could have if moved to pure functions. I didn't want inheritance, I was asked to do that before for the config annotation.
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.
in my opinion there are two things: on one side is the qualifier, that force us to inherit and in the other the base methods. I don't have a strong opinion, so do what you prefer, but I don't think it is needed to add methods to this class (and couple the child tests to it) VS avoiding the inheritance.
Actually, if you ask me I would completely remove the ScreenshotsTest base class and instead add the qualifier to each test, like we do with some other tests like the acceptance.
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.
Agree, but then we'll be back to the initial code in which I was asked not to add the qualifier to each test: #296 (comment) 🤔
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.
Exactly... I'm not a fan of inheritance per se but here I see the same benefits we got from using a base class for unit tests in https://github.com/Telefonica/android-messenger/blob/integration/test-commons/src/main/java/com/tuenti/messenger/test/UnitTest.java to avoid repeating code in tests over and over again (and in for roborazzi, also possible errors to be introduced if we forget to set the qualifier or use a different one)
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.
Yup, in the end we agreed on leaving this base class for screenshot tests to avoid repeating code at least for now unless at some point we find another way to set the default qualifier and then this can be updated.
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.
Is it a good idea to group several elements in one layout? Instead of doing parameterized test of each UI element like the Button example? I think it should be unified
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.
In my opinion it's good offering multiple options and multiple ways to do this. In here we can use the layout from catalog as it has the different inputs and just use that instead of having to recreate the different TextInput states one by one and checking them separately, which would work as well. I'm just leaving more options to the ones creating the tests. With this way we could have mistica tested quite quickly and then decide wether it's worth doing it one by one or just doing it when a component is updated... Wdyt?
But perhaps we could move this to the catalog, I'm going to try that and check how it looks. I'll be back.
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've removed the tests of the layout from the pr, we might want to reintroduce them in the catalog, or not. But I'm leaving them out of the scope for this pr 7416b62
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.
Nice job!
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.
Get the ball rolling!
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.
Great job!
@@ -7,7 +7,7 @@ import com.github.takahirom.roborazzi.captureRoboImage | |||
import com.telefonica.mistica.compose.theme.brand.Brand | |||
import org.robolectric.annotation.Config | |||
|
|||
@Config(qualifiers = RobolectricDeviceQualifiers.Pixel5) | |||
@Config(sdk = [33], qualifiers = RobolectricDeviceQualifiers.Pixel5) |
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.
why is the sdk needed here? what happens if we do not specify it?
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.
It's not really needed, but it seems it's good to specify the sdk in case you want to be able to create the baseline from a different machine than the ci. I've read it might happen than the images not match on the ci if this sdk is not specified, specially if the baseline is created on a different OS than what the CI uses.
This is just the global config value which my understanding is that it can be overridden in the specific tests we want to.
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, +100 to have anything that could be affected by differences in the CI vs local environment specified in the config in order to prevent unexpected errors not related to actual bugs.
📱 New catalog for testing generated: Download |
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.
Great job!! 🚀
🥅 What's the goal?
Add screenshot testing in mística: POC Roborazzi tests -> Jira Task
🚧 How do we do it?
What is missing:
☑️ Checks
🧪 How can I test this?
The test is being run on each commit to this pr for now (Compare Screenshots action), we should be able to run it also on demand once in integration as it has the
workflow_dispatch
as well (apart from being run on each pr).