Flutter, тесты и CI (ч.2)
Даже с Flutter shit happens. Случается ли это "по-незнанию" или это просто "лыжи не едут" - сказать сложно. А речь пойдет про вид тестирования, описанный в предыдущем посте - golden-тестах, также о том, почему успешный прогон голденов на локальной машине никак не гарантирует успешного прогона в раннере CI.
Начнем сначала и пойдем к концу. Итак, архитектура Flutter... 🙂 Состовляющие Flutter части условно можно разделить на 2 большие группы: платформенная часть и все остальное (включая engine и сам фреймворк). В то время как бОльшая часть фреймворка позволяет нам абстрагироваться от платформеных приколов и делать наши приложения, в платформенной части проиходят не менее интересные вещи: старт потоков, установка surface для отрисовки UI и тд. И в конце концов мы получаем pixel-perfect UI на всех целевых платформах... Так сказали в документации.
Если не драматизировать, то небольшие отличия есть, но в 99.9999999% случаев вы никогда не заметите разницы. Но мы должны вспомнить контекст, в котором мы говорим об этой разнице - golden-тестах. Важно понимать, что такой тест выявляет несоотвествие скриншотов с поразительной точностью, что в свою очередь не позволяет тестам завершиться без ошибок. К счастью, касается это, в основной массе случаев, только виджета Text.
Я столкнулся с этим в ходе поиска ошибки, из-за которой падали мои тесты в пайплайне github actions. Дело в том, что выходные данные тестов зависят от платформы. В частности, известно, что отдельные платформы отображают текст иначе, чем другие. Голдены, которые были созданы на MacOS могут провалить сверку с голденами, созданными на Linux. Поэтому alchemist (который я теперь использую для golden-тестов) явно генерит и разделяет не только платформенные голдены, но и отдельный набор для CI, где базовые шрифты текста заменены на цветные квадраты. Это позволяет тесту оставаться консистентным при прогоне на разных платформах.
Такая вот история о том, как незамысловатая идея покрытия кода тестами приводит к интересным открытиям 😁