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

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

То о чём вы пишете — это не модульные, а компонентные тесты, которые покрывают все кейсы модульных и интеграционных. Я как раз недавно писал разъясняющую этот вопрос статью.


Вам не удалось показать сложность предметной области. Те пара приведённых вами скриншотов не выглядят чем-то архи сложным. Тем не менее я немного знаком с БЭМ стеком, поэтому охотно верю, что вам действительно пришлось написать 800 компонент, накопипастить 250 000 CLOS и 56Мб кода, на поддержку которых требуется 16 разработчиков с утро до ночи добавляющих новый код без надежды на рефакторинг. Но это особенность вашего инстумента, а не предметной области. Добавьте какой-нибудь Redux и кода волшебным образом станет ещё больше, без какого-либо прироста функциональности.


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


Часто никакая подготовка не нужна. Например, когда тестируется функция:


console.assert( Math.pow( 2 , 3 ) === 8 )

Не менее часто действие заключается именно в подготовке:


wizard.nextStep().nextStep()
console.assert( wizard.passport.isVisible === true )

А ещё не редко необходимо проверять правильно ли мы выполнили подготовку дополнительной поверкой в середине:


wizard.nextStep().nextStep()
console.assert( wizard.passport.isVisible === false )

wizard.toggleRegistration()
console.assert( wizard.passport.isVisible === true )

А бывает, что и проверка не нужна, ибо сам факт успешного выполнения кода достаточен:


localStorage // local storage is available

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

Привет! Вы правы, что не показаны сложные кейсы. Идея была — на примере простых кейсов показать, как тестировать код, зависящий от API браузера.

это особенность вашего инстумента, а не предметной области

Здесь не могу с вами согласиться. Можете привести аргументы?

Берём первый попавшийся пример и видим:


{
    block: 'button',
    mods: { theme: 'islands', size: 's' },
    text: 'button',
    icon: { block: 'icon', mods: { action: 'download' } }
},
' ',
{
    block: 'button',
    mods: { theme: 'islands', size: 's' },
    icon: { block: 'spin', mods: { theme: 'islands', size: 'xs', visible: true } },
    text: 'Loading...'
},

Как это могло бы быть:


<= Download $mol_button sub /
    <= Download_icon $mol_icon_load_down
    <= Download_text @ \button
<= Loading $mol_button sub /
    <= Loading_icon $mol_icon_spin
    <= Loading_text @ \Loading...
Вам не удалось показать сложность предметной области.

Хорошо же, когда сложная тема просто объясняется?)
Зачем нужен headless chrome, если есть jsdom и тесты можно запускать без имитации браузера вообще? Более того решаются сразу проблемы с бандлингом, поскольку мы выполняем тесты в nodejs — все реквайры и импорты (после бейбла) работают нативно.

И в этом случае можно использовать абсолютно все инструменты для моков — proxyquire, jest, rewire, fetch-mock, nock и т.д. с полным контролем. Более того — скорость запуска и работы этих тестов будет значительно выше + не надо тащить хром и кучу всякого дополнительного добра.
Пробовали jsdom, но отказались из-за множества мелких отличий от работы настоящего браузера. Сходу сейчас не смогу сказать, каких именно, но, если хотите, уточню и напишу вам.

В jsdom нет поддержки css. Например, element.offsetWidth всегда возвращает 0. Аналогично нули по всем параметрам возвращает element.getBoundingClientRect(). Если вам нужно тестировать что-то завязанное на эти значения, то jsdom вам не подойдет.

Если у вас прямо все завязано на динамические вычисления — то да, но в большинстве случаев это не так. Вы ведь тестируете функциональность. Все эти методы (в том числе getBoundingClientRect()) можно довольно просто определить на возвращение не нулевого значения, причем для разных тестов разные, что дает хорошую гибкость.

Если вас устраивает константное значение, то можно зарефакторить свой код, использовать чистые функции, например: getPosition(element.getBoundingClientRect()). Такой код легко тестировать, передавая разные варианты через аргумент. В этой ситуации даже jsdom не понадобится.


Обычно, когда говорят "нам нужен getBoundingClientRect", то действительно нужен более-менее честно работающий метод.

Ну, например в интеграционных тестах иногда нужно проверить 3-rd party библиотеку, которой нужны размеры (virtualised table или responsive графики) и в большинстве случаев достаточно константного значения.
Но соглашусь, что бывают кейсы, когда нужно большее. Но на мой взгляд их меньшинство, для них можно использовать настоящий браузер. Для всего остального более чем достаточно jsdom-а.

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


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

В jsdom практически весь Browser API реализован криво и не по спеке. Тот же HTMLImageElement, например.

Команда JSDOM прикладывает большие усилия по следованию спецификации. Главный ментейнер проекта, Доменик Деникола так же по совместительству является членом рабочей группы WHATWG.


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

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