Tests
Тестуванні ПЗ - Процес дослідження, випробування програмного продукту для перевірки відповідності між реальним поведінкою програми та її очікуваною поведінкою.
Автоматизоване тестування ПЗ - частина процесу тестування на етапі контролю якості в процесі розробки програмного забезпечення. Воно використовує програмні засоби для виконання тестів і перевірки результатів виконання, що допомагає скоротити час тестування і спростити його процес.
- використовується для розподулення тестів по рівням застосунку.
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
| ...ByLabelText | label or aria-label content | <label for="element" /> |
| ...ByPlaceholderText | input placeholder value | <input placeholder="name" /> |
| ...ByText | element text content | <p>Lorem ipsum</p> |
| ...ByDisplayValue | Current value of input element | |
| ...ByAltText | img alt attribute | <img alt="movie poster" /> |
| ...ByTitle | title attribute or svg title tag | <span title="Add" /> or <title /> |
| ...ByRole | ARIA role | <div role="dialog" /> |
| ...ByTestId | data-testid attribute | <div data-testid="some-message" /> |
| no match | 1 match | 1+ match | Await? | |
|---|---|---|---|---|
| getBy... | throw | return | throw | No |
| findBy... | throw | return | throw | Yes |
| queryBy... | null |
return | throw | No |
| getAllBy... | throw | array | array | No |
| findAllBy... | throw | array | array | Yes |
| queryAllBy... | [] |
array | array | No |
screen.getByText(/Search:/i)
screen.getByRole('textbox')
screen.getByLabelText(/Search:/i)
screen.getByPlaceholderText('search text...')
screen.getByAltText('search image')
screen.getByDisplayValue('123')
expect(screen.getByPlaceholderText('search text...')).toBeRequired();
// якщо нам потрібно заперечення, ставимо .not
expect(screen.getByPlaceholderText('search text...')).not.toBeRequired();
expect(screen.getByPlaceholderText('search text...')).toBeEmptyDOMElement();
expect(screen.getByPlaceholderText('search text...')).toHaveAttribute('id');
fireEvent - імітація взаємодії користувача з якимись елементами.
test('change search input', () => {
render(<Search/>);
const inputElement = screen.getByRole('textbox');
fireEvent.change(inputElement, {
target: { value: 'React' }
})
expect(screen.queryByText(/Searches for React/i)).toBeInTheDocument();
});
test('checkbox click', () => {
const handleChange = jest.fn();
const { container: { firstChild: checkbox } } = render(
<input type="checkbox" onChange={handleChange} />
)
expect(checkbox).not.toBeChecked();
fireEvent.click(checkbox);
expect(handleChange).toBeCalledTimes(1);
expect(checkbox).toBeChecked();
})
test('input focus', () => {
const { getByTestId } = render(
<input type="text" data-testid="my-input" />
)
const input = getByTestId('my-input');
expect(input).not.toHaveFocus();
input.focus();
expect(input).toHaveFocus();
})
import userEvent from '@testing-library/user-event'
test('click on checkbox', () => {
const { container } = render(<input type="checkbox" />)
const checbox = container.firstChild;
expect(checbox).not.toBeChecked();
userEvent.click(checbox);
expect(checbox).toBeChecked();
})
test('onChange input', () => {
const { getByTestId } = render(<Search />);
const input = getByTestId('input-data');
expect(input.value).toBeFalsy();
userEvent.type(input, 'I love tests')
expect(input.value).toBe('I love tests');
})
test('onChange input with screen', () => {
render(<Search />);
expect(screen.queryByDisplayValue('I love tests')).not.toBeInTheDocument();
userEvent.type(screen.getByTestId('input-data'), 'I love tests')
expect(screen.getByDisplayValue('I love tests')).toBeTruthy();
})
test('click on checkbox', () => {
const { container } = render(<input type="checkbox" />);
const checkbox = container.firstChild;
expect(checkbox).not.toBeChecked();
// у випадку необхідності потрібно додати ніліштування для івента
// наприклад: ми натискаємо на чекбокс з затиснутим ctrl/shift
userEvent.click(checkbox, { ctrlKey: true, shiftKey: true });
expect(checkbox).toBeChecked();
})
test('dblClick on checkbox', () => {
const onChange = jest.fn();
const { container } = render(<input type="checkbox" onChange={onChange} />)
const checkbox = container.firstChild;
expect(checkbox).not.toBeChecked();
userEvent.dblClick(checkbox);
expect(onChange).toHaveBeenCalledTimes(2);
})
test('tab focus', () => {
const { getAllByTestId } = render(<>
<input data-testid='element' type="checkbox" />
<input data-testid='element' type="radio" />
<input data-testid='element' type="number" />
</>)
const [checkbox, radio, number] = getAllByTestId('element');
userEvent.tab();
expect(checkbox).toHaveFocus();
userEvent.tab();
expect(radio).toHaveFocus();
userEvent.tab();
expect(number).toHaveFocus();
})
test('select option', () => {
const { getByRole, getByText } = render(
<select>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
)
userEvent.selectOptions(getByRole('combobox'), '1'); // значення, яке юзер обирає
expect(getByText('A').selected).toBeTruthy();
userEvent.selectOptions(getByRole('combobox'), '2');
expect(getByText('A').selected).toBeFalsy();
expect(getByText('B').selected).toBeTruthy();
})
test('fetch', async () => {
window.fetch = jest.fn();
window.fetch.mockResolvedValueOnce({
json: async () => ({ ...mockData... }),
});
const { findAllByRole } = render(<Async/>);
const listItemElement = await findAllByRole('listitem');
expect(listItemElement).not.toHaveLength(0);
});