Конкурентный и последовательный запуск тестов
Serialized — тип данных позволяющий контролировать конкурентное или последовательное выполнение тестов.
По умолчанию
Тесты выполняются конкурентно (concurrency) по умолчанию. Это возможно благодаря использованию метода withTaskGroup(of:returning:body:)
из раздела Structured concurrency
[1].
Количество одновременно запущенных тестов управляется в runtime
.
Последовательное выполнение
Для последовательного выполнения теста с множеством аргументов используй трейт .serialized
:
@Test(.serialized, arguments: Food.allCases)
func prepare(food: Food) {
// ...
}
Функция
prepare(food:)
будет выполнять последовательно каждый из аргументов.
Атрибут @Suite
принимает такой же трейт:
@Suite(.serialized)
struct IsolationConfirmation {
@Test(arguments: IsolatedData.allCases)
func executeWith(data: IsolatedData) async throws {
// Выполнение этой функции будет последовательным,
// аргумент за аргументом.
}
@Test
func uniqlyExecute() async throws {
// Данная функция не будет запущена до тех пор,
// пока executeWith(data:) выполняется. Прежде
// чем начать выполнение необходимо дождаться
// завершение предыдущей.
}
}
extension IsolationConfirmation {
@Suite
struct NonIsolatedData {
// Все функции в этом типе данных будут
// выполняться последовательно
}
}
В примере выше ты применил трейт .serialized
и все функции с атрибутом @Test
, включая вложенные типы данных, будут выполняться последовательно.
important
Трейт .serialized
применяется рекурсивно. При применении к атрибуту @Suite, любая функция с атрибутом @Test будет выполнятья последовательно, включая вложенные типы данных.
Применение трейта не влияет на выполнение других типов данных и тестов в других файлах. Эффект будет только на там, где указан .serialized
.
Другим примером, когда применение трейта не имеет эффекта, послужит пример ниже:
@Test
func findPalindrome() {
let word: String = "Madam"
let result = word.filter(\.isLetter).lowercased().reversed()
#expect(word.lowercased() == String(result))
}
Применение трейта к одиночной глобальной функции не имеет никакого эффекта.
Ты получишь предупреждение, если функция не имеет параметров, а атрибут @Test
не имеет аргументов.
⚠️ Trait '.serialized' has no effect when used with a non-parameterized test function
Если ты передал флаг --no-parallel
в команду swift test
, то применение трейта не будет иметь эффекта, посколько ты глобально отключил конкурентное выполнение.
note
На момент выхода книги не существует обратного трейта, который выполняет тесты конкурентно.
[1]Познакомится с новым подходом можно в моей книге Structured Concurrency не магия.