An ActivityScenario extension and a Junit4 TestRule to simulate changing the font size on a device/emulator, as it would be done by going to Settings > display > Font size

Overview

FontSizeActivityScenario and FontSizeTestRule

An ActivityScenario and a Junit4 TestRule to be used together with its org.junit.runners.Parameterized. It simulates changing the font size on a device/emulator, as it would be done by going to "Settings > display > Font size"

This helps to write snapshot tests that can catch visual regresion bugs like this one

FONT SIZE NORMAL FONT SIZE HUGE

This library has been mentioned in

  1. Kotlin Weekly #266

You can read more about it in my series on snapshot testing, featured in :

  1. Android Weekly #479
  2. .kotlinTesting (September 2021)
  3. Software Testing Notes #20
  4. Test Automation Weekly #8

Integration

To integrate FontSizeTestRule into your project:

Add jitpack to your root build.gradle file:

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Add a dependency to build.gradle

dependencies {
    androidTestImplementation 'com.github.sergio-sastre:FontSizeTestRule:v1.0.1'
}

or if you want to try the FontSizeActivityScenario or use the FontScaleTestRules reliably on any API level:

dependencies {
    androidTestImplementation 'com.github.sergio-sastre:FontSizeTestRule:v1.1.0-SNAPSHOT'
}

What to keep in mind

Prefer FontSizeActivityScenario to FontSizeTestRule. That is because Google deprecated resources.updateConfiguration(resources.configuration, metrics) on API 25+, and the test rule is based on that method. Therefore, previous to v1.1.0-SNAPSHOT, the TestRule does not work on devices/emulators running 25+. In order to solve this, from 25+, the rule will execute the corresponding adb shell command to change the font size:
"settings put system font_scale ${fontScale.value}
However, this has the drawback that the font size change does not happen immediately, making your tests run more slow.

This issue is overcome by using FontSizeActivityScenario.launchWith(fontScale), currently available on 'com.github.sergio-sastre:FontSizeTestRule:v1.1.0-SNAPSHOT'. The only inconvenient is that you cannot snapshot-test your own activities with it. That is because in order to use resources.updateConfiguration(resources.configuration, metrics) replacement, we need to override attachBaseContext() in an activity.

Summary

FontSizeActivityScenario FontSizeTestRule
Any API < API 25, otherwise might be more slow
Cannot snapshot-test Activities Can snapshot-test any View
Preferred over FontSizeTesRule Recommended only to snapshot Activites

Usage

If you are using FontSizeActivityScenario you need to add the following activities to your debug/manifest

<application
        ...
   <activity android:name="sergio.sastre.fontsize.SmallFontSizeActivity"></activity>
   <activity android:name="sergio.sastre.fontsize.NormalFontSizeActivity"></activity>
   <activity android:name="sergio.sastre.fontsize.LargeFontSizeActivity"></activity>
   <activity android:name="sergio.sastre.fontsize.HugeFontSizeActivity"></activity>
</application>

in order to test Jetpack Compose views, use createEmptyComposeRule() together with FontSizeActivityScenario as follows:

@get:Rule
val composeTestRule = createEmptyComposeRule()

@Test
fun composeWithFontSizeTest() {
    FontSizeActivityScenario.launchWith(testItem.fontScale).onActivity {
            it.setContent {
                myComposeView()
            }
        }

    compareScreenshot(composeTestRule, name = testItem.testName)
}

You can find some test samples of FontSizeActivityScenario and FontScaleTestRule in the Road to Effective Snapshot Testing repo:

  1. FontActivityScenario -> in the DeleteDialogTest.kt file.
  2. FontScaleTestRule -> also in the DeleteDialogTest.kt file.
You might also like...
Espresso - Use Espresso to write concise, beautiful, and reliable Android UI tests
Espresso - Use Espresso to write concise, beautiful, and reliable Android UI tests

Espresso Use Espresso to write concise, beautiful, and reliable Android UI tests

A set of TestRules and ActivityScenarios to facilitate UI Testing under given configurations: FontSizes, Locales

AndroidUiTestingUtils A set of TestRules, ActivityScenarios and utils to facilit

Setup CheckStyle, FindBugs, PMD and Lint for your Android project easily

android-quality-starter setup CheckStyle, FindBugs, PMD and Lint for your Android project easily This project adds gradle setup for quality tools ment

This is a specified proportion to the size of the Layout or View support library, with which you can easily set a fixed ratio of the size of the Layout or View, internal adaptive size calculation, completely abandon the code to calculate the size! If you have any questions in the course or suggestions, please send an e-mail to the following e-mail, thank you! a set of Settings like composable items to help android Jetpack Compose developers build complex settings screens
a set of Settings like composable items to help android Jetpack Compose developers build complex settings screens

This library provides a set of Settings like composable items to help android Jetpack Compose developers build complex settings screens without all the boilerplate

An example for who are all going to start learning Kotlin programming language to develop Android application.

Kotlin Example Here is an example for who are all going to start learning Kotlin programming language to develop Android application. First check this

Registration validation testing, Room database testing using JUnit4
Registration validation testing, Room database testing using JUnit4

Notes app Registration details validation testing, Room database testing using JUnit4 ✨ Screenshots Authors Tridev Deka - LinkedIn - Tridev Deka MIT L

Android Kotlin+ MVVM + Retrofit2 + Room +Dagger2 + Coroutines + Junit4 + Espresso + Mockito + MockWebServer

Movies-TMDB Android Kotlin+ MVVM + Retrofit2 + Room +Dagger2 + Coroutines + Junit4 + + Espresso + Mockito + MockWebServer Movies-TMDB Android Movies-T

Custom font library for android | Library to change/add font of Entire Android Application at once without wasting your time - TextViews, EditText, Buttons, Views etc.,

AppFontChanger In a Single shot change font of Entire Android Application - TextViews, EditText, Buttons, Views etc., Kindly use the following links t

A TextView that automatically fit its font and line count based on its available size and content
A TextView that automatically fit its font and line count based on its available size and content

AutoFitTextView A TextView that automatically fit its font and line count based on its available size and content This code is heavily based on this S

A TextView library that allows the user to increase/decrease font size with a two finger gesture by the user.
A TextView library that allows the user to increase/decrease font size with a two finger gesture by the user.

PinchZoomTextView Library This library allows you to have a TextView that will grow/shrink the font size using gestures from the user. Usage To have a

Events Calendar is a user-friendly library that helps you achieve a cool Calendar UI with events mapping. You can customise every pixel of the calendar as per your wish and still achieve in implementing all the functionalities of the native android calendar in addition with adding dots to the calendar which represents the presence of an event on the respective dates. It can be done easily, you are just a few steps away from implementing your own badass looking Calendar for your very own project!
An extension of Android's TextView, EditText and Button that let's you use the font of your choice

AnyTextView (deprecated) Note: AnyTextView is no longer being maintained. I recommend replacing AnyTextView with the Calligraphy library instead. Frus

Android-ScrollBarPanel allows to attach a View to a scroll indicator like it's done in Path 2.0
Android-ScrollBarPanel allows to attach a View to a scroll indicator like it's done in Path 2.0

Path 2.0 like ScrollBarPanel for Android Android-ScrollBarPanel allows to attach a View to a scroll indicator like it's done in Path 2.0. Features Sup

Tork is a quiz Application done in android
Tork is a quiz Application done in android

Tork(Quiz game app) A simple mini quiz game app about programming languages. About The app is a sample quiz with integration of Firebase. The categori

Modern GTD(Get Things Done) Android App
Modern GTD(Get Things Done) Android App

Neo Flow A modern GTD Android App to improve your workflow Explore the docs » View Demo · Report Bug · Request Feature Table of Contents About The Pro

AutosizeEditText for Android is an extension of native EditText that offer a smooth auto scale text size.
AutosizeEditText for Android is an extension of native EditText that offer a smooth auto scale text size.

AutoscaleEditText AutosizeEditText for Android is an extension of native EditText that offer a smooth auto scale text size. Latest Version How to use

A set of web-based tools for generating graphics and other assets that would eventually be in an Android application's res/ directory.

Android Asset Studio Open the Android Asset Studio See the older version if you're having trouble with the new version A web-based set of tools for ge

Android view that allows the user to create drawings. Customize settings like color, width or tools. Undo or redo actions. Zoom into DrawView and add a background.
Android view that allows the user to create drawings. Customize settings like color, width or tools. Undo or redo actions. Zoom into DrawView and add a background.

DrawView Android view that allows the user to create drawings. Draw anything you like in your Android device from simple view. Customize draw settings

Comments
  • Compose error on snapshot version

    Compose error on snapshot version

    Hello, I've prepared a compose branch when sometimes there is an error when running the snapshot tests. It happened in API 28 and API 30, I'm not sure if this is strictly related to this library, however when running the tests with my hack this didn't occur. Maybe it's related to compose flakiness, and the hacky timeouts mitigated it.

    The command:

    ./gradlew executeScreenshotTests -Precord 
    

    The error has the following stack trace:

    java.lang.IllegalStateException: No compose views found in the app. Is your Activity resumed?
    at androidx.compose.ui.test.TestContext.getAllSemanticsNodes$ui_test_release(TestOwner.kt:96)
    at androidx.compose.ui.test.SemanticsNodeInteraction.fetchSemanticsNodes$ui_test_release(SemanticsNodeInteraction.kt:82)
    at androidx.compose.ui.test.SemanticsNodeInteraction.fetchOneOrDie(SemanticsNodeInteraction.kt:155)
    at androidx.compose.ui.test.SemanticsNodeInteraction.fetchSemanticsNode(SemanticsNodeInteraction.kt:106)
    at androidx.compose.ui.test.AndroidImageHelpers_androidKt.captureToImage(AndroidImageHelpers.android.kt:40)
    at com.karumi.shot.compose.SemanticsNodeBitmapGenerator.generateBitmap(SemanticsNodeBitmapGenerator.kt:12)
    at com.karumi.shot.compose.ScreenshotSaver.getBitmapFromScreenshotToSave(ScreenshotSaver.kt:28)
    at com.karumi.shot.compose.ScreenshotSaver.saveScreenshot(ScreenshotSaver.kt:19)
    at com.karumi.shot.compose.ComposeScreenshot.saveScreenshot(ComposeScreenshot.kt:22)
    at com.karumi.shot.ScreenshotTest$DefaultImpls.compareScreenshot(ScreenshotTest.kt:144)
    at sergio.sastre.testing.ButtonTest.compareScreenshot(ButtonTest.kt:21)
    at com.karumi.shot.ScreenshotTest$DefaultImpls.compareScreenshot(ScreenshotTest.kt:116)
    at sergio.sastre.testing.ButtonTest.compareScreenshot(ButtonTest.kt:21)
    at sergio.sastre.testing.ButtonTest.buttonIsShownProperly(ButtonTest.kt:82)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at sergio.sastre.fontsize.testrule.FontScaleTestRule$FontScaleStatement.evaluate(FontScaleTestRule.kt:36)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at androidx.compose.ui.test.junit4.AndroidComposeTestRule$AndroidComposeStatement.evaluateInner(AndroidComposeTestRule.android.kt:343)
    at androidx.compose.ui.test.junit4.AndroidComposeTestRule$AndroidComposeStatement.evaluate(AndroidComposeTestRule.android.kt:332)
    at androidx.compose.ui.test.junit4.android.EspressoLink$getStatementFor$1.evaluate(EspressoLink.android.kt:48)
    at androidx.compose.ui.test.junit4.IdlingResourceRegistry$getStatementFor$1.evaluate(IdlingResourceRegistry.jvm.kt:160)
    at androidx.compose.ui.test.junit4.android.ComposeRootRegistry$getStatementFor$1.evaluate(ComposeRootRegistry.android.kt:150)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2205)
    
    opened by AKJAW 9
  • Problem with Emulators with API 26+

    Problem with Emulators with API 26+

    Hello, I couldn't find any guidelines for issues so I'll just explain the problem I'm experiencing.

    I have a Jetpack Compose project for which I want to try out Snapshot testing. I was following the README for the RoadToEffectiveSnapshotTesting project and created a parameterized test where the font changes.

    Shot only supports API's 26+ to create a screenshot for composables. However when I tried using this TestRule on API 26, 28 and 30 the font did not change. Neither in my own project nor in the RoadToEffectiveSnapshotTesting one.

    I'm not sure if this is a problem with my machine / emulators or the TestRule. I wasn't able to debug the TestRule because I only had access to the decompiled sources (maybe it would be possible to expose the source code through the library to make debugging easier?).

    My current hack to change the font looks like this:

    @Before
    fun setUp() {
        InstrumentationRegistry
            .getInstrumentation()
            .uiAutomation
            .executeShellCommand("settings put system font_scale ${data.fontScale.value}")
            .apply {
                Thread.sleep(2000)
                close()
            }
    }
    
    @After
    fun tearDown() {
        InstrumentationRegistry
            .getInstrumentation()
            .uiAutomation
            .executeShellCommand("settings put system font_scale 1.0")
            .apply {
                Thread.sleep(1000)
                close()
            }
    }
    

    But this is only an temporary solution 😄

    opened by AKJAW 7
  • #issue1/not working from api26+

    #issue1/not working from api26+

    1. FontSizeTestRule - Uses adb command to change font size on API25+. This makes tests a bit more slower though

    2. Add FontSizeActivityScenario - Works fast and reliably, however one cannot test full Activities with it. Serves the purpose for fragments, views, dialogs, view holders, and composable though (warning: I have not tested it with all of them)

    opened by sergio-sastre 0
Releases(v1.1.1)
  • v1.1.0-SNAPSHOT(Sep 5, 2021)

    This pre-release:

    • FontSizeTestRule: Changes the font size via adb command on devices and emulators running API 25+. However, this might make the tests run a bit more slowly on them
    • Adds FontSizeActivityScenario for alternatively changing the font size via code through an ActivityScenario on any API. It basically opens an empty activity with the context configure with the proper font scale, and snapshots the target views in it. Has the drawback that it cannot be used to snapshot test our own activities.
    Source code(tar.gz)
    Source code(zip)
Owner
Sergio Sastre Flórez
I make things happen
Sergio Sastre Flórez
Selenium WebDriver and Appium based Web, Mobile (Android, iOS) and Windows desktop Automation Framework with BDD & Non-BDD implementation support

Selenium WebDriver and Appium based Web, Mobile (Android, iOS) and Windows desktop Automation Framework with BDD & Non-BDD implementation support

null 10 Dec 5, 2022
Powerful, elegant and flexible test framework for Kotlin with additional assertions, property testing and data driven testing

Kotest is a flexible and comprehensive testing tool for Kotlin with multiplatform support. To learn more about Kotest, visit kotest.io or see our quic

Kotest 3.8k Jan 3, 2023
A tool for scan and replace file content. Instead of global search and replace, it can specify replace scope

ScanReplace.kt A tool for scan and replace file content Instead of global search and replace, it can specify replace scope Usage java -jar ScanReplace

CWKSC 4 Jan 27, 2022
A collection of tests and easy to reuse pieces of code for bdk-jvm and bdk-android

Readme This repo is a collection of tests and easy to reuse pieces of code for bdk-jvm and bdk-android. Note that they don't aim to provide a full cov

thunderbiscuit 1 Jun 28, 2022
Library to simplify and speed up the creation and work with adapters with payload.

Novalles Library to simplify and speed up the creation and work with adapters with payload. How to use Annotate your UI model with UIModel Annotation.

Бырна Алексей 3 Oct 11, 2022
Control and manage Android devices from your browser.

Warning This project along with other ones in OpenSTF organisation is provided as is for community, without active development. You can check any othe

STF 12.7k Jan 6, 2023
null 866 Dec 27, 2022
TestObserver to easily test LiveData and make assertions on them.

JCenter Update LiveData Testing is currently published on JCenter - it will serve packages until February 1st, 2022. LiveData Testing packages will be

Josef Raska 395 Dec 8, 2022
Barista makes developing UI test faster, easier and more predictable. Built on top of Espresso

Barista makes developing UI test faster, easier and more predictable. Built on top of Espresso, it provides a simple and discoverable API, removing most of the boilerplate and verbosity of common Espresso tasks. You and your Android team will write tests with no effort.

Adevinta Spain 1.6k Jan 5, 2023
A JUnit5 Platform TestEngine integrated with the official FHIR Validator to run profile and Questionnaire validation as tests.

?? FHIR Validator JUnit Engine A JUnit5 TestEngine to integrate the FHIR Validator into the JUnit5 ecosystem. Supports writing expected validation out

NAV IT 2 Feb 2, 2022