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

DesignReviewScreenshot feature #601

Open
VladislavSumin opened this issue Dec 2, 2023 · 0 comments
Open

DesignReviewScreenshot feature #601

VladislavSumin opened this issue Dec 2, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@VladislavSumin
Copy link
Collaborator

VladislavSumin commented Dec 2, 2023

Проблема

Сейчас Kaspresso не предоставляет готовых инструментов для автоматизированного дизайн ревью.

Решение

Поддержать возможность автоматизированного дизайн ревью путем попиксельного сравнения скриншотов.

Возможный путь реализации инструмента

Текущие проблемы

  1. DocLocScreenshotTestCase не переиспользует интерфейс Screenshot, вместо него использую свою приватную реализацию (это кажется весьма неожиданным поведением, такой подход может вызывать недоумение, так как переопределение базового интерфейса никак не влияет на работу док&лок тестов) . Эту проблему предлагается решить унификацией интерфейса Screenshot путем добавления туда нового метода и последующей миграции DocLocScreenshotTestCase на использование Screenshot интерфейса.
interface Screenshots {
    <...>

    /**
     * Делает полный скриншот экрана устройства
     */
    fun takeDeviceWindow(tag: String)
}
  1. Нет возможности вешать перехватчики на вызовы Screenshot интерфейса. Это мешает реализовать некоторые возможности Алюра о которых ниже. Интерфейс для перехватчиков мог бы выглядеть так:
interface ScreenshotInterceptor {
    fun beforeScreenshot(tag: String, mode: ScreenshotMode)
    fun afterScreenshot(tag: String, mode: ScreenshotMode, file: File)
    fun onScreenshotError(tag: String, mode: ScreenshotMode, e: Exception)

    // Для примера, можно сделать отдельные методы или наоборот общий метод с этим параметром в Screenshot
    enum class ScreenshotMode {
        SIMPLE,
        FULL,
        WINDOW,
    }
}
  1. Нет перехватчика для DocLocTestCase который бы аттачил все скриншоты к Алюр отчету. Это было бы полезно для удобства анализа скриншотов. Необходимо добавить такой функционал использую интерсептор из пункта 2.

После исправления проблем выше можно приступить к реализации основной фичи.

Реализация основной фичи

  1. Добавляем скриншот компаратор - интерфейс для сравнения двух скриншотов (в предполагаемой реализации сравнивать будем на android девайсе так как это в разы проще и на практике не сильно медленнее, сравнение попиксельное):
interface ScreenshotsComparator {
    fun compare(
        expected: File,
        actual: File,
        diff: File? = null,
        diffColor: Int = Color.MAGENTA,
        accuracy: Float = 0f // разрешенная погрешность при сравнении (сколько пикселей могут отличаться) в %
    ): Boolean
}
  1. Добавляем перехватчики для ScreenshotsComparator аналогично ScreenshotInterceptor.
  2. Добавляем перехватчики для добавления в алюр отчеты отличающихся скриншотов
  3. Добавляем DesignReviewScreenshotTestCase аналогичный по виду DocLocScreenshotTestCase, тут следует рассписать подробнее:
    DesignReviewScreenshotTestCase добавляет новый метод compareScreenshot который можно вызвать в любой момент теста, данный вызов делает скриншот и сравнивает его с эталоном в режиме проверки или обновляет эталон в режиме обновления (режим задается через конструктор). Важная особенность таких сравнений что при провале проверки тест падает не сразу, а после полного прохождения - это необходимо что бы собрать другие отличающиеся скриншоты и не прогонять тест повторно после фикса каждого отдельного скриншота.

Эталоны будут загружаться на устройство либо самим тестом по переданному пути через AdbServer, либо должны быть заранее загружены на устройство сторонней системой.

Выгрузка эталонов может быть реализована с помощью уже существующего механизма выгрузки артефактов.

Отдельно почему сравниваем именно на устройстве?

Сравнивать на устройстве значительно более проще с точки зрения реализации в коде, а так же с точки зрения конфигурации, вся философия Kaspresso строится на выполнении кода тестов на устройстве. Конечно, как вариант, можно реализовать такие проверки внутри adb на стороне хоста, но adb не является обязательным инструментом. Так же такие сравнения на хосте могут вызывать сложности при формировании Alure отчета если он формируется на устройстве.
Касательно производительности сравнения скриншотов, фактически сравнение происходит достаточно быстро и мы не испытывали никаких проблем что бы гонять этот код на устройстве.

P.S. подобный подход (за вычетом отдельных перехватчиков, так как как нам не нужно отделять alure в отдельный модуль) используется у нас уже достаточно длительное время и в целом неплохо себя зарекомендовал.

@VladislavSumin VladislavSumin added the enhancement New feature or request label Dec 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant