Snapshot-тестирование компонентов в Riot.js используется для фиксации и контроля структуры отрендеренного интерфейса. Подход основан на сравнении текущего HTML-представления компонента с ранее сохранённым эталонным снимком. При любом расхождении тест сигнализирует об изменении, что позволяет выявлять регрессии в разметке и логике отображения на раннем этапе.
Riot.js генерирует DOM на основе шаблонов, реактивных выражений и состояния компонента. Snapshot-тесты решают несколько задач:
if,
each, слоты)Snapshot не проверяет поведение в интерактивном смысле, а именно результат рендеринга.
Типичный стек для snapshot-тестирования компонентов Riot.js:
.riot-файловУстановка зависимостей:
npm install --save-dev jest jsdom @riotjs/compiler @riotjs/test-utils
Минимальная конфигурация Jest:
// jest.config.js
module.exports = {
testEnvironment: 'jsdom',
transform: {
'^.+\\.riot$': '@riotjs/compiler'
}
}
Пример компонента:
<!-- hello.riot -->
<hello>
<p class={ color }>{ message }</p>
<script>
export default {
state: {
message: 'Hello Riot',
color: 'primary'
}
}
</script>
</hello>
Компонент содержит реактивное состояние и привязку класса, что делает его подходящим для snapshot-проверки.
Тест создаётся как обычный Jest-тест с сохранением HTML-снимка.
// hello.test.js
import { component } from '@riotjs/test-utils'
import Hello from './hello.riot'
describe('Hello component snapshot', () => {
it('matches the default snapshot', () => {
const mount = component(Hello)
const el = mount()
expect(el).toMatchSnapshot()
})
})
При первом запуске Jest создаёт файл снимка:
__snapshots__/hello.test.js.snap
Содержимое snapshot:
exports[`Hello component snapshot matches the default snapshot 1`] = `
<div>
<p class="primary">
Hello Riot
</p>
</div>
`;
Snapshot-тесты особенно полезны при проверке разных состояний.
it('matches snapshot with custom state', () => {
const mount = component(Hello)
const el = mount({
state: {
message: 'Custom text',
color: 'danger'
}
})
expect(el).toMatchSnapshot()
})
Каждый вариант состояния сохраняется как отдельный снимок, позволяя контролировать визуальные изменения при разных входных данных.
Компоненты Riot.js часто используют директивы if и
each. Snapshot позволяет зафиксировать оба варианта.
<list>
<ul if={ items.length }>
<li each={ items }>{ name }</li>
</ul>
<p if={ !items.length }>Empty</p>
<script>
export default {
state: {
items: []
}
}
</script>
</list>
Тестирование пустого и непустого состояния:
it('renders empty state', () => {
const mount = component(List)
const el = mount({ state: { items: [] } })
expect(el).toMatchSnapshot()
})
it('renders list items', () => {
const mount = component(List)
const el = mount({
state: { items: [{ name: 'A' }, { name: 'B' }] }
})
expect(el).toMatchSnapshot()
})
Изменения в шаблоне или логике компонента приводят к расхождению snapshot-ов. Jest сообщает об этом и предлагает обновление:
jest -u
Обновление допустимо только при осознанном изменении структуры DOM. Snapshot-тесты не должны использоваться как автоматическое подтверждение любых правок.
Для стабильности snapshot-ов рекомендуется:
id, дат, случайных значенийПри необходимости можно сериализовать только часть DOM:
expect(el.querySelector('p')).toMatchSnapshot()
Snapshot-тесты в Riot.js дополняют, но не заменяют проверки логики:
Комбинация обоих подходов даёт контроль как над внешним видом компонента, так и над его внутренним поведением.
Snapshot-файлы являются частью исходного кода:
Грамотно поддерживаемые snapshot-ы превращаются в документацию реального состояния компонентов и служат надёжным инструментом контроля качества при разработке на Riot.js.