概述
Swift-Mimic
是一个库,用于使用最少的代码更改模拟网络请求。它可以用于
- 将单元测试和 UI 测试转换为在模拟 API 响应上运行,最小化测试维护并优化测试速度
- 在新功能准备好实际 API 端点之前开发新功能,只需少量代码更改
Swift-Mimic
被设计为包含所有部件、易于集成的解决方案,具有几个可扩展的功能
- 基于文件的模拟捆绑包,反映了 API 端点结构,并附带基础 URL
- 支持多个模拟捆绑包套件,可以根据不同的测试场景进行层叠覆盖
- 可交换的模拟捆绑协议,如果需要,可以开发自己的高级捆绑格式
- 自动发现模拟捆绑包中的端点,因此默认场景不需要代码
- 使用三条代码即可与任何现有的单元或 UI 测试集成
安装
我们建议使用 Cocoapods 进行安装
pod 'swift-mimic'
重要:由于一个已知的 Cocoapods 问题,UI 测试可能无法编译。目前记录的解决方案是将以下 post_install
钩子包括在您的 Podfile
中
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# This works around a unit test issue introduced in Xcode 10.
# We only apply it to the Debug configuration to avoid bloating the app size
if config.name == "Debug" && defined?(target.product_type) && target.product_type == "com.apple.product-type.framework"
config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = "YES"
end
end
end
end
配置
创建模拟包
在配置应用程序使用《Swift-Mimic》之前,第一步是创建一个API模拟包。有几种方法可以做到这一点,从手动生成文件夹和文件结构到使用记录器框架,如SWHttpTrafficRecorder。
模拟包的结构很简单。假设您有一个提供以下端点的API
- https://my-service.com/api/authenticate/
- https://my-service.com/api/users/
- https://my-service.com/api/projects/
假设您将模拟以下请求
- POST https://my-service.com/api/authenticate/
- GET https://my-service.com/api/users/
- GET https://my-service.com/api/projects/
- POST https://my-service.com/api/projects/
然后您的模拟包结构应该是这样的
- Mocks.bundle
- api
- authenticate
- post.json
- users
- get.json
- projects
- get_200.json
- post_201.json
- authenticate
- api
列表中的每个JSON文件都应该包含要模拟的API响应。文件名可以提供两种格式:HTTP METHOD.json
或 HTTP METHOD_RESPONSE CODE.json
。如果您没有提供响应代码,则《Swift-Mock》将假设匹配的HTTP方法是默认文件,并将其优先级高于其他文件。
您可以在Xcode项目中添加该包的任何位置,但是确保它同时与主应用程序目标以及测试目标链接。
您可以创建任意数量的包,以便在单个基本URL下组织端点或支持多个API URL下的模拟。
更新网络集成
为了使《Swift-Mimic》能够在不添加额外代码的情况下覆盖网络请求,您需要将一个特殊配置传递给API请求层使用的活动《URLSession》。这很容易做到,以下是一个使用《Alamofire》的示例
if let mockUrlSessionConfiguration = MimicSession.shared?.urlSessionConfiguration {
sessionManager = Alamofire.SessionManager(configuration: mockUrlSessionConfiguration)
} else {
sessionManager = SessionManager.default
}
这是一个标准的《URLSessionConfiguration》对象,因此它可以传递给任何在《URLSession》上运行的任何网络层,包括苹果的原始实现。
设置测试套件
最后一步是在您的测试层中定义您的模拟套件,以便测试运行器知道它配置的模拟。这里是最简单的实现方式
import XCTest
import swift_mimic
extension XCUIApplication: MimicUIApplication {
}
class ExampleTest: XCTestCase {
var app: XCUIApplication = XCUIApplication()
override func setUp() {
continueAfterFailure = false
let suite = MIMMockSuite(baseURL: "https://my-service.com", bundleNames: "Mocks")
try? MimicLauncher.launch(app, with: [suite])
}
}
这里有几个事情在进行。首先,我们要确保 XCUIApplication
被配置为包括 MimicUIApplication
。你只需要在测试目标中完成这一步,而且只需一次。
然后,我们创建一个指向项目中的正确包的 MIMMockSuite
实例,并将其与我们要覆盖的 API 基础 URL 配对。
最后,我们使用我们刚刚创建的套件调用 MimicLauncher
,以便它可以在配置中包含它。
你可以创建尽可能多的套件,并按你想它们被加载的顺序将它们传递给启动器。比如说,你有一个针对测试套件的特殊认证案例。如果不同基础 URL 对于案例是必需的,你可以通过以下方式利用套件的级联性质来实现:
class ExampleTest: XCTestCase {
var app: XCUIApplication = XCUIApplication()
override func setUp() {
let suite = MIMMockSuite(baseURL: "https://my-service.com", bundleNames: "Mocks")
let adminSuite = MIMMockSuite(baseURL: "https://my-second-service.com", bundleNames: "AdminMocks")
try? MimicLauncher.launch(app, with: [suite, adminSuite])
}
}
如果你的这两种情况都使用相同的基 URL,你应该使用以下结构:
class ExampleTest: XCTestCase {
var app: XCUIApplication = XCUIApplication()
override func setUp() {
let suite = MIMMockSuite(baseURL: "https://my-service.com", bundleNames: ["Mocks", "AdminMocks"])
try? MimicLauncher.launch(app, with: [suite])
}
}
套件将按照数组中的倒序,从最后一个元素到第一个元素优先级进行排序。
发行历史
- 0.3.0 - 2019 年 1 月 15 日
- 添加自动发现和更简单的基本设置
- 0.2.5 - 2019 年 1 月 14 日
- 添加文档
- 0.2.3 - 2019 年 1 月 13 日
- 第一个稳定版本,包含完整示例项目
鸣谢
由 Hipo 团队构建,贡献者包括:
- Goktug Berk Ulu
- Eray Diler
- Salih Karasuluoglu
- Taylan Pince
贡献
- 分叉它 (https://github.com/Hipo/swift-mimic/fork)
- 创建您的功能分支 (
git checkout -b feature/fooBar
) - 提交您的更改 (
git commit -am '添加一些 fooBar'
) - 将更改推送到分支 (
git push origin feature/fooBar
) - 创建新的拉取请求
许可证
在 MIT 许可证下分发。有关更多信息,请参阅 LICENSE
文件。