Как стать автором
Обновить

Как я перестал беспокоиться и полюбил тестирование React-компонентов

Время на прочтение12 мин
Количество просмотров33K
Всего голосов 13: ↑12 и ↓1+11
Комментарии12

Комментарии 12

Я периодически думаю можно ли делать интеграционные тесты, но на не моковых ответах API.

Цель такая - быть уверенным что все не отвалится не только на "правильных" ответах API, а на тех что есть сейчас.

Юнит-тесты реактовских компонент — невероятно бессмысленная вещь. Очень недалеко от Enterprise FizzBuzz.


Означает ли, что если юнит-тесты пройдут — наши компоненты будут правильно отображаться и работать? Нет, не означает. Да и принципиально не может, потому что всё, что мы проверили — это делают ли наши компоненты в замокированном DOM некоторые вещи, которые мы ожидаем. От этого и до "компонент правильно отображается и работает" — пропасть, со дна которой на тебя смотрят страшные штуки по имени CSS, browser compatibility, и всё вот это.


Означает ли, что если юнит-тесты не пройдут — наши компоненты не будут правильно отображаться и работать? И опять же нифига: на моей практике на каждую сотню случаев отвала юнит-тестов компонентов примерно штук 5 сообщали о реальных проблемах, а остальные 95 — это "я чего-то поменял в компоненте и теперь мне надо поправить тест, чтоб не падал".


Если у вас очень много свободного времени — тогда да, пишите юнит-тесты на компоненты. Если же нет — тестируйте бизнес-логику, а не появление каких-то там элементов в замокированном DOM.

Не соглашусь с вами.

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

Если вам приходится переписывать тесты если не изменился функционал, то у вы пишете странные и бесполезные тесты.

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

И случаев, когда вам в компоненте нужно столько логики, что её уже неплохо бы тестировать — крайне мало. Но поскольку случаи наворачивания логики внутрь компонента обычно (обычно в идеале, а не обычно когда усилиями традиционных "программистов на реакте" в компонентах оказывается весь код проекта) касается специфических разборок с DOM, то даже и тут тестирование этого на ненастоящем игрушечном DOM — бесполезно.


Если же ваша "внутренняя логика" компонента не совершенно примитивна (взяли уже приготовленные данные, отобразили эти данные как есть) и не написана ради оптимизаций и решения сложных проблем DOM — то ей не место внутри компонента.


Если вам приходится переписывать тесты если не изменился функционал, то у вы пишете странные и бесполезные тесты.

Вы статью-то вообще читали? Когда сторона тестов дёргает сторону тестируемого кода через селекторы, завязывающиеся на конкретные теги, классы, или (обоже) тексты — вам неизбежно придётся писать "странные и бесполезные" тесты, которые будут ломаться так сразу, как только в компоненте поменяется хоть что-нибудь по его форме (и плевать, что по смыслу не поменяется ничего).

Во-первых, в контексте rtl тестирование компонентов уже не является юнит. Т.к. рендерит все потомки тестируемого компонента. Во-вторых, что плохого в покрытии веток кода тестами? В-третьих, е2 тесты все равно должны быть. То есть всегда можно выбрать другие типы тестирования не взамен, а в помощь.

Во-первых, в контексте rtl тестирование компонентов уже не является юнит.

Да, и поэтому нужно тащить что-то еще для мокирования компонент (типа enzyme), если уж вы вступили на эту кривую дорожку. А то еще и тесты будут не юнит, а хренпоймичто.


Во-вторых, что плохого в покрытии веток кода тестами?

Ровно то же плохое, что и в лопаньи пузырьков на пленке. То есть, в общем-то ничего, просто само по себе это совершенно бесполезное занятие, на выходе которого имеем только кучу попорченной пленки. А в нашем случае — гору кода, которая ничего полезного не делает, и будет дальше жрать время на поддержку, пока кто-нибудь её не выкинет из проекта нафиг.


В-третьих, е2 тесты все равно должны быть.

Какое отношение это всё имеет к rtl и статье? Я где-то в своем комментарии сказал, что тестов не надо вообще?

мокирования компонент (типа enzyme)

При чём тут мокирование? Если у меня, условно, импорт компонента из mui, то он совершенно обычно зарезолвится в тестовом окружении.

Ровно то же плохое, что и в лопаньи пузырьков на пленке

Неостроумные аналогии не по делу - вот что бесполезно.

Какое отношение это всё имеет к rtl и статье? 

Самое прямое. Речь о тестировании.

Когда сторона тестов дёргает сторону тестируемого кода через селекторы, завязывающиеся на конкретные теги, классы, или (обоже) тексты — вам неизбежно придётся писать "странные и бесполезные" тесты

Вам стоит ознакомиться с философией и позиционированием rtl. С семантикой в html, с доступностью. И потом писать что-то в духе того, что тесты построены не нестабильных селекторах классов. И да, какая проблема с текстами? Если есть intl с дефолтными стрингами, которые, как правило, не меняются. А реальные переводы лежат отдельно или запрашиваются с сервера.

Большинство описанных проблем решены несколько лет назад и активно используется очень многими разработчиками, которые по вашему мнению "лопают пузырики". Пожалуй, только в русском сообществе можно встретить настолько некомпетентное, но переполненное важностью, мнение.

Соглашусь в одном - логику из компонентов нужно выносить.

Если у меня, условно, импорт компонента из mui, то он совершенно обычно зарезолвится в тестовом окружении.

Это зависит исключительно от вашего тестового окружения. Может и не зарезолвиться. Почти все тестовые обвязки умеют (и обильно практикуют) вмешиваться в "обычные резолвы".


Неостроумные аналогии не по делу — вот что бесполезно.

Аналогия совершенно прямая. Вы спросили "что плохого в покрытии веток кода тестами", я вам ответил. Само по себе "покрытие кода" — совершенно бессмысленное занятие, которое само по себе никак не увеличивает качество продукта, ни устойчивость к рефакторингу, ни еще что вы там захотите придумать. Всё, что делает "покрытие кода" — это позволяет вам вывести красивую циферку процента покрытия, которая сама по себе ни о чем не говорит, да и не может.


Самое прямое. Речь о тестировании.

Rtl никак не относится к e2e и принципиально не может.


Пожалуй, только в русском сообществе можно встретить настолько некомпетентное, но переполненное важностью, мнение.

Это всегда очень иронично, когда мне пишут абзац голословного текста, сводящийся к "вы ничего не понимаете в N", а сразу за ним — процитированное ^_^


Большинство описанных проблем решены несколько лет назад и активно используется очень многими разработчиками, которые по вашему мнению "лопают пузырики".

Так что именно решено? Ваши компоненты всегда сверстаны с идеальнейшем соответствием семантике html? Ваши классы никогда не меняются? У вас всегда есть intl с дефолтными болванками текстов? И так в любом вашем проекте?
Если это всё надо, чтоб rtl можно было удобно пользоваться — то я, пожалуй, не буду. В моем мире такая идеальность даже не ночует обычно. А жить как-то надо.


Соглашусь в одном — логику из компонентов нужно выносить.

Что вы тогда собрались в них тестировать? Как они взяли кусок данных и обернули его в <span>? А это точно настолько нетривиально, что без тестов никуда?

Не тестируй библиотеку, тестируй свой код. Для всего скопа языков так говорят. Для мира js не так?

PS: для критичных сценариев есть более верхнеуровневые тесты, предлагаю это не обсуждать обсуждая юниты и их убойность

Не тестируй библиотеку, тестируй свой код. Для всего скопа языков так говорят. Для мира js не так?

Ну так что вы протестируете, взяв реакт-компоненты и rtl?
Море всего, на самом деле, но "своего кода" там будет совсем чуть, а проверять его поведение вы будете внутри вороха абстракций. В то время, как для презентационного слоя единственный критерий прохождения или не прохождения приемки — это чтоб оно всё появилось в реальном браузере и отработало в нем же. Работает ли оно внутри абстракций rtl — это вообще абсолютно никого не волнует.

страшные штуки по имени CSS, browser compatibility, и всё вот это.

Как эти проблемы решает описанный подход?

 остальные 95 — это "я чего-то поменял в компоненте и теперь мне надо поправить тест, чтоб не падал".

У вас то же самое, но глобально. И это только стор и роутер из явных зависимостей. С накрученными по пути контекстами, кастомными хуками, редукс мидлварями и прочим, о каком-то рефакторинге будут говорить разве что шепотом. Тем более, что подобные тесты достаточно слабо защищают от нового кода, скорее от изменения существующего.

тестируйте бизнес-логику,

Как этому противоречат юнит тесты?

Как эти проблемы решает описанный подход?

Какой "описанный подход"?


И это только стор и роутер из явных зависимостей.

Мой "стор" выражается ключевым словом class и никаких зависимостей, не относящихся к работе с данными приложения не требует. А к чему вы тут роутер припахали — для меня вообще загадка. Роутер не относится к работе с данными.


С накрученными по пути контекстами, кастомными хуками, редукс мидлварями и прочим, о каком-то рефакторинге будут говорить разве что шепотом.

Если вы работаете с редаксом — мои соболезнования. Я не работаю и никому не советую этого делать.
Контексты и хуки относятся к реакту, и к работе над данными никогда не привлекаются. Да и не должны. Если вы без реакта не можете написать модельную часть приложения (работу с данными, собссно) — проблема в вас.


Как этому противоречат юнит тесты?

Я где-то написал, что юнит-тесты этому противоречат?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий