关于iOS测试
Posted 颐和园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于iOS测试相关的知识,希望对你有一定的参考价值。
- 如何 Update snapshot image
如果修改了 UI,那么当你提 PR 时很可能 UITest 会测试失败,因为 UI 有了改变。
你会看到测试代码在哪里失败,比如 OnboardLandingViewControllerTests 类的某 某方法等。
找到这个类的 setUp 方法添加: recordMode = true
然后运行 snapshot test,然后 snapshot test 会录制一张图片并打印出图片路径 (有 时候可能需要将这张图片复制一份到 cosmos-ios-lib/TestSupport/ ReferenceImages_64 下面对应子目录),然后将 recordMode 一句删除,push,注 意应该勾选上那张图片一起提交。
回去 Jenkins ⻚面,点击 reRun failed testing
注意,需要选择 iPhone XR 13.3 模拟器并关闭 Dynamic font
2、无论用哪个模拟器,上传的 snapshots 总是无法通过测试
遇到个问题,snapshot test 要求 iPhone XR 13.3,但上传图片后还是失败。将模拟 器换成 iPhone XR 12.4 /13.3, iPhone 11 10.3-13.3 都试过了,还是不行。
先后提交了十多次代码,最后发现,需要将 Larger Accessibility Sizes 关闭, 然后 把字号大小恰好调到中间呢。因为之前为了测试 accessibility,已经改变了默认的 字体大小,导致截图和原来始终有区别。
4、‘xxx’ is inaccessible due to ‘private’ protection level
将这个属性标记为 private(set), 这样可以允许外部读取,但不能修改这个属性。
如果这是一个函数,则只能将它改成非 private。
5、单元测试中如何进行异步测试
// Create an expectation
let expectation = XCTestExpectation(description: "wait") let dispatchTime = DispatchTime.now()+1 DispatchQueue.main.asyncAfter(deadline: dispatchTime){
// Fullfil the expectation to let the test runner // know that it's OK to proceed expectation.fulfill()
}
// Wait for the expectation to be fullfilled, or time out
// after 1 seconds. This is where the test runner will pause. wait(for: [expectation], timeout: 2) XCTAssertTrue(mockNavigationController.navigationDidPop) XCTAssertTrue(mockNavigationController.navigationDidDismiss)
上面的方法可以用于单个文件的测试,但是整个 UT 和 jekins 将无法通过,所以还 是得用下面的方法。这个方法单个文件无法通过,但 UT 和 jenkins 都没问题:
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { XCTAssertTrue(interactor.requestCardLostStolenCalled)
}
注意,timeout 的时间最好设置得比 dispatchtime 多一些,否则又可能 expectiation 还没有 fullfill 就超时了。具体多多少不好说,这里多加 1 秒只是一个 经验值。
11、如何测试 tableview // Test for tableview
func testTableView() {
viewModel = SetupViewViewModel( title: "title",
sectionModels: [ SectionModel(
title: "title", cellModels: [
DetailsTableViewCell.ViewData( reviewItem: ReviewItem.ViewModel(
title: AccessibleValue("title"), value: AccessibleValue("value"), subValue: nil,
hasBottomDivider: false ),
valueAccessibilityLabel: nil, subValueAccessibilityLabel: nil, hasBottomDivider: false
) ]
) ],
confirmButtonTitle: "confirmButtonTitle" )
viewController.reviewCellConfig = viewModel.sectionModels viewController.tableView.reloadData()
debugPrint(viewController.reviewCellConfig)
// Test for headerInsection
let header = viewController.tableView(viewController.tableView,
viewForHeaderInSection: 1) XCTAssertNotNil(header)
// Test for heightForHeaderInSection
let height = viewController.tableView(viewController.tableView, heightForHeaderInSection: 0)
XCTAssertNotEqual(0, height)
// Test for cellForRowAtIndexPath
let cell = viewController.tableView(viewController.tableView, cellForRowAt: IndexPath(row: 0, section: 0))
}
13、不要用单个文件测试代替整个 UT 测试
因为有时候,单个文件测试通过,不表示整个 UT 通过,而且这样的测试代码在 Jekins 上是通不过的。
14、测试 presenter 时出现的一个问题
测试 presentSetupView 时,发现单个文件测试通过,但是整个 UT 报错,同时提
交代码后 jenkiins 测试失败。
最后发现是 presenter 的 presentSetupView 写的有问题。
因为 presentSetupView 中有一个判断,只有满足条件才调用 viewController 的 displaySetupView 方法。测试的时候条件不满足,所以没有调用,导致测试不通 过。
15、NSMutableAttributedString 导致 UT crash 的问题
比如这行代码在 UT 中会通不过:
let message = try? NSMutableAttributedString( data: data,
options: [
.documentType: NSAttributedString.DocumentType.html,
],
documentAttributes: nil )
这是一个 known bug,https://developer.apple.com/forums/thread/115405
由于这个方法在解析含有 html 标签 data 时导致主线程阻塞过⻓,由于 App 中多线 程执行的场景不多,所以不会有问题。但是在 UT 中,由于有大量 asyncAfter 调 用,所以会出现 crash。
如果将 option 参数改为:
options: [
.documentType: NSAttributedString.DocumentType.plain, ],
则不会导致此问题。尝试过将 html 设置为空字符串,但是仍然不行,只有改 option。
以上是关于关于iOS测试的主要内容,如果未能解决你的问题,请参考以下文章