Тесты: ваша страховочная сетка
Тест — это код, который проверяет, что другой код делает то, что вы ожидаете. Написанный однажды, он выполняется за секунды и сразу же сообщает вам, если что-то регрессировало.
Вам не нужно 100% покрытие. Начните с тестирования того, что навредило бы сильнее всего, если бы сломалось: вход в систему, платежи, данные, которые нельзя восстановить, ключевая бизнес-логика. AI прекрасно пишет тесты — часто лучше, чем пишет функциональность, потому что ожидаемое поведение здесь конкретно.
Вот промпт, который хорошо работает:
Напиши тесты для функции calculateDiscount в src/pricing.js.
Покрой: обычный случай, нулевой/пустой случай, граничный случай
максимальной скидки и один невалидный ввод. Используй существующую
тестовую обвязку в этом репозитории (посмотри, как устроены другие
файлы *.test.js). Запусти тесты и покажи мне, что они проходят,
прежде чем закончить.
Последняя строка важна. Всегда просите AI запустить тесты, а не просто написать их. Тест, который ни разу не выполнялся, — это догадка. Стоит также быть конкретным насчёт того, какие случаи покрывать, потому что, предоставленный сам себе, AI склонен написать три вариации счастливого пути и назвать это исчерпывающим. Случаи, которые на самом деле ловят баги, — скучные: пустой ввод, граничное значение, то, что должно бросить исключение.
Простой пример того, что он должен выдать:
import { calculateDiscount } from "./pricing.js";
import { describe, it, expect } from "vitest";
describe("calculateDiscount", () => {
it("applies a normal percentage discount", () => {
expect(calculateDiscount(100, 0.2)).toBe(80);
});
it("returns the full price when discount is zero", () => {
expect(calculateDiscount(100, 0)).toBe(100);
});
it("never discounts below zero", () => {
expect(calculateDiscount(100, 1.5)).toBe(0);
});
it("rejects a negative price", () => {
expect(() => calculateDiscount(-10, 0.2)).toThrow();
});
});
Когда вы позже меняете функциональность, сначала запустите тесты. Если они стали красными, вы нашли поломку раньше своих пользователей. Когда AI исправляет баг, попросите его добавить тест, который падает на старом поведении, — так баг не сможет тихо вернуться. У этой привычки есть название: регрессионный тест. Каждый баг, на который вы наткнулись, — это урок, за который кодовая база заплатила; регрессионный тест — это способ сохранить урок.
Одно предупреждение: тест тоже может быть неверным. Если AI напишет тест, который утверждает, что багованное поведение правильно, он будет проходить вечно, пока ваше приложение остаётся сломанным. Поэтому читайте утверждения (assertions), а не только зелёные галочки. Проходящий тест означает лишь «код делает то, что говорит тест», — вам всё равно нужно убедиться, что тест говорит правильное.