Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
MSTest предоставляет атрибуты для управления выполнением тестов, включая параллелизацию, модели потоков, время ожидания, повторные попытки и условное выполнение на основе платформы или среды.
Атрибуты многопоточности
Атрибуты потоков определяют, какие методы тестирования модели потоков используются. Эти атрибуты важны при тестировании com-компонентов, элементов пользовательского интерфейса или кода с определенными требованиями к потоку.
STATestClassAttribute
Компонент STATestClassAttribute выполняет все методы тестирования в классе (включая ClassInitialize и ClassCleanup) в однопоточной модели (STA). Используйте этот атрибут при тестировании COM-объектов, требующих STA.
[STATestClass]
public class ComInteropTests
{
[TestMethod]
public void TestComComponent()
{
// This test runs in an STA thread
var comObject = new SomeComObject();
// Test COM interactions
}
}
Замечание
Этот атрибут поддерживается только в Windows в MSTest версии 3.6 и более поздних версиях.
STATestMethodAttribute
Выполняет STATestMethodAttribute определенный метод тестирования в однопоточной квартире. Используйте этот атрибут для отдельных тестов, которые нуждаются в STA, в то время как для других тестов в классе это не требуется.
[TestClass]
public class MixedThreadingTests
{
[STATestMethod]
public void TestRequiringSTA()
{
// This test runs in an STA thread
}
[TestMethod]
public void RegularTest()
{
// This test uses default threading
}
}
Замечание
Этот атрибут поддерживается только в Windows в MSTest версии 3.6 и более поздних версиях.
Сохранение контекста STA для асинхронных продолжений
Начиная с MSTest 4.1, в STATestMethodAttribute добавлено свойство UseSTASynchronizationContext, которое гарантирует, что асинхронные продолжения выполняются в одном и том же потоке STA. При включении атрибут создает настраиваемый SynchronizationContext, который отправляет продолжения обратно в поток STA, что необходимо для тестирования компонентов пользовательского интерфейса, требующих использования потока STA в ходе их асинхронных операций.
[TestClass]
public class UIComponentTests
{
[STATestMethod(UseSTASynchronizationContext = true)]
public async Task TestAsyncUIOperation()
{
// Initial code runs on STA thread
var control = new MyControl();
await control.LoadDataAsync();
// Continuation also runs on STA thread,
// ensuring UI operations remain valid
Assert.IsTrue(control.IsDataLoaded);
}
}
Подсказка
Используйте UseSTASynchronizationContext = true при тестировании компонентов Windows Forms или WPF, которые выполняют асинхронные операции и ожидают, что их продолжение будет выполняться в одном потоке.
UITestMethodAttribute
Атрибут UITestMethod планирует тестовое выполнение в потоке пользовательского интерфейса. Этот атрибут предназначен для тестирования приложений UWP и WinUI, требующих доступа к потоку пользовательского интерфейса.
[TestClass]
public class WinUITests
{
[UITestMethod]
public void TestUIComponent()
{
// This test runs on the UI thread
var button = new Button();
button.Content = "Click me";
Assert.IsNotNull(button.Content);
}
}
Замечание
Для этого атрибута требуется соответствующий адаптер MSTest для платформ UWP или WinUI. Дополнительные сведения см. в разделе поддержки платформы .
Атрибуты параллелизации
Атрибуты параллелизации определяют, выполняются ли тесты одновременно, повышая время выполнения теста.
ParallelizeAttribute
По умолчанию MSTest выполняет тесты последовательно. Атрибут уровня сборки позволяет параллельное ParallelizeAttribute выполнение тестов.
using Microsoft.VisualStudio.TestTools.UnitTesting;
[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]
Область параллелизации
| Scope | Поведение |
|---|---|
ClassLevel |
Несколько классов тестирования выполняются параллельно, но тесты в классе выполняются последовательно. |
MethodLevel |
Отдельные методы тестирования могут выполняться параллельно независимо от их класса. |
Рабочие потоки
Свойство Workers задает максимальное количество потоков для параллельного выполнения:
-
0(по умолчанию): используйте количество логических процессоров на компьютере - Любое положительное целое число: используйте заданное число потоков.
// Parallelize at class level with 2 worker threads
[assembly: Parallelize(Workers = 2, Scope = ExecutionScope.ClassLevel)]
Подсказка
Кроме того, можно настроить параллелизацию с помощью runsettings или testconfig.json без изменения кода.
Подсказка
Включите параллелизацию на уровне сборки по умолчанию, даже если многие тесты в настоящее время требуют последовательного выполнения. Этот подход рекомендует создавать новые тесты, поддерживающие параллельное выполнение с самого начала. Используйте анализатор MSTEST0001 , чтобы убедиться, что сборка явно объявляет намерение параллелизации с [assembly: Parallelize] или [assembly: DoNotParallelize]. После включения параллелизации просмотрите каждый тестовый класс, чтобы определить, поддерживает ли она безопасную одновременную выполнение. Часто исключение только нескольких классов или методов с DoNotParallelize оказывается достаточным, что позволяет запускать большинство тестов параллельно для значительного ускорения выполнения тестов.
DoNotParallelizeAttribute
Система DoNotParallelizeAttribute предотвращает параллельное выполнение для определенных сборок, классов или методов. Используйте этот атрибут, когда тесты разделяют состояние или ресурсы, к которым нельзя безопасно обращаться одновременно.
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
[TestClass]
public class ParallelTests
{
[TestMethod]
public void CanRunInParallel()
{
// This test can run with others
}
}
[TestClass]
[DoNotParallelize]
public class SequentialTests
{
[TestMethod]
public void MustRunSequentially()
{
// This class's tests run sequentially
}
}
[TestClass]
public class MixedTests
{
[TestMethod]
public void CanRunInParallel()
{
// This test can run with others
}
[TestMethod]
[DoNotParallelize]
public void MustBeIsolated()
{
// This specific test doesn't run in parallel
}
}
Замечание
Вам потребуется DoNotParallelize только в том случае, если вы включили параллельное выполнение с атрибутом Parallelize .
Атрибуты времени ожидания
Атрибуты времени ожидания препятствуют выполнению тестов на неопределенный срок и помогают выявлять проблемы с производительностью.
TimeoutAttribute
TimeoutAttribute указывает максимальное время (в миллисекундах), за которое может выполняться метод теста или метод фиктуры. Если выполнение превышает это время, тест завершается ошибкой.
[TestClass]
public class TimeoutTests
{
[TestMethod]
[Timeout(5000)] // 5 seconds
public void TestWithTimeout()
{
// Test must complete within 5 seconds
}
}
Подсказка
Вы можете настроить глобальное время ожидания теста с помощью runsettings (TestTimeout) или testconfig.json (timeout.test) без изменения кода.
Применение времени ожидания к методам фикстур
Вы также можете применить тайм-ауты к методам инициализации и очистки:
[TestClass]
public class FixtureTimeoutTests
{
[ClassInitialize]
[Timeout(10000)]
public static void ClassInit(TestContext context)
{
// Must complete within 10 seconds
}
[TestInitialize]
[Timeout(2000)]
public void TestInit()
{
// Must complete within 2 seconds
}
}
Подсказка
Каждый метод светильника [Timeout] , принимаюющий атрибут, имеет эквивалентный глобальный параметр конфигурации. Настройте время ожидания глобально через runsettings или testconfig.json, используя такие параметры, как TestInitializeTimeout, ClassInitializeTimeout, AssemblyInitializeTimeout, и аналогичные параметры для очистки.
Замечание
Таймауты не гарантированы в точности. Тест прерывается после указанного времени, но фактическая отмена может занять немного больше времени.
Совместная отмена
По умолчанию MSTest оборачивает каждый временной метод тестирования в отдельную задачу или поток. По достижении времени ожидания платформа перестает наблюдать за тестом, но базовая задача продолжает выполняться в фоновом режиме. Это поведение может вызвать проблемы:
- Метод теста продолжает получать доступ к ресурсам и изменять состояние даже после истечения времени ожидания.
- Фоновое выполнение может привести к условиям гонки, влияющим на последующие тесты.
- Каждый раз метод вызывает дополнительные издержки от оболочки задачи или потока.
Начиная с MSTest 3.6 используйте CooperativeCancellation свойство, чтобы избежать этих проблем. В совместном режиме MSTest не упаковывает тест в дополнительную задачу. Вместо этого, когда достигается время ожидания, фреймворк сигнализирует токен отмены. Ваш тестовый код отвечает за регулярную проверку маркера и его корректное завершение.
[TestClass]
public class CooperativeTimeoutTests
{
[TestMethod]
[Timeout(5000, CooperativeCancellation = true)]
public async Task TestWithCooperativeCancellation(CancellationToken cancellationToken)
{
// Check the token periodically
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(100, cancellationToken);
// Do work
}
}
[TestMethod]
[Timeout(5000, CooperativeCancellation = true)]
public void SyncTestWithCooperativeCancellation(CancellationToken cancellationToken)
{
// Works with sync methods too
for (int i = 0; i < 1000; i++)
{
cancellationToken.ThrowIfCancellationRequested();
// Do work
}
}
}
Преимущества совместной отмены:
- Снижение затрат на производительность (без дополнительной оболочки задач или потоков на тест).
- Очистка ресурсов стала более эффективной благодаря тому, что ваш код ясно обрабатывает отмену.
- Соответствует стандартным моделям отмены в .NET.
- Детерминированное поведение за счет избегания состояний гонки между тестовым кодом и ненаблюдаемым фоновым выполнением.
Замечание
Для кооперативной отмены требуется, чтобы тестовый код регулярно проверял токен отмены. Если ваш код не проверяет токен, тест не остановится при достижении тайм-аута.
Подсказка
Вы можете включить кооперативную отмену глобально для всех атрибутов времени ожидания с помощью runsettings или testconfig.json вместо индивидуальной настройки каждого атрибута.
Подсказка
Связанные анализаторы:
- MSTEST0045 — рекомендует использовать кооперативную отмену для атрибутов времени ожидания.
Атрибуты повторных попыток
Атрибуты повторных попыток помогают обрабатывать нестабильные тесты, автоматически повторно выполняя не прошедшие тесты.
RetryAttribute
RetryAttribute, представленный в MSTest 3.8, автоматически выполняет повторные попытки методов тестирования, которые завершаются сбоем или истечением времени ожидания. Настройте максимальное количество попыток повторного выполнения, задержку между этими попытками и стратегию отката.
[TestClass]
public class RetryTests
{
[TestMethod]
[Retry(3)] // Retry up to 3 times if the test fails
public void FlakeyNetworkTest()
{
// Test that might occasionally fail due to network issues
}
[TestMethod]
[Retry(3, MillisecondsDelayBetweenRetries = 1000, BackoffType = DelayBackoffType.Exponential)]
public void TestWithExponentialBackoff()
{
// Retries with increasing delays: 1s, 2s, 4s
}
[TestMethod]
[Retry(5, MillisecondsDelayBetweenRetries = 500, BackoffType = DelayBackoffType.Constant)]
public void TestWithConstantDelay()
{
// Retries with constant 500ms delay between attempts
}
}
Параметры конфигурации
| Недвижимость | Description | По умолчанию |
|---|---|---|
MaxRetryAttempts |
Максимальное количество попыток повторов (только для чтения, задаётся через конструктор) | Обязательно |
MillisecondsDelayBetweenRetries |
Базовая задержка между повторными попытками (в мс) | 0 |
BackoffType |
Constant или Exponential задержка |
Constant |
Замечание
В методе теста может присутствовать только один RetryAttribute . Нельзя использовать RetryAttribute для методов, которые не помечены как TestMethod.
Подсказка
Связанные анализаторы:
-
MSTEST0043 — рекомендуется использовать
RetryAttributeв методах тестирования.
Реализации пользовательских повторных попыток
Создайте пользовательскую логику повторных попыток путем наследования от RetryBaseAttribute:
public class CustomRetryAttribute : RetryBaseAttribute
{
private readonly int _maxRetries;
public CustomRetryAttribute(int maxRetries)
{
_maxRetries = maxRetries;
}
// Implement abstract members
// Add custom logic for retry conditions
}
Атрибуты условного выполнения
Атрибуты условного выполнения определяют, выполняются ли тесты на основе определенных условий, таких как операционная система или среда CI.
ConditionBaseAttribute
Это ConditionBaseAttribute абстрактный базовый класс для условного выполнения. MSTest предоставляет несколько встроенных реализаций.
Замечание
По умолчанию атрибуты условия не наследуются. Применение их к базовому классу не влияет на производные классы. Атрибуты настраиваемого условия могут переопределить это поведение путем переопределения AttributeUsage, но это не рекомендуется, чтобы сохранить согласованность со встроенными атрибутами условия.
Подсказка
Связанные анализаторы:
- MSTEST0041 — рекомендует использовать атрибуты на основе условий с классами тестирования.
OSConditionAttribute
OSConditionAttribute запускает или пропускает тесты в зависимости от операционной системы. Используйте перечисление OperatingSystems флагов, чтобы указать, какие операционные системы применяются.
[TestClass]
public class OSSpecificTests
{
[TestMethod]
[OSCondition(OperatingSystems.Windows)]
public void WindowsOnlyTest()
{
// Runs only on Windows
}
[TestMethod]
[OSCondition(OperatingSystems.Linux | OperatingSystems.OSX)]
public void UnixLikeOnlyTest()
{
// Runs on Linux or macOS
}
[TestMethod]
[OSCondition(ConditionMode.Exclude, OperatingSystems.Windows)]
public void SkipOnWindowsTest()
{
// Runs on any OS except Windows
}
}
Поддерживаемые операционные системы
| OS | Description |
|---|---|
Windows |
Microsoft Windows |
Linux |
Дистрибутивы Linux |
OSX |
macOS |
FreeBSD |
FreeBSD |
Объедините операционные системы с побитовой операторОМ OR (|).
Подсказка
Связанные анализаторы:
-
MSTEST0061 — рекомендует использовать атрибут
OSConditionвместо проверок среды выполнения.
CIConditionAttribute
Элемент CIConditionAttribute выполняет или пропускает тесты в зависимости от того, исполняются ли они в среде непрерывной интеграции.
[TestClass]
public class CIAwareTests
{
[TestMethod]
[CICondition] // Default: runs only in CI
public void CIOnlyTest()
{
// Runs only in CI environments
}
[TestMethod]
[CICondition(ConditionMode.Include)]
public void ExplicitCIOnlyTest()
{
// Same as above, explicitly stated
}
[TestMethod]
[CICondition(ConditionMode.Exclude)]
public void LocalDevelopmentOnlyTest()
{
// Skipped in CI, runs during local development
}
}
IgnoreAttribute
IgnoreAttribute безусловно пропускает тестовый класс или метод. При необходимости укажите причину пропуска.
Подсказка
Связанный анализатор: MSTEST0015 — метод тестирования не должен игнорироваться. Включите этот анализатор для обнаружения тестов, которые постоянно игнорируются.
[TestClass]
public class IgnoreExamples
{
[TestMethod]
[Ignore]
public void TemporarilyDisabled()
{
// This test is skipped
}
[TestMethod]
[Ignore("Waiting for bug #123 to be fixed")]
public void DisabledWithReason()
{
// This test is skipped with a documented reason
}
}
[TestClass]
[Ignore("Entire class needs refactoring")]
public class IgnoredTestClass
{
[TestMethod]
public void Test1() { } // Skipped
[TestMethod]
public void Test2() { } // Skipped
}
Ссылка на рабочие элементы
Когда вы игнорируете тесты из-за известных проблем, используйте WorkItemAttribute или GitHubWorkItemAttribute для отслеживания:
[TestClass]
public class TrackedIgnoreExamples
{
[TestMethod]
[Ignore("Waiting for fix")]
[WorkItem(12345)]
public void TestWithWorkItem()
{
// Linked to work item 12345
}
[TestMethod]
[Ignore("Known issue")]
[GitHubWorkItem("https://github.com/owner/repo/issues/42")]
public void TestWithGitHubIssue()
{
// Linked to GitHub issue #42
}
}
Лучшие практики
Используйте параллелизацию мудро: включите параллелизацию для независимых тестов, но используйте
DoNotParallelizeдля тестов с общим состоянием.Задайте соответствующие значения времени ожидания: выберите время ожидания, которые позволяют нормально выполнять, но перехватывать зависшие тесты. Рассмотрим медленные среды CI.
Предпочитайте совместную отмену: используйте совместную отмену, чтобы избежать дополнительных оболочек задач и предотвратить фоновое выполнение тестов с истекшим временем. Включите анализатор MSTEST0045 для применения этой практики.
Документирование игнорируемых тестов: Всегда указывайте причину и ссылку на рабочий элемент при игнорировании тестов.
Используйте повторные попытки экономно: устраните коренную причину ненадёжных тестов вместо того, чтобы полагаться на повторные попытки.
Тестируйте код для конкретной ОС соответствующим образом: используйте
OSConditionдля выполнения тестов, зависящих от платформы, только в тех случаях, когда они применимы.
См. также
- Настройка MSTest
- Жизненный цикл тестирования
- Написание тестов в MSTest
- MSTEST0001. Использование атрибута Parallelize
- MSTEST0041. Использование атрибутов на основе условий с классом тестирования
- MSTEST0043. Использование атрибута повторных попыток в методе тестирования
- MSTEST0045. Используйте взаимодействующую отмену для обработки времени ожидания
- MSTEST0059. Правильное использование атрибута Parallelize
- MSTEST0061. Вместо проверки среды выполнения используйте атрибут OSCondition