TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #1851 1.4K
День 1510. #ЗаметкиНаПолях
Создание Параметризованных Тестов в xUnit
xUnit использует атрибуты для определения методов тестирования. Атрибут Fact определяет простой тест, а атрибут Theory определяет параметризованный тест. Допустим, у нас есть следующий тест, проверяющий, что парсер email корректно извлекает домен:
public void Should_Return_Domain(
string email, string expectedDomain)
{
var parser = new EmailParser();
var domain = parser.GetDomain(email);
Assert.Equal(domain, expectedDomain);
}

Рассмотрим 4 способа написания параметризованных тестов.
1. InlineData
Простейший способ - вы предоставляете тестовые данные, передавая значения конструктору:
[Theory]
[InlineData("test@test.com", "test.com")]
[InlineData("user@github.io", "github.io")]
public void Should_Return_Domain(
string email, string expectedDomain)
{ … }

Мы предоставляем два строковых значения для атрибута InlineData: аргумент тестируемого метода и ожидаемый результат. Можно указать атрибут InlineData столько раз, сколько будет тестовых случаев.
Недостаток в том, что код становится очень многословным, когда у нас много тестовых случаев. И мы ограничены использованием только константных данных для параметров.

2. MemberData
С помощью MemberData мы можем программно предоставить тестовые данные из статического свойства или члена типа:
[Theory]
[MemberData(nameof(EmailTestData))]
public void Should_Return_Domain(
string email, string expectedDomain)
{ … }

public static IEnumerable<object[]>
EmailTestData => new List<object>
{
new object[] { "test@test.com", "test.com" },
new object[] { "user@github.io", "github.io" }
};

Вы указываете имя члена в атрибуте MemberData. Одно ограничение - свойство (или метод) должно возвращать IEnumerable<object[]>, поэтому строгой типизации не существует.

3. ClassData
Позволяет извлечь тестовые данные в отдельный класс. Это полезно для организации тестовых данных отдельно от тестов и упрощает повторное использование. Вы загружаете тестовые данные из класса, который наследуется от IEnumerable<object[]> и реализует метод GetEnumerator:
[Theory]
[ClassData(typeof(EmailTestData))]
public void Should_Return_Domain(
string email, string expectedDomain)
{ … }

public class EmailTestData : IEnumerable<object[]>
{
public IEnumerable<object[]> GetEnumerator()
{
yield return new object[] {
"test@test.com", "test.com" };
yield return new object[] {
"user@github.io", "github.io" };
}

IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
};

Этот подход сложен, потому что нужно реализовать интерфейс IEnumerable. И мы всё ещё страдаем от отсутствия безопасности типов.

4. TheoryData
Позволяет реализовать класс для тестовых данных, сохраняя при этом безопасность типов. Вот пример в сочетании с атрибутом ClassData, но его также можно использовать и с MemberData, возвращая TheoryData из свойства или метода:
[Theory]
[ClassData(typeof(EmailTestData))]
public void Should_Return_Domain(
string email, string expectedDomain)
{ … }

public class EmailTestData :
TheoryData<string, string>
{
public EmailTestData()
{
Add("test@test.com", "test.com");
Add("user@github.io", "github.io");
}
};

TheoryData – обобщённый класс, который позволяет указывать типы для параметризованного теста. Вы просто вызываете метод Add в конструкторе, чтобы предоставить тестовые данные для одного тестового примера. А добавление дополнительных тестов сводится к многократному вызову метода Add.

Источник: https://www.milanjovanovic.tech/blog/creating-data-driven-tests-with-xunit
  • 👍 20
More from @netdeveloperdiary
  1. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  2. Oct 1, 2026Post #3357
  3. Sep 30, 2026Post #3356
  4. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  5. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  6. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →