LocalServer
描述
LocalServer 是一个框架,它提供多种选项,可以在代码中直接创建 Swift Stub Local Server,它可以在模拟器和设备上独立运行,支持 Xcode Parallel Testing。它用 Swift 编写以创建 Stub Servers,UITest Servers,并提供了一种简单的方法来 Mock 功能以创建测试替身(伪造、存根、间谍和模拟)。它支持所有 Apple 平台 iOS、MacOS、WatchOS 和 TVOS。
它也与大多数Networking库兼容,如 Alamofire、Moya、AFNetworking 或本机的 URLSession 和 NSURLConnection。请查看 编程指南 部分,获取示例。
功能
- 在不改变或注入现有 URLSession 代码的情况下创建存根服务器
- 为 WKWebView 创建存根版本
- 支持模拟器和设备上的 Xcode Parallel Testing
- 用于单元测试的存根服务器
- UITest 存根服务器用于 UI 测试
运行应用 | 使用 Local Server 进行 UITest |
---|---|
生成随机用户 | 仅生成模拟用户 |
![]() |
![]() |
安装
您可以直接在单元测试目标中使用LocalServer,而无需为主目标添加任何额外代码。一旦单元测试在主目标中运行。
仅对UI测试目标,需要在主目标中添加一些额外代码。
CocoaPods
使用将以下内容添加到您的 Podfile 文件中
pod 'LocalServer'
Carthage
使用将以下内容添加到您的 Cartfile 或 Cartfile.private 文件中
github "db-in/LocalServer"
Swift Package Manager
使用将以下内容添加到您的 Package.swift 文件中
let package = Package(
name: "myproject",
dependencies: [
.package(url: "https://github.com/db-in/LocalServer"),
],
targets: [
.target(
name: "myproject",
dependencies: ["LocalServer"]),
]
)
编程指南
提供的功能包括
- 第三方网络库
- 占位服务器
- UITest服务器
第三方网络库(Alamofire、Moya 等)
无需修改主目标中的任何代码,即可模拟 单元测试目标!你不需要在生产代码中污染测试库或创建任何专门的架构以允许测试。
保留你的生产网络代码的原始形式,只需将以下代码添加到你的 单元测试目标 中:
import LocalServer
...
StubResponse(json: ["param" : "value"])
.withStatusCode(200)
.send(to: "apple")
上述代码足够模拟任何匹配包含 "apple"
的 URL 的调用,并返回上面定义的 JSON 模拟的 200 HTTP 状态码。
占位服务器
占位服务器是本地服务器的基座。它可以拦截使用 URLSession 进行的任何网络调用。
以下是一些创建 占位响应
的函数示例:
StubResponse(string: "UTF8 string to become body")
StubResponse(json: ["param" : "value", "number": 1])
StubResponse(filename: "file", ofType: "html")
StubResponse(filename: "file", ofType: "json", bundle: myBundle)
StubResponse(data: myBodyData)
针对更精细和具体的实现,为每个 HTTP 定义不同的响应:
import LocalServer
...
func startMyLocalServer() {
let server = StubServer()
server.route([.GET], url: "https://apple.com") { (request, parameters) -> StubResponse in
return StubResponse().withStatusCode(204)
}
server.route([.POST], url: "https://apple.com") { _,_ in
return StubResponse().withStatusCode(206)
}
StubServer.instance = server
}
你也可以测试网络错误
StubResponse()
.withError(MyMockNetworkError.noInternet)
.send(to: "https://apple.com")
重要提示:在定义相同的 HTTP 方法的占位 URL 时,请注意 URL 使用 正则表达式 进行评估,这意味着正则表达式可能会错误地相互覆盖并导致不正确的行为。另外,send(to:)
是一个方便的方法,因此底层使用共享服务器。每次将 StubServer.instance
设置为 nil
时都会重置。
一旦将 StubServer.instance
定义为非 nil
,它将启动本地服务器。要停止本地服务器,只需将其设置为 nil
,这是默认值。
UITest Server
根据苹果的设计,UITest 目标在独立的应用程序上运行,这意味着它无法访问主应用程序中的代码或执行任何编程操作。UITest 服务器使用 ProcessInfo
桥接在每次启动时将数据从 UITest 目标发送到主应用程序。
根据测试最佳实践,每个 UITest 用例都应该重新启动主应用程序。
项目结构
// UITest Target
|-- LocalServer
|-- JsonFile1.json
|-- JsonFile2.json
|-- JsonFile2.json
// Main Target
|-- LocalServer
所需代码
// UITest Target
UITestResponse()
.withStatusCode(201)
.send(to: "google.com")
// Main Target
UITestServer.start()
常见问题解答
我可以将 LocalServer 部署到生产环境(App Store)吗?
- 当然可以。主要目标是提供模拟和存根功能,但如果需要,您也可以将其用于生产环境。
如果我只用它进行调试,我应该使用
#if DEBUG
吗?
- 作为一个动态 Swift 框架,LocalServer 只会在首次调用时在运行时加载。所以,如果您的生产代码从不使用任何 LocalServer API,它甚至不会被加载。
#if DEBUG
可以使用,但是根据 UITest 标准,您还可以考虑使用类似XCUIApplication().launchArguments
+if ProcessInfo().arguments.contains("-UITests") { ... }
的方法 - UI 测试快速指南/
- 使用 Swift 在 Xcode 中进行 UI 测试入门
我可以模拟缓慢的网络响应吗?
- 是的,您可以在任何响应对象中使用
delay
属性来模拟。