Таинственный гость (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());