Бөлісу құралы:


Организация тестов и метаданных в MSTest

MSTest предоставляет атрибуты для организации тестов, добавления метаданных и связывания тестов с системами отслеживания работы. Эти атрибуты помогают эффективно фильтровать, сортировать и управлять тестами в больших наборах тестов.

Обзор

Атрибуты метаданных отображаются в окне свойств Visual Studio для методов тестирования. Они помогают вам:

  • Упорядочение тестов: группирование тестов по категориям, приоритету или владельцу.
  • Запуск тестов фильтра: выполнение определенных подмножеств тестов на основе метаданных.
  • Отслеживайте покрытие тестов: связывайте тесты с рабочими элементами и требованиями.
  • Создание отчетов: включение метаданных в тестовые отчеты и панели мониторинга.

Классификация тестов

TestCategoryAttribute

Группы TestCategoryAttribute группируют тесты по категориям для фильтрации и организации. Этот атрибут можно применить на уровне метода, класса или сборки, а категории объединяются при применении на нескольких уровнях.

Категории уровня метода

Примените категории непосредственно к методам тестирования для управления с высокой точностью:

[TestClass]
public class OrderTests
{
    [TestMethod]
    [TestCategory("Integration")]
    public void CreateOrder_SavesOrderToDatabase()
    {
        // Integration test
    }

    [TestMethod]
    [TestCategory("Unit")]
    public void CalculateTotal_ReturnsSumOfItems()
    {
        // Unit test
    }

    [TestMethod]
    [TestCategory("Integration")]
    [TestCategory("Slow")]
    public void ProcessLargeOrder_CompletesSuccessfully()
    {
        // Multiple categories allowed
    }
}

Категории уровня класса

Примените категорию к тестовом классу, чтобы назначить эту категорию всем методам тестирования в классе:

[TestClass]
[TestCategory("Payments")]
public class PaymentServiceTests
{
    [TestMethod]
    public void ProcessPayment_ValidCard_Succeeds()
    {
        // Inherits "Payments" category from class
    }

    [TestMethod]
    [TestCategory("Slow")]
    public void ProcessBatchPayments_LargeVolume_CompletesSuccessfully()
    {
        // Has both "Payments" (from class) and "Slow" (from method) categories
    }
}

Категории уровня сборки

Примените категорию на уровне сборки, чтобы классифицировать все тесты во всей сборке теста. Этот подход полезен для различения типов тестов в проектах:

// In AssemblyInfo.cs or any file in your test project
using Microsoft.VisualStudio.TestTools.UnitTesting;

[assembly: TestCategory("E2E")]

Используйте категории уровня сборки для упорядочивания тестовых проектов по типу теста:

Проект Категория сборок Цель
MyApp.UnitTests Unit Быстрые, изолированные модульные тесты
MyApp.IntegrationTests Integration Тесты с внешними зависимостями
MyApp.E2ETests E2E Сквозные тесты сценариев

Фильтрация тестов по категориям

Выполните тесты по категориям с помощью dotnet test команды:

# Run only integration tests
dotnet test --filter TestCategory=Integration

# Run tests in multiple categories
dotnet test --filter "TestCategory=Integration|TestCategory=Unit"

# Exclude slow tests
dotnet test --filter TestCategory!=Slow

В обозревателе тестов Visual Studio используйте поле поиска с Trait: префиксом:

  • Trait:"TestCategory=Integration" — показаны тесты интеграции
  • -Trait:"TestCategory=Slow" — исключает медленные тесты

TestPropertyAttribute

TestPropertyAttribute добавляет пользовательские метаданные "ключ-значение" к тестам. Используйте этот атрибут, если встроенные атрибуты не соответствуют вашим потребностям.

[TestClass]
public class CustomMetadataTests
{
    [TestMethod]
    [TestProperty("Feature", "Authentication")]
    [TestProperty("Sprint", "23")]
    [TestProperty("RiskLevel", "High")]
    public void Login_WithValidCredentials_Succeeds()
    {
        // Test with custom properties
    }

    [TestMethod]
    [TestProperty("Feature", "Authorization")]
    [TestProperty("RequirementId", "REQ-AUTH-001")]
    public void AccessAdminPage_RequiresAdminRole()
    {
        // Link to requirements
    }
}

Свойства отображаются в окне Свойств Visual Studio в разделе Тестовые.

Фильтрация по пользовательским свойствам

# Filter by custom property
dotnet test --filter "Feature=Authentication"

Тестирование владения и приоритета

OwnerAttribute

OwnerAttribute указывает, кто отвечает за тест.

[TestClass]
public class PaymentTests
{
    [TestMethod]
    [Owner("jsmith")]
    public void ProcessPayment_ChargesCorrectAmount()
    {
        // John Smith owns this test
    }

    [TestMethod]
    [Owner("team-payments")]
    public void RefundPayment_CreditsCustomerAccount()
    {
        // Team responsibility
    }
}

Фильтрация тестов по владельцу:

dotnet test --filter Owner=jsmith

PriorityAttribute

Указанный PriorityAttribute обозначает относительную важность теста. Более низкие значения указывают на более высокий приоритет.

[TestClass]
public class CriticalPathTests
{
    [TestMethod]
    [Priority(0)]
    public void Login_IsAlwaysAvailable()
    {
        // Highest priority - core functionality
    }

    [TestMethod]
    [Priority(1)]
    public void CreateAccount_WorksCorrectly()
    {
        // High priority
    }

    [TestMethod]
    [Priority(2)]
    public void CustomizeProfile_SavesPreferences()
    {
        // Medium priority
    }
}

Фильтрация тестов по приоритету:

# Run only highest priority tests
dotnet test --filter Priority=0

# Run high priority or higher
dotnet test --filter "Priority=0|Priority=1"

DescriptionAttribute

Элемент DescriptionAttribute предоставляет удобочитаемое описание того, что тест проверяет.

Предупреждение

Используйте Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute, а не System.ComponentModel.DescriptionAttribute. Анализатор MSTEST0031 обнаруживает неправильное использование.

[TestClass]
public class DocumentedTests
{
    [TestMethod]
    [Description("Verifies that orders over $100 receive a 10% discount")]
    public void ApplyDiscount_LargeOrder_Gets10PercentOff()
    {
        // Test implementation
    }

    [TestMethod]
    [Description("Ensures email validation rejects malformed addresses")]
    public void ValidateEmail_InvalidFormat_ReturnsFalse()
    {
        // Test implementation
    }
}

Отслеживание рабочих задач

WorkItemAttribute

Связи WorkItemAttribute связывают тесты с рабочими элементами в вашей системе отслеживания (например, Azure DevOps).

[TestClass]
public class BugFixTests
{
    [TestMethod]
    [WorkItem(12345)]
    [Description("Regression test for bug #12345")]
    public void DatePicker_LeapYear_HandlesFebruary29()
    {
        // Test that verifies the bug fix
    }

    [TestMethod]
    [WorkItem(67890)]
    [WorkItem(67891)]  // Can link multiple work items
    public void Export_LargeDataset_CompletesWithinTimeout()
    {
        // Test related to multiple work items
    }
}

GitHubWorkItemAttribute

Ссылки GitHubWorkItemAttribute связывают тесты с задачами на GitHub.

[TestClass]
public class GitHubLinkedTests
{
    [TestMethod]
    [GitHubWorkItem("https://github.com/myorg/myrepo/issues/42")]
    public void FeatureX_WorksAsExpected()
    {
        // Test linked to GitHub issue #42
    }

    [TestMethod]
    [GitHubWorkItem("https://github.com/myorg/myrepo/issues/100")]
    [Ignore("Waiting for upstream fix")]
    public void DependentFeature_RequiresUpdate()
    {
        // Ignored test linked to tracking issue
    }
}

Атрибуты рабочих элементов особенно полезны при сочетании с Ignore:

[TestMethod]
[Ignore("Known issue, tracked in work item")]
[WorkItem(99999)]
public void KnownIssue_AwaitingFix()
{
    // Provides traceability for why the test is ignored
}

Объединение атрибутов

Объединение нескольких атрибутов метаданных для комплексной тестовой организации:

[TestClass]
public class FullyDocumentedTests
{
    [TestMethod]
    [TestCategory("Integration")]
    [TestCategory("API")]
    [Owner("payment-team")]
    [Priority(1)]
    [Description("Verifies that the payment API returns correct error codes for invalid requests")]
    [WorkItem(54321)]
    [TestProperty("Sprint", "24")]
    [TestProperty("Feature", "ErrorHandling")]
    public void PaymentAPI_InvalidRequest_ReturnsAppropriateErrorCode()
    {
        // Well-documented test with full traceability
    }
}

Лучшие практики

  1. Используйте согласованные категории: установите соглашения об именовании для тестовых категорий в проекте.

  2. Задайте приоритеты стратегически: зарезервируйте Priority(0) для тестов на критическом пути, которые должны пройти для работоспособной сборки.

  3. Ссылка на рабочие элементы: всегда связывайте тесты с соответствующими рабочими элементами для обеспечения трассировки, особенно регрессионные тесты на наличие ошибок.

  4. Цель тестирования документа: Используйте Description для сложных тестов, где имя метода не полностью объясняет намерение.

  5. Сохраняйте текущие метаданные: обновляйте метаданные при изменении области тестирования или владения.

  6. Используйте категории для фильтрации: Разрабатывайте категории для поддержки нужд вашего конвейера CI/CD (например, "Smoke", "Ночные", "Интеграция").

Фильтрация тестов

Фильтрация командной строки

# Filter by category
dotnet test --filter TestCategory=Unit

# Filter by owner
dotnet test --filter Owner=jsmith

# Filter by priority
dotnet test --filter Priority=0

# Combine filters (AND)
dotnet test --filter "TestCategory=Integration&Priority=0"

# Combine filters (OR)
dotnet test --filter "TestCategory=Smoke|TestCategory=Critical"

# Exclude by filter
dotnet test --filter TestCategory!=Slow

# Filter by custom property
dotnet test --filter "Feature=Payments"

Обозреватель тестов Visual Studio

Используйте поле поиска в обозревателе тестов:

  • Trait:"TestCategory=Integration" — фильтрация по категориям
  • Trait:"Owner=jsmith" — фильтр по владельцу
  • Trait:"Priority=0" — фильтрация по приоритету

Дополнительные сведения о фильтрации тестов см. в разделе "Запуск выборочных модульных тестов".

См. также