Pull to refresh

Comments 12

Cypress, на мой взгляд, лучше подходит для интеграционных тестов - у него есть как режим прогона в открытом браузере, так и в headless режиме. Но это требует запуска проекта в отдельном процессе (либо докер-контейнере), на который уже заходит Cypress. Это усложняет настройку CI, но упрощает подготовку самих тестов - не нужно вызывать методы рендеринга в некий nodejs-DOM и надеяться, что в актуальных браузерах тоже будет работать, так как тест заходит на реальный запущенный сайт в реальном браузере.

С Кентом хотелось бы согласиться, и сложно не согласиться, что E2E это единственная осязаемая гарантия итоговой работоспособности, но найти компанию, которая потратит столько усилий для создания на каждый тест стабильных стендов со всей инфраструктурой бэка и базами с сэмпловыми данными в соответствии с текущей веткой каждого сервиса и структурой баз на определенный момент времени (либо версией, указанной вручную), мне пока не удалось. Особенно, если есть интеграции со внешними сервисами, ибо в каждом нужно сконфигурировать работу с данным тест-стендом. Были попытки на реальных стендах прогонять, создавая море новых юзеров и не завязываясь на стабильные сущности, но этим можно покрыть только функционал "котик отобразился" без конкретизации какой котик, в каком порядке, с какими характеристиками, какими действиями при клике и т.п., что надежности продукту не добавляет.

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

Иными словами толку от отдела ручных тестировщиков больше чем от вот этого вот всего в статье.

Сложно научить машину думать как человек и обладать его компетенциями. Вроде простой кейс для человека - открыть страницу, увидеть что ничего не поехало, попрокручивать. Для машины это проверить наличие тысяч элементов, их взаимоположения, в разных режимах адаптивности (несколько вариантов мобильных устройств, планшеты, десктоп), высчитать возможный скролл, проверить по Intersection Observer (которые нужно еще везде развесить), что элемент виден в определенном положении скролла. Нужны еще константные непротиворечивые идентификаторы, благодаря которым тест не сломается на середине. И это простейший кейс, который человеком проверяется за секунды, а кодом описать - как космолет запустить.

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

Для интеграционных тестов подойдет и Cypress (или другое решение, которое умеет в headless режим работы), с этим полностью согласен. У нас на некоторых внутренних проектах компании его успешно используют. Но все же интеграционные это про тестирование компонентов (а не всего приложения), и компонентное тестирование на мой взгляд выигрывает RTL: сложность и написания, скорость выполнения, API библиотек (субъективно, но все же). Поэтому в Самокате как основное решение для интеграционных тестов мы выбрали именно этот вариант.

Про 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 )
			
		},
		
	})

И всё это тайпчекается. А каждый такой тест исполняется меньше, чем за пол миллисекунды:

Доллары привлекают деньги? Иначе зачем их столько?

Для различения локального и глобального неймспейсов.

Так как тестировать современный фронт?

У вас все свелось к тестам, но чтоб тесты написать, для начала фичу нужно ручками проверить

Речь в посте как раз про тесты через код, и они не отменяют ручное тестирование. НО, они помогают, в том числе, оптимизировать время QA на проведение регресса в дальнейшем.

Как не тестировать современный фронтенд?

Как по мне, для достаточного тестирования нужны только три из пяти слоёв. Статические, скриншотные и Е2Е. Остальные слои только точнее покажут где проблема.

Сильно зависит от проекта. Для какой-нибудь npm библиотеки очень важны юнит-тесты, для многих внутренних небольших проектов не так важны E2E и скриншотные, как интеграционные и юнит. В чистом виде E2E тесты довольно ресурсно-затратные для написания, поэтому их на моей практике пишут достаточно редко.
Sign up to leave a comment.