Включить XML в качестве встроенного ресурса для модульного тестирования?

#unit-testing

#модульное тестирование

Вопрос:

У меня есть объекты, которые инициализируются путем сериализации XML-файла.

Я подумываю о включении тестовых данных в тестовый проект в качестве встроенного ресурса вместо «жесткого кодирования» данных в самом методе тестирования.

Встроенный жестко запрограммированный подход:

 [Test]
public void IsMale_CheckIfGenderIsMale_ReturnsTrue()
{
Human human = new Human();
human.Gender = Gender.Male;
Gender expected = Gender.Male;
Assert.IsTrue((human.Gender == expected));
}
  

Подход XML:

 [Test]
public void IsMale_CheckIfGenderIsMale_ReturnsTrue()
{
Human human = Human.Initialize("Human_Male.xml");
Gender expected = Gender.Male;
Assert.IsTrue((human.Gender == expected));
}
  

Какой подход лучше?

Ответ №1:

Мы часто используем встроенные XML-файлы в нашем проекте для тестирования. Потому что мы хотим протестировать создание объектов с использованием xml.

Также рекомендуется отделять создание объектов от самого класса, например:

 Human human = HumanFactory.Create("Human_Male.xml");
  

Тогда класс human будет иметь конструктор, который принимает такие параметры, как gender, и может быть вызван из класса HumanFactory . Это разделение проблем, которое позволит отделить логику вашего класса от механизма его построения.

И когда вам нужен человеческий объект для теста, вы можете либо создать его напрямую, либо использовать factory и создать его из xml.

Я бы также еще больше упростил класс HumanFactory, предоставив ему строку xml (или поток) вместо имени файла. Это может упростить тестирование, поскольку вы можете просто включить xml в свой тестовый код, а не в файл:

 Human human = HumanFactory.Create("<human gender="m"></human>");
Assert.AreEqual(human.Gender,  Gender.Male);
  

В противном случае ваш тест зависит от:

  1. код настройки теста, развертывающий «Human_Male.xml » файл в файловую систему и последующее его удаление. Хотя в Visual Studio test есть хороший механизм для этого (развертывание параметров тестирования скопирует файлы в папку тестового запуска как часть настройки тестового запуска).
  2. Включая путь к встроенному ресурсу в ваш тестовый код. Если вам когда-нибудь понадобится реструктурировать макет вашего проекта, вам нужно будет изменить тестовый код, чтобы он соответствовал. И убедитесь, что вы используете относительный путь.

Ответ №2:

Единственная проблема с внешними файлами заключается в том, что они могут меняться.

Мой предпочтительный вариант — иметь ряд функций инициализации в тестовом файле, которые можно вызывать из метода тестирования по мере необходимости. Это также упрощает и ускоряет чтение для других пользователей, которые могут получить ваш код, или даже для вас самих через шесть месяцев.

Другой вариант — основать некоторые из ваших классов объектов на интерфейсном / абстрактном типе, чтобы вы могли издеваться над ними (даже в своем коде во время выполнения), создав вместо этого тестовый класс. Например (не зависит от кода):

базовый абстрактный класс / интерфейс: IHuman IHuman.Гендерное свойство / атрибут IHuman.Свойство высоты / атрибут IHuman.Свойство / атрибут веса

класс HumanMale наследует IHuman HumanMale.Пол переопределяет IHuman Gender, возвращая мужской.

класс HumanFemale наследует IHuman HumanFemale.Gender переопределяет IHuman Gender, возвращая Female.

Затем весь код использует IHuman, и вы даже можете использовать фабрику для создания типов IHuman, чтобы создать легион киберлюдей 🙂