From 476e4544dcc3ba47aaa005d9b8ed63044c96fc2b Mon Sep 17 00:00:00 2001 From: Michael Link Date: Tue, 12 May 2026 16:15:46 -0500 Subject: [PATCH] Update README.md and swift-testing unit tests for clarity of usage --- README.md | 5 +-- Tests/SwiftTesting/SubprocessSwiftTests.swift | 33 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 83e88d2..7e23270 100644 --- a/README.md +++ b/README.md @@ -223,10 +223,11 @@ func testSoftwareVersion() async throws { } ``` -Apply it to a whole suite to cover every test in the type: +Apply it to a whole suite to cover every test in the type (all tests inherit the suite level shared `@TaskLock`): ```swift -@Suite(.subprocess) +// Using `.subprocess` at the suite level you will almost certainly need to also use `.serialized` +@Suite(.serialized, .subprocess) struct MyCommandTests { @Test func testGrep() async throws { diff --git a/Tests/SwiftTesting/SubprocessSwiftTests.swift b/Tests/SwiftTesting/SubprocessSwiftTests.swift index 5e8fc96..7b502fb 100644 --- a/Tests/SwiftTesting/SubprocessSwiftTests.swift +++ b/Tests/SwiftTesting/SubprocessSwiftTests.swift @@ -7,7 +7,7 @@ import SubprocessTesting @Suite struct SubprocessSwiftTests: ~Copyable { - @Test(.subprocessTesting, arguments: 0..<100) + @Test(.subprocess, arguments: 0..<100) func `mocks can handle parallel testing`(_ count: Int) async throws { let testFileURL = URL(fileURLWithPath: "/tmp/\(Self.self)-\(UUID().uuidString).txt") @@ -35,7 +35,7 @@ struct SubprocessSwiftTests: ~Copyable { } @Test(arguments: 0..<5) - func `other testing still works`(_ count: Int) async throws { + func `direct test of command still works`(_ count: Int) async throws { let testFileURL: URL = { let url = URL(fileURLWithPath: "/tmp/\(Self.self)-\(UUID().uuidString).txt") @@ -49,8 +49,8 @@ struct SubprocessSwiftTests: ~Copyable { try FileManager.default.removeItem(at: testFileURL) } - @Test(.subprocessTesting, arguments: ["foo", "bar", "baz"]) - func testEcho(_ word: String) async throws { + @Test(.subprocess, arguments: ["foo", "bar", "baz"]) + func echo(_ word: String) async throws { Subprocess.expect(["/bin/echo", word], standardOutput: "\(word)\n".data(using: .utf8)) let output = try await Subprocess.string(for: ["/bin/echo", word]) @@ -59,8 +59,8 @@ struct SubprocessSwiftTests: ~Copyable { try Subprocess.verify() } - @Test(.subprocessTesting) - func testSoftwareVersion() async throws { + @Test(.subprocess) + func `software version`() async throws { Subprocess.expect(["/usr/bin/sw_vers", "-productVersion"], standardOutput: "15.0\n".data(using: .utf8)) let version = try await Subprocess.string(for: ["/usr/bin/sw_vers", "-productVersion"]) @@ -70,10 +70,11 @@ struct SubprocessSwiftTests: ~Copyable { } } -@Suite(.subprocessTesting) +@Suite(.subprocess) struct MyCommandTests: ~Copyable { - @Test - func testGrep() async throws { + // must be serialized otherwise concurrent usage will race against the suite shared mock storage + @Test(.serialized, arguments: 0..<10) + func grep(count: Int) async throws { Subprocess.expect(["/usr/bin/grep", "foo"], standardOutput: "foo bar\n".data(using: .utf8)) let result = try await Subprocess.string(for: ["/usr/bin/grep", "foo"]) @@ -83,7 +84,7 @@ struct MyCommandTests: ~Copyable { } @Test - func testMissingFile() async throws { + func `missing file`() async throws { let error = NSError(domain: NSPOSIXErrorDomain, code: Int(ENOENT)) Subprocess.expect(["/bin/cat", "/no/such/file"], error: error) @@ -91,6 +92,18 @@ struct MyCommandTests: ~Copyable { try await Subprocess.data(for: ["/bin/cat", "/no/such/file"]) } } + + // this test creates its own isolated mocks separate from the other tests + @Test(.subprocess, arguments: 0..<10) + func `grep returns an error`(count: Int) async throws { + let error = NSError(domain: NSPOSIXErrorDomain, code: Int(ENOENT)) + Subprocess.expect(["/usr/bin/grep", "foo"], error: error) + + await #expect(throws: (any Error).self) { + try await Subprocess.string(for: ["/usr/bin/grep", "foo"]) + } + try Subprocess.verify() + } } private extension SubprocessSwiftTests {