How to write basic async tests 如何编写基本的异步测试

How to write basic async tests 如何编写基本的异步测试

温馨提示:本文最后更新于2025-02-10 11:45:32,某些文章具有时效性,若有错误或已失效,请在下方留言

Both Swift Testing and XCTest allow us to test asynchronous code built with Swift concurrency by marking tests as async. This means we can wait for concurrent code to complete using await, we can create tasks and task groups, we can use async let, and more. I’ll show you how it’s done first in Swift Testing, then in XCTest.
Swift Testing 和 XCTest 都允许我们通过将测试标记为异步来测试使用 Swift 并发构建的异步代码。这意味着我们可以使用 await 等待并发代码完成,我们可以创建任务和任务组,我们可以使用 async let 等等。我将首先在 Swift Testing 中向您展示它是如何完成的,然后在 XCTest 中完成。

Important: Regardless of whether you use XCTest or Swift Testing, it’s important you use @testable import YourAppTarget in your test code to make all your internal types available for testing.
重要: 无论您使用的是 XCTest 还是 Swift Testing,在测试代码中使用 @testable import YourAppTarget 所有内部类型都可用于测试,这一点很重要。

For Swift Testing, the main change to make is marking your @Test function as being async, like this:
对于 Swift Testing,要进行的主要更改是将你的 @Test 函数标记为async,如下所示:

struct DataHandling {
    @Test("Loading view model names")
    func loadNames() async throws {
        let viewModel = ViewModel()
        try await viewModel.loadNames()
        #expect(viewModel.names.isEmpty == false, "Names should be full of values.")
    }
}

If we were to make the same with XCTest, we’d write this:
如果我们要对 XCTest 进行相同的作,我们可以这样写:

final class DataHandlingTests: XCTestCase {
    func test_loadNames() async throws {
        let viewModel = ViewModel()
        try await viewModel.loadNames()
        XCTAssertFalse(viewModel.names.isEmpty, "Names should be full of values.")
    }
}

In both places, using await inside tests marks a potential suspension point, just like in production code. This potentially allows the test system to execute other tests while the first one is suspended, which in the case of Swift Testing is straightforward given that it was designed for parallel test execution as standard.
在这两个地方,在测试中使用 await 会标记一个潜在的暂停点,就像在生产代码中一样。这可能允许测试系统在第一个测试暂停时执行其他测试,这在 Swift Testing 的情况下很简单,因为它是为并行测试执行而设计的。

If the expectation you’re making is a requirement – if the whole test run should be considered a failure because the current test has failed – then in Swift Testing code you should use #require rather than #expect, like this:
如果你的期望是一个要求 —— 如果整个测试运行应该被认为是失败的,因为当前测试已经失败 —— 那么在 Swift 测试代码中,你应该使用 #require 而不是 #expect,像这样:

try #require(viewModel.names.isEmpty == false, "Names should be full of values.")

That check will throw an error on failure, which in turn will cause Swift Testing to exit the current test function.
该检查将在失败时引发错误,这反过来又会导致 Swift Testing 退出当前的测试函数。

In comparison, XCTest had a Boolean continueAfterFailure property on XCTestCase, which sort of did the same – as long as you were constantly toggling it each test, and didn’t forget one by accident.
相比之下,XCTest 在 XCTestCase 上有一个布尔值 continueAfterFailure 属性,该属性的作用相同 – 只要您在每次测试中不断切换它,并且不会意外忘记一个。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享