🔬 Юнит-тестирование
Принципы, структура AAA, моки, покрытие, примеры на JS, Python и Java.
Шпаргалки · Тестирование · #testing #unit #tdd
Идея
Юнит-тест проверяет небольшую единицу (функция, метод, класс) изолированно, быстро и без сети и БД.
Принципы F.I.R.S.T.
Fast (быстрые), Independent (независимые), Repeatable (повторяемые), Self-validating (сами решают пройден или нет), Timely (пишутся вовремя).
Структура AAA
- Arrange подготовка данных и объектов.
- Act вызов проверяемого кода.
- Assert сравнение с ожидаемым.
JavaScript (Vitest / Jest)
import { describe, it, expect, vi } from 'vitest';
import { discount } from './price';
describe('discount', () => {
it('даёт 10% на заказ от 1000', () => {
expect(discount(1000)).toBe(100);
});
it('не даёт скидку на малый заказ', () => {
expect(discount(500)).toBe(0);
});
it('вызывает логгер', () => {
const log = vi.fn();
discount(1000, log);
expect(log).toHaveBeenCalledWith('discount applied');
});
});
Python (pytest)
import pytest
from price import discount
@pytest.mark.parametrize("total, expected", [(1000, 100), (500, 0)])
def test_discount(total, expected):
assert discount(total) == expected
def test_negative_total_raises():
with pytest.raises(ValueError):
discount(-1)
Java (JUnit 5 + Mockito)
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock PaymentGateway gateway;
@InjectMocks OrderService service;
@Test
void chargesCustomer() {
when(gateway.charge(100)).thenReturn(true);
assertTrue(service.pay(100));
verify(gateway).charge(100);
}
}
Двойники тестов
| Тип | Назначение |
|---|---|
| Dummy | заглушка-параметр, не используется |
| Stub | возвращает заранее заданный ответ |
| Mock | проверяет, как его вызывали |
| Spy | реальный объект с подсмотром вызовов |
| Fake | упрощённая рабочая реализация (БД в памяти) |
Покрытие кода
Строки, ветки, условия. Покрытие показывает, что не проверено, но не гарантирует качество тестов. Разумная цель 70–85% по критичному коду.
Хорошие практики
- Один тест проверяет одно поведение, название описывает его.
- Без зависимости от порядка запуска и времени (подмените часы).
- Тестируйте поведение, а не внутреннюю реализацию.
- Граничные значения и ошибки, а не только «счастливый путь».
- TDD: красный (тест падает) → зелёный (минимальный код) → рефакторинг.
Инструменты по языкам
JS: Vitest, Jest, Mocha. Python: pytest, unittest. Java: JUnit, TestNG, Mockito. C#: xUnit, NUnit, Moq. Go: testing, testify. PHP: PHPUnit, Pest.