Таинственный гость (Mystery Guest)
Тест зависит от внешнего ресурса — файла на диске, записи в базе данных, глобальной переменной, — который создаётся где-то вне тест-метода. Читая тест, невозможно понять, откуда берутся данные.
Симптомы
- Тест читает файл из
/tmp/или абсолютного пути без пояснения, кто его создал -
parser.parse(Paths.get("/tmp/test-invoice.xml"))— файл существует «магически» - Тест опирается на конкретную запись в тестовой БД по ID (
findById(42L)) - Данные создаются в
@BeforeAllдругого класса или в SQL-скриптах, о которых знают не все - Тест падает на чистой машине, потому что «гость» не был заранее создан
Причины возникновения
- Тест писался на уже подготовленной среде, где данные были созданы вручную
- Стремление избежать повторения кода фикстуры — вынесли создание данных «куда-то»
- Нет договорённости о том, где и как создаются тестовые данные
- Унаследованный код, где тестовые данные готовились отдельными скриптами
Почему это проблема
- Нечитаемость: тест непонятен без изучения внешних зависимостей — нарушение принципа самодокументирования
- Хрупкость: файл удалили, запись изменили — тест упал без очевидной причины
- Невоспроизводимость: тест не запускается на чистой машине или в другом окружении
- Скрытые связи: тесты связаны через файловую систему или БД, хотя выглядят независимо
Решение
Фикстура создаётся прямо в тесте; если нужен файл — класть его в src/test/resources:
// ❌ откуда файл?
Invoice invoice = parser.parse(Paths.get("/tmp/test-invoice.xml"));
// ✅ данные явны прямо в тесте
String xml = """
<invoice><supplier>ООО Рога и Копыта</supplier><total>15000.00</total></invoice>
""";
Invoice invoice = parser.parse(xml);
// Если нужен файл — рядом с тестом в test/resources
Path fixture = Paths.get(getClass().getResource("/fixtures/invoice.xml").toURI());