Comments 12
Cypress, на мой взгляд, лучше подходит для интеграционных тестов - у него есть как режим прогона в открытом браузере, так и в headless режиме. Но это требует запуска проекта в отдельном процессе (либо докер-контейнере), на который уже заходит Cypress. Это усложняет настройку CI, но упрощает подготовку самих тестов - не нужно вызывать методы рендеринга в некий nodejs-DOM и надеяться, что в актуальных браузерах тоже будет работать, так как тест заходит на реальный запущенный сайт в реальном браузере.
С Кентом хотелось бы согласиться, и сложно не согласиться, что E2E это единственная осязаемая гарантия итоговой работоспособности, но найти компанию, которая потратит столько усилий для создания на каждый тест стабильных стендов со всей инфраструктурой бэка и базами с сэмпловыми данными в соответствии с текущей веткой каждого сервиса и структурой баз на определенный момент времени (либо версией, указанной вручную), мне пока не удалось. Особенно, если есть интеграции со внешними сервисами, ибо в каждом нужно сконфигурировать работу с данным тест-стендом. Были попытки на реальных стендах прогонять, создавая море новых юзеров и не завязываясь на стабильные сущности, но этим можно покрыть только функционал "котик отобразился" без конкретизации какой котик, в каком порядке, с какими характеристиками, какими действиями при клике и т.п., что надежности продукту не добавляет.
найти компанию, которая потратит столько усилий для создания на каждый тест стабильных стендов со всей инфраструктурой бэка и базами с сэмпловыми данными в соответствии с текущей веткой каждого сервиса и структурой баз на определенный момент времени (либо версией, указанной вручную), мне пока не удалось. Особенно, если есть интеграции со внешними сервисами, ибо в каждом нужно сконфигурировать работу с данным тест-стендом. Были попытки на реальных стендах прогонять, создавая море новых юзеров и не завязываясь на стабильные сущности, но этим можно покрыть только функционал "котик отобразился" без конкретизации какой котик, в каком порядке, с какими характеристиками, какими действиями при клике и т.п., что надежности продукту не добавляет.
Иными словами толку от отдела ручных тестировщиков больше чем от вот этого вот всего в статье.
Сложно научить машину думать как человек и обладать его компетенциями. Вроде простой кейс для человека - открыть страницу, увидеть что ничего не поехало, попрокручивать. Для машины это проверить наличие тысяч элементов, их взаимоположения, в разных режимах адаптивности (несколько вариантов мобильных устройств, планшеты, десктоп), высчитать возможный скролл, проверить по Intersection Observer (которые нужно еще везде развесить), что элемент виден в определенном положении скролла. Нужны еще константные непротиворечивые идентификаторы, благодаря которым тест не сломается на середине. И это простейший кейс, который человеком проверяется за секунды, а кодом описать - как космолет запустить.
Вариант со скриншотами тоже имеет массу ограничений, хотя для машины сравнить 2 картинки и высчитать расхождения несложно. Что уж говорить о сложных кейсах и поведении юзера, которое почти нереально предсказать, и его условиях в виде медленного и нестабильного интернета. Ручных тестировщиков, на мой взгляд, заменить в ближайшей перспективе не получится, можно только немного убедиться, что в определенных идеальных кейсах код будет работать успешно.
Про E2E, в чистом виде, я на своей практике не встречал. Всегда были подготовлены стенды внешних API или избегались кейсы, которые могут заэффектить прогоны следующих тестов (типа, регистрация пользователя).
Подержите моё пиво, ща я вам покажу по настоящему современный фронтенд..
Начнём со схемы ответа сервера
const Image = $mol_data_record({
url: $mol_data_string,
})
const Search = $mol_data_record({
data: $mol_data_array(
$mol_data_record({
images: $mol_data_record({
downsized_medium: Image,
}),
})
)
})
Реализуем API, который валидирует ответ по схеме
export class $my_catinder_api extends $mol_object2 {
@ $mol_mem_key
search( param: { query: string, offset: number } ) {
const response = this.$.$mol_fetch.json(
`https://api.giphy.com/v1/gifs/search?q=${ param.query }&offset=${ param.offset }&limit=1&api_key=Gc7131jiJuvI7IdN0HZ1D7nh0ow5BU6g`
)
return Search( response as any ).data[0].images.downsized_medium.url
}
}
Добавим мокнутое апи, которое не ходит в сеть
$mol_test_mocks.push( $ => {
class $my_catinder_api_mock extends $.$my_catinder_api {
@ $mol_mem_key
search( param: { query: string, offset: number } ) {
return $mol_guid() + '.gif'
}
}
$.$my_catinder_api = $my_catinder_api_mock
} )
Скомпонуем приложение из компонент
$my_catinder_app $mol_stack
title \Catinder
api $my_catinder_api
offset? 0
sub /
<= Photo $mol_image
uri <= photo \
<= Buttons $mol_view sub /
<= Prev $mol_button_minor
click? <=> prev? null
sub /
<= Prev_icon $mol_icon_chevron_left
<= Next $mol_button_minor
click? <=> next? null
sub /
<= Next_icon $mol_icon_chevron_right
Добавим логики
export class $my_catinder_app extends $.$my_catinder_app {
photo() {
return this.api().search({
query: 'cat',
offset: this.offset(),
})
}
prev() {
this.offset( Math.max( 0, this.offset() - 1 ) )
}
next() {
this.offset( this.offset() + 1 )
}
}
Наведём красоты
namespace $.$$ {
$mol_style_define( $my_catinder_app, {
Photo: {
objectFit: 'contain',
alignSelf: 'stretch',
justifySelf: 'stretch',
},
Buttons: {
alignSelf: 'stretch',
justifySelf: 'stretch',
justifyContent: 'stretch',
alignContent: 'stretch',
$mol_button: {
flex: {
grow: 1,
},
alignItems: 'center',
':hover': {
background: {
color: 'transparent',
},
},
},
},
Prev: {
justifyContent: 'left',
},
Next: {
justifyContent: 'right',
},
} )
}
И, наконец, тесты:
$mol_test({
'next image is different'( $ ) {
const app = $my_catinder_app.make({ $ })
const prev = app.Photo().uri()
app.Next().click()
const next = app.Photo().uri()
$mol_assert_unique( prev, next )
},
'no prev of first image'( $ ) {
const app = $my_catinder_app.make({ $ })
const prev = app.Photo().uri()
app.Prev().click()
const next = app.Photo().uri()
$mol_assert_equal( prev, next )
},
})
И всё это тайпчекается. А каждый такой тест исполняется меньше, чем за пол миллисекунды:
Так как тестировать современный фронт?
У вас все свелось к тестам, но чтоб тесты написать, для начала фичу нужно ручками проверить
Как не тестировать современный фронтенд?
Как по мне, для достаточного тестирования нужны только три из пяти слоёв. Статические, скриншотные и Е2Е. Остальные слои только точнее покажут где проблема.
Как тестировать современный фронтенд