Skip to content

Latest commit

 

History

History
97 lines (79 loc) · 3.68 KB

File metadata and controls

97 lines (79 loc) · 3.68 KB

Running tests serially or in parallel

Control whether tests run serially or in parallel.

Overview

By default, tests run in parallel with respect to each other. Parallelization is accomplished by the testing library using task groups, and tests generally all run in the same process. The number of tests that run concurrently is controlled by the Swift runtime.

Disable parallelization

Parallelization can be disabled on a per-function or per-suite basis using the Trait/serialized trait:

@Test(.serialized, arguments: Food.allCases) func prepare(food: Food) {
  // This function will be invoked serially, once per food, because it has the
  // .serialized trait.
}

@Suite(.serialized) struct FoodTruckTests {
  @Test(arguments: Condiment.allCases) func refill(condiment: Condiment) {
    // This function will be invoked serially, once per condiment, because the
    // containing suite has the .serialized trait.
  }

  @Test func startEngine() async throws {
    // This function will not run while refill(condiment:) is running. One test
    // must end before the other will start.
  }
}

When added to a parameterized test function, this trait causes that test to run its cases serially instead of in parallel. When applied to a non-parameterized test function, this trait has no effect. When applied to a test suite, this trait causes that suite to run its contained test functions and sub-suites serially instead of in parallel.

The Trait/serialized trait is recursively applied: if it is applied to a suite, any parameterized tests or test suites contained in that suite are also serialized (as are any tests contained in those suites, and so on.)

This trait doesn't affect the execution of a test relative to its peers or to unrelated tests. This trait has no effect if test parallelization is globally disabled (by, for example, passing --no-parallel to the swift test command.)

Serialize tests across multiple files

You may want to organize tests across multiple files while preserving the serialization of a test suite. For example, consider a scenario where you spin up a live database for integration testing. You may want to have a large suite of tests across many files use that same database, but concurrent access to the database could cause test failures. To achieve this, you can mark a test suite as Trait/serialized and extend that type across your various files. Because the testing library recursively applies Trait/serialized to all test content within a suite, you can even put your tests in sub-suites.

  • FoodTruckDatabaseTests.swift
    @Suite(.serialized) struct FoodTruckDatabaseTests {}
  • FoodTruckDatabaseTests+Writing.swift
    extension FoodTruckDatabaseTests {
      @Test func insertOrder() { /* ... */ }
      @Test func updateOrder() { /* ... */ }
      @Test func deleteOrder() { /* ... */ }
    }
  • FoodTruckDatabaseTests+Reading.swift
    extension FoodTruckDatabaseTests {
      @Suite struct ReadingTests {
        @Test func fetchOrder() { /* ... */ }
        @Test func fetchMenu() { /* ... */ }
        @Test func fetchIngredients() { /* ... */ }
      }
    }

In the example above, all the test functions in the FoodTruckDatabaseTests extension and in ReadingTests will run serially with respect to each other because they are eventually contained within a test suite which is declared Trait/serialized.