#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);
В противном случае ваш тест зависит от:
- код настройки теста, развертывающий «Human_Male.xml » файл в файловую систему и последующее его удаление. Хотя в Visual Studio test есть хороший механизм для этого (развертывание параметров тестирования скопирует файлы в папку тестового запуска как часть настройки тестового запуска).
- Включая путь к встроенному ресурсу в ваш тестовый код. Если вам когда-нибудь понадобится реструктурировать макет вашего проекта, вам нужно будет изменить тестовый код, чтобы он соответствовал. И убедитесь, что вы используете относительный путь.
Ответ №2:
Единственная проблема с внешними файлами заключается в том, что они могут меняться.
Мой предпочтительный вариант — иметь ряд функций инициализации в тестовом файле, которые можно вызывать из метода тестирования по мере необходимости. Это также упрощает и ускоряет чтение для других пользователей, которые могут получить ваш код, или даже для вас самих через шесть месяцев.
Другой вариант — основать некоторые из ваших классов объектов на интерфейсном / абстрактном типе, чтобы вы могли издеваться над ними (даже в своем коде во время выполнения), создав вместо этого тестовый класс. Например (не зависит от кода):
базовый абстрактный класс / интерфейс: IHuman IHuman.Гендерное свойство / атрибут IHuman.Свойство высоты / атрибут IHuman.Свойство / атрибут веса
класс HumanMale наследует IHuman HumanMale.Пол переопределяет IHuman Gender, возвращая мужской.
класс HumanFemale наследует IHuman HumanFemale.Gender переопределяет IHuman Gender, возвращая Female.
Затем весь код использует IHuman, и вы даже можете использовать фабрику для создания типов IHuman, чтобы создать легион киберлюдей 🙂