Test-Driven Development (TDD, Разработка через тестирование) — это не просто техника написания тестов, а целая философия проектирования программного обеспечения. Для новичка она может казаться странной и неудобной: зачем писать тест для кода, которого еще не существует? Однако, следуя ее принципам, вы сможете создавать более чистый, модульный и надежный код. Данная инструкция разберет TDD на простом примере, шаг за шагом.
Основной цикл TDD известен как «Красный-Зеленый-Рефакторинг» (Red-Green-Refactor). Это три этапа, которые повторяются для каждой новой крошечной функциональности.
Шаг 0: Понимание требований. Прежде чем писать код, нужно четко понять, что должна делать функция или модуль. Допустим, мы пишем функцию `isPrime(n)`, которая определяет, является ли переданное число простым. Простое число — это натуральное число больше 1, которое имеет ровно два делителя: 1 и само себя.
Шаг 1: Красная стадия (Red). Напишите самый простой и очевидный тест для еще несуществующей функции. Сначала он должен упасть. Это подтверждает, что тест действительно проверяет что-то и что новый код еще не написан. Используйте любой фреймворк для тестирования (Jest для JavaScript, pytest для Python, JUnit для Java).
Например, на JavaScript с Jest:
```
test('should return false for numbers less than 2', () => {
expect(isPrime(1)).toBe(false);
});
```
Запустите тесты. Они, конечно, упадут, потому что функция `isPrime` не определена или не возвращает ожидаемого значения. Вы увидите красный цвет (ошибку). Цель достигнута.
Шаг 2: Зеленая стадия (Green). Теперь ваша задача — написать минимально необходимый код, чтобы этот тест прошел. Не думайте о будущих требованиях, только о текущем падающем тесте.
```
function isPrime(n) {
if (n < 2) {
return false;
}
// Временная заглушка
return true;
}
```
Запустите тесты снова. Теперь они должны пройти (стать зелеными). Вы сделали минимальную работу. Функция пока некорректна, но она проходит конкретный написанный тест.
Шаг 3: Рефакторинг (Refactor). На этом этапе вы улучшаете написанный код, не меняя его поведения (чтобы тесты оставались зелеными). Пока что улучшать нечего — код и так минимален. Переходим к следующему циклу.
Цикл 2. Добавляем новую функциональность.
Красный: Пишем следующий тест, который расширяет спецификацию.
```
test('should return true for prime numbers', () => {
expect(isPrime(2)).toBe(true);
expect(isPrime(3)).toBe(true);
expect(isPrime(5)).toBe(true);
});
```
Запускаем. Тест упадет, потому что для числа 2 функция вернет `true` (из-за нашей заглушки), но это случайное совпадение. Для 7 она тоже вернет `true`, но мы еще не проверяли составные числа. Давайте добавим тест на составное число, чтобы точно увидеть красный цвет.
```
test('should return false for non-prime numbers', () => {
expect(isPrime(4)).toBe(false);
expect(isPrime(6)).toBe(false);
});
```
Запускаем — оба новых теста падают.
Зеленый: Теперь нужно реализовать настоящую логику проверки простоты числа. Пишем наивный, но рабочий алгоритм.
```
function isPrime(n) {
if (n < 2) return false;
for (let i = 2; i < n; i++) {
if (n % i === 0) return false;
}
return true;
}
```
Запускаем все тесты. Они становятся зелеными.
Рефакторинг: Теперь можно подумать об оптимизации. Наш алгоритм проверяет все числа до `n`, что неэффективно. Достаточно проверять до квадратного корня из `n`. Также можно сразу обработать четные числа. Меняем реализацию:
```
function isPrime(n) {
if (n < 2) return false;
if (n === 2) return true;
if (n % 2 === 0) return false;
const limit = Math.sqrt(n);
for (let i = 3; i
Test-Driven Development: Пошаговая инструкция для начинающих разработчиков
Детальное пошаговое руководство по методологии Test-Driven Development для начинающих. На примере функции проверки числа на простоту разбирается цикл «Красный-Зеленый-Рефакторинг», объясняются базовые принципы и преимущества подхода.
87
5
Комментарии (11)