如何使用 Xcode UITest 检查测试是否在应用程序中引发异常

问题描述 投票:0回答:1

我正在尝试在 Xcode 中编写 UI 测试,以便能够知道我的代码是否会导致 UITableView 在刷新拉刷新期间崩溃。

我的测试如下:

func testPullToRefresh_shouldNotCrash() throws {
    do {
        let app = XCUIApplication()
        app.launch()
        
        let tableView = app.tables.firstMatch
        try pullToRefresh(from: tableView)
    } catch {
        XCTFail("Crashed")
    }
}

也尝试过这样做:

    func testPullToRefresh_shouldNotCrash() {
    let app = XCUIApplication()
    app.launch()
    
    let tableView = app.tables.firstMatch
    XCTAssertNoThrow(try pullToRefresh(from: tableView))
}

当我运行测试时,应用程序崩溃了,我在 Xcode 中看到异常,但在所有测试成功之后

我尝试编写示例项目,但它无论如何都不起作用

示例代码:

视图控制器:

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!
    
    private var dataSource = DataSource()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.dataSource = dataSource
        tableView.delegate = dataSource
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: #selector(refreshData), for: .valueChanged)
        tableView.refreshControl = refreshControl
    }
    
    @objc func refreshData() throws {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            self.tableView.insertRows(at: [IndexPath(item: 0, section: 1)], with: .automatic)
            self.tableView.refreshControl?.endRefreshing()
        }
    }
}

数据来源:

import UIKit

class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
    
    var data = ["Cell 1", "Cell 2", "Cell 3", "Cell 4", "Cell 5"]
    
    // UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }
    
    // UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

测试:

import XCTest

final class ExceptionTestsUITests: XCTestCase {

    func testPullToRefresh_shouldNotCrash() throws {
        do {
            let app = XCUIApplication()
            app.launch()
            
            let tableView = app.tables.firstMatch
            try pullToRefresh(from: tableView)
        } catch {
            XCTFail("Crashed")
        }
    }
    
    func pullToRefresh(from element: XCUIElement) throws {
        let startPosition = CGPoint(x: 100, y: 100)
        let endPosition = CGPoint(x: 100, y: 500)
        let start = element.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)).withOffset(CGVector(dx: startPosition.x, dy: startPosition.y))
        let finish = element.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)).withOffset(CGVector(dx: endPosition.x, dy: endPosition.y))
        start.press(forDuration: 0, thenDragTo: finish)
    }
}

有什么办法让它发挥作用吗?

ios xcode xctest xcuitest
1个回答
0
投票

我猜问题出在您的 pullToRefresh 方法上,因为您已将 tableview 作为参考元素。尝试这样:

extension XCUIElement {
    func pullToRefresh() {
        if self.elementType == .table {
            let start = self.cells.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
            let finish = self.cells.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 7))
            start.press(forDuration: 0, thenDragTo: finish)
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.