Introduction to swift-concurrency-extras
The swift-concurrency-extras
project offers a range of tools to help developers manage Swift concurrency in a more testable and reliable manner. This project is particularly useful for developers who need to ensure the reliability of concurrent code in Swift applications.
Motivation
The core motivation behind this library is to make Swift concurrency more approachable and less prone to errors during testing. It provides several specialized tools:
LockIsolated
: A type designed to wrap values in an isolated context using a locking mechanism for thread-safe read and write operations.AnyHashableSendable
: Type-erased wrappers that retain thesendability
characteristic of the underlying values.- Streams: Features a few APIs that support Swift streams, making them easier to handle in tests.
- Tasks: Enhancements to Swift’s
Task
type to simplify its use, particularly in testing scenarios. - Serial Execution: A utility to help run tasks serially and deterministically, which is particularly useful in tests.
LockIsolated
The LockIsolated
type acts as a wrapper to make other values thread-safe by synchronizing access to them using locks. This allows developers to read and write values in a safe, synchronous manner, crucial for managing concurrency issues.
AnyHashableSendable
Much like AnyHashable
, this utility maintains the attribute of sendability
of the type it wraps. This is useful when you need a type-erased wrapper but don't want to lose the sendable nature of that type.
Streams
The library enhances the handling of Swift streams in a few ways:
- Back-ported Functions: Swift 5.9’s
makeStream(of:)
functions are included, allowing the simulation of streams during tests. - Static Helpers: Includes
AsyncStream.never
andAsyncThrowingStream.never
, representing streams that live infinitely without emitting values. These are beneficial for tests where a stream should indefinitely suspend. - Stream Completion: Provides
AsyncStream.finished
, which represents a stream that instantly finishes without emitting, helping in scenarios where a quick stream end is needed during tests.
Tasks
This library enhances the task handling capabilities:
Task.never()
: This utility allows a task to suspend indefinitely without completing, useful for satisfying dependency requirements mockingly.Task.cancellableValue
: Helps in awaiting a task's value while also attending to its cancellation state.Task.megaYield()
: A means to mitigate flakiness in async tests by introducing multiple suspensions to give other tasks time to execute.
Serial Execution
Testing asynchronous code often faces challenges due to the non-deterministic execution of tasks. The library offers withMainSerialExecutor
, which attempts to execute tasks serially and predictably within a test. However, this utility is test-specific and not recommended for production code due to potential modifications in Swift runtime that might affect execution.
Documentation and Resources
Documentation for the swift-concurrency-extras
project is continuously updated and available online. The library was inspired and supported by resources from the Point-Free video series, dedicated to exploring Swift.
Related Libraries
Several other libraries complement this project by offering tools that improve Swift code testability and architecture. Some notable ones include:
- Case Paths: For handling and testing enum cases.
- Clocks: For versatile time-based operations.
- Combine Schedulers: For managing Combine schedulers with ease.
- Composable Architecture: A methodology for constructing applications that prioritize testing and maintainability.
- Custom Dump: Utilities for inspecting and comparing data structures.
- Dependencies: For dependency management, particularly in environments inspired by SwiftUI.
- Snapshot Testing: Tools for visual and behavioral testing through recording snapshots.
- XCTest Dynamic Overlay: Calls testing utilities directly from application code, expanding test coverage possibilities.
License
The library is open source and released under the MIT License, inviting developers to use, modify, and distribute it freely.
This extensive collection of tools and utilities makes swift-concurrency-extras
a vital resource for developers aiming to streamline and ensure the reliability of Swift concurrency in their applications.