Stencil Testing Library представляет собой набор инструментов для тестирования компонентов, разработанных с использованием фреймворка Stencil. Она предоставляет мощные возможности для тестирования веб-компонентов, фокусируясь на их поведении и взаимодействиях, а не на реализации. Эта библиотека использует знакомый API, схожий с популярной Testing Library для React, но адаптирован для работы с веб-компонентами, что позволяет создавать более стабильные и поддерживаемые тесты.
Для начала необходимо установить Stencil Testing Library. Она входит в состав большинства шаблонов Stencil, но если вам нужно установить её вручную, это можно сделать через npm:
npm install @stencil/core @stencil/testing
После установки Stencil Testing Library необходимо настроить тестовую среду. Stencil использует Jest для выполнения тестов, поэтому необходимо убедиться, что Jest и необходимые зависимости для работы с компонентами установлены.
npm install --save-dev jest @stencil/core @testing-library/jest-dom
Кроме того, для корректной работы тестов следует настроить
jest.config.js:
module.exports = {
preset: '@stencil/core/testing',
};
После выполнения этих шагов Stencil Testing Library готова к использованию.
Stencil Testing Library ориентирован на поведение компонентов. Это означает, что тесты должны фокусироваться на взаимодействиях с компонентами, а не на их внутренней реализации. Тесты обычно пишутся в формате, схожем с тестами для других JavaScript фреймворков, например, React, с использованием библиотеки Jest и API Testing Library.
Для начала создадим простейший компонент и напишем для него тест.
Пример компонента:
@Component({
tag: 'my-button',
styleUrl: 'my-button.css',
shadow: true,
})
export class MyButton {
@Prop() text: string;
render() {
return <button>{this.text}</button>;
}
}
Для тестирования компонента, который рендерит простую кнопку, можно использовать следующий код:
import { newSpecPage } from '@stencil/core/testing';
import { MyButton } from './my-button';
describe('my-button', () => {
it('renders the correct text', async () => {
const page = await newSpecPage({
components: [MyButton],
html: `<my-button text="Click me"></my-button>`,
});
expect(page.root).toEqualHtml(`
<my-button text="Click me">
<button>Click me</button>
</my-button>
`);
});
});
В этом тесте используется метод newSpecPage, который
позволяет создать экземпляр компонента в тестовом окружении и проверить
его рендеринг. Тест проверяет, что кнопка рендерится с правильным
текстом.
Stencil позволяет передавать данные в компоненты через пропсы. В тестах можно легко установить значения пропсов с помощью синтаксиса HTML или через свойства компонента.
it('renders the button with the provided text', async () => {
const page = await newSpecPage({
components: [MyButton],
html: `<my-button text="Submit"></my-button>`,
});
expect(page.root.textContent).toBe('Submit');
});
В этом тесте мокируется пропс text, и проверяется, что
текст кнопки соответствует переданному значению.
Stencil поддерживает создание пользовательских событий через механизм
EventEmitter. Например, для тестирования события можно
сделать следующее:
@Component({
tag: 'my-button',
styleUrl: 'my-button.css',
shadow: true,
})
export class MyButton {
@Event() buttonClicked: EventEmitter;
@Method()
async clickButton() {
this.buttonClicked.emit();
}
render() {
return <button onCl ick={() => this.clickButton()}>Click me</button>;
}
}
Тестирование этого компонента с событием можно выполнить следующим образом:
import { newSpecPage } from '@stencil/core/testing';
import { MyButton } from './my-button';
describe('my-button', () => {
it('emits buttonClicked event when clicked', async () => {
const page = await newSpecPage({
components: [MyButton],
html: `<my-button></my-button>`,
});
const button = page.root.shadowRoot.querySelector('button');
const spy = jest.fn();
page.root.addEventListener('buttonClicked', spy);
button.click();
await page.waitForChanges();
expect(spy).toHaveBeenCalled();
});
});
В этом тесте создается шпион (spy) на событие
buttonClicked, и проверяется, что оно вызывается при клике
на кнопку.
Stencil Testing Library поддерживает асинхронные тесты с помощью
стандартных возможностей Jest. Когда компоненты требуют асинхронного
рендеринга (например, при ожидании загрузки данных или асинхронных
операций), можно использовать методы await и
waitForChanges.
Пример асинхронного теста:
it('loads data asynchronously', async () => {
const page = await newSpecPage({
components: [MyButton],
html: `<my-button></my-button>`,
});
page.root.text = 'Loading...';
await page.waitForChanges();
page.root.text = 'Data loaded';
await page.waitForChanges();
expect(page.root.textContent).toBe('Data loaded');
});
Здесь waitForChanges используется для ожидания
завершения асинхронных изменений в компоненте.
Stencil поддерживает Shadow DOM, что позволяет компонентым быть инкапсулированными и изолированными от остальной части страницы. Для тестирования стилей компонентов, использующих Shadow DOM, можно использовать стандартные методы проверки стилей и манипуляции с элементами внутри теневого дерева.
Пример теста, который проверяет стили компонента:
it('applies styles correctly', async () => {
const page = await newSpecPage({
components: [MyButton],
html: `<my-button></my-button>`,
});
const button = page.root.shadowRoot.querySelector('button');
expect(button).toHaveStyle({ 'background-color': 'blue' });
});
Этот тест проверяет, что кнопка внутри компонента имеет правильный стиль.
Stencil компоненты могут взаимодействовать с внешними библиотеками и сервисами. Для этих случаев можно использовать моки и шпионов для имитации этих зависимостей.
Пример использования мока для HTTP-запроса:
it('fetches data from API', async () => {
const mockFetch = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue({ data: 'test' }),
});
global.fetch = mockFetch;
const page = await newSpecPage({
components: [MyButton],
html: `<my-button></my-button>`,
});
await page.root.loadData();
await page.waitForChanges();
expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/data');
});
Здесь fetch мокается с помощью Jest, и проверяется, что
запрос был отправлен на правильный URL.
Интеграционные тесты позволяют проверять взаимодействие между несколькими компонентами. В Stencil это можно сделать через создание нескольких компонентов на одной странице и проверку их взаимодействий.
Пример интеграционного теста:
it('interacts between components', async () => {
const page = await newSpecPage({
components: [MyButton, MyOtherComponent],
html: `<my-button></my-button><my-other-component></my-other-component>`,
});
const button = page.root.querySelector('my-button');
const otherComponent = page.root.querySelector('my-other-component');
button.click();
await page.waitForChanges();
expect(otherComponent.someProperty).toBe(true);
});
Здесь проверяется взаимодействие между кнопкой и другим компонентом при выполнении действия.
Stencil Testing Library предоставляет мощные инструменты для тестирования компонентов в экосистеме Stencil. С помощью Jest и API, аналогичного Testing Library, можно легко создавать надежные и поддерживаемые тесты для компонентов, обеспечивая проверку их поведения, стилей, событий и взаимодействий с другими компонентами.