- PVSM.RU - https://www.pvsm.ru -
Идея статьи возникла после нескольких лекций о том, как писать тесты и как использовать xUnit [1]. Обо всём можно по отдельности почитать подробно. Здесь же я собрал общую информацию о том, как удачно на практике всё это применяется и сопроводил ссылками, для дальнейшего ознакомления. Обзор делался по версии 2.0.
Распространённая практика помещать все тестовые проекты в отдельный фолдер. Это относится и к структуре фолдеров на диске, и к фолдерам в солюшене. Практика распространена именно благодаря удобству. Так же, имя проекта и пространство имен полностью повторяют тестируемый модуль с добавлением в конце слова Tests (обычно через точку). Для простоты поиска тестов все тесты, относящиеся к некоторому классу помещаются в его класс с тестами. Т.о. получается пара из оргигинального класса и класса с тестами. Разделение между юнит, интеграционными, нагрузочными происходит либо по категорям, либо по логике основной системы. Это значит, что если интеграционные тест нельзя отнести к одному классу (обычно, это так), то они выносятся в отдельную сборку, посвященную тестируемому функционалу. Или, например, нагрузочные тесты могут тестировать работу некоторого метода одного класса. В этом случае тест размещается в парном классе. Структура самих тестов любого типа соответствует стилю AAA. Систематизируем вышесказанное:
xUnit является одним из популярных, нынче, фреймворков. На его описании останавливаться не буду, а приведу сухую выжимку. Если будут вопросы, пишите в коментах, отвечу.
Немного устаревшая информация, тем не менее, довольно полная, приведена в сравнении xUnit с другими фреймворками (MSTest, NUnit) [3]. Хочу отметить только важные отличия:
В остальном возможности похожи. xUnit приписывают очень высокую гибкость по кастомизации, возможность расширить/изменить поведение, запуск тестов и пр. Но мне не приходилось на практике что-то такое делать.
Fact — это отдельный юнит-тест, не принимающий параметров. Theory — это тест, принимающий параметры, при этом может быть несколько сценариев. Fixture — класс для настройки и очистки некоторого контекста. Контекст присоединяется к классу с тестами либо с помощью интерфейса IClassFixture, либо с помощью коллекции и интерфейса ICollectionFixture. Коллеция может включать несколько классов с тестами.
Пример Fact и двух вариантов Theory:
public class TestSuite
{
[Fact]
public void Should_do_somthing(){...}
[Theory]
[InlineData(20, 180, 80, ”good”)]
[InlineData(20, 180, 50, ”bad”)]
public void Should_measure_weight(int age, int height, decimal weight, string expected){...}
[Theory]
[MemberData(“AgeHeightWeightData”)]
public void Should_measure_weight(int age, int height, decimal weight, string expected){...}
public static IEnumerable<object[]> AgeHeightWeightData()
{
yield return new object[] {20, 180, 80, "good"};
yield return new object[] {20, 180, 50, "bad"};
}
}
Чуть больше деталей тут [4] и тут [5].
По умолчанию, тесты в одном классе и коллекции выполняются синхронно. Например, если при выполнении тестов у вас используется расшаренный ресурс и это вызывает проблемы (например, тесты падают, т.к. ресурс залочен), то можно поместить такие тесты в одну коллекцию и проблема уйдет, т.к. исчезнет параллелизм. В целом, стек вызовов и то, что происходит выглядит, примерно, так:
CollectionFixture: ctor - переменные этого контекста видны классам TestClass1 и TestClass2
ClassFixture: ctor - переменные этого контекста видны в TestClass1
TestClass1: ctor - переменные этого контекста видны только в одном тесте
Test1() - выполняется синхронно внутри одного класса и коллекции
TestClass1: disposed - все переменные контекста удаляются
TestClass1: ctor
Test2()
TestClass1: disposed
ClassFixture: disposed - все переменные контекста удаляются
TestClass2: ctor
Test3()
TestClass2: disposed
CollectionFixture: disposed
TestClass3: Test4() - этот тестовый класс не использует другие контексты и тесты выполняются параллельно с остальными
Стоит отметить, что при определении коллекции используется класс-маркер, который не создаётся вообще. Создаются только классы, присоединенные с помощью ICollectionFixture. Об этом подробнее читайте тут [6], а о параллелизме — тут [7].
Она есть, правда, не везде из коробки. В моём любимом TeamCity всё отлично, т.к. делать ничего не надо. Хуже в Jenkins, т.к. надо заморочиться с установкой плагина. А вот в TFS темный лес. Мне не удалось найти вменяемого примера установки и запуска xUnit. Буду рад ссылкам. Остается запуск силами скриптов MSBuild и NAnt.
Автор: ETman
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/115545
Ссылки в тексте:
[1] xUnit: https://xunit.github.io/
[2] мануал: http://dannorth.net/introducing-bdd/
[3] xUnit с другими фреймворками (MSTest, NUnit): http://xunit.github.io/docs/comparisons.html
[4] тут: https://xunit.github.io/docs/getting-started.html
[5] тут: http://binary-notes.ru/data-driven-test-with-xunit/
[6] тут: http://xunit.github.io/docs/shared-context.html
[7] тут: http://xunit.github.io/docs/running-tests-in-parallel.html
[8] Источник: https://geektimes.ru/post/272994/
Нажмите здесь для печати.