无法访问xctestcase UI测试中的SwiftUi文本

发布于 2025-02-01 17:23:23 字数 1555 浏览 2 评论 0原文

我正在尝试将UI测试添加到SwiftUI项目中。

我有一个列表,其中包含视图 - 然后包含许多视图。

我似乎无法在UI测试中访问最远的视图。

我以为我可以在每个元素上添加可访问性标识符,但我无法保持测试通行证。

一个非常简单的例子;

contentView

struct ListModel: Identifiable {
    let id: String
    let text: String
}

struct ContentView: View {
    
    private var state = (0..<50).map { ListModel(id: "\($0)", text: "Row \($0)") }
    
    var body: some View {
        List(state, id: \.id) { item in
            ContentViewRow(text: item.text)
                .accessibility(identifier: "FEED_ITEM")
        }
        .accessibility(identifier: "FEED")
    }
}

struct ContentViewRow: View {
    let text: String
    var body: some View {
        Text(text)
            .accessibility(identifier: "CONTENT_ROW_TEXT")
    }
}

测试

class TestingSwiftUIUITests: XCTestCase {

    func testExample() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()
        
        let feed = app.tables["FEED"]
        XCTAssert(feed.waitForExistence(timeout: 0.5))

        let row0 = feed.staticTexts["FEED_ITEM"].firstMatch
        XCTAssert(row0.waitForExistence(timeout: 0.5))
        
        let textView = row0.staticTexts["CONTENT_ROW_TEXT"].firstMatch
        XCTAssert(textView.waitForExistence(timeout: 0.5)) // <-- This fails.
    }
}

如何在contentViewrow内访问视图 - 谢谢。

I am trying to add UI tests to a SwiftUI project.

I have a list, which contains views - those then contain a number of views.

I cannot seem to access the furthest most view in my UI test.

I thought I could add an accessibility identifier to each element but I cannot make my test pass still.

A very simple example;

ContentView

struct ListModel: Identifiable {
    let id: String
    let text: String
}

struct ContentView: View {
    
    private var state = (0..<50).map { ListModel(id: "\($0)", text: "Row \($0)") }
    
    var body: some View {
        List(state, id: \.id) { item in
            ContentViewRow(text: item.text)
                .accessibility(identifier: "FEED_ITEM")
        }
        .accessibility(identifier: "FEED")
    }
}

struct ContentViewRow: View {
    let text: String
    var body: some View {
        Text(text)
            .accessibility(identifier: "CONTENT_ROW_TEXT")
    }
}

Tests

class TestingSwiftUIUITests: XCTestCase {

    func testExample() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()
        
        let feed = app.tables["FEED"]
        XCTAssert(feed.waitForExistence(timeout: 0.5))

        let row0 = feed.staticTexts["FEED_ITEM"].firstMatch
        XCTAssert(row0.waitForExistence(timeout: 0.5))
        
        let textView = row0.staticTexts["CONTENT_ROW_TEXT"].firstMatch
        XCTAssert(textView.waitForExistence(timeout: 0.5)) // <-- This fails.
    }
}

How can I access a view inside ContentViewRow - thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

-残月青衣踏尘吟 2025-02-08 17:23:23

标识符:content_row_text似乎被标识符覆盖:feed_item

也许您可​​以仅离开feed_item,并在需要时检查标签文本。

let row0 = feed.staticTexts["FEED_ITEM"].firstMatch
XCTAssert(row0.waitForExistence(timeout: 0.5))
XCTAssert(row0.label == "Row 0")

identifier: CONTENT_ROW_TEXT seems to be overriden by identifier: FEED_ITEM

Perhaps you can leave just FEED_ITEM and check for the label text if needed.

let row0 = feed.staticTexts["FEED_ITEM"].firstMatch
XCTAssert(row0.waitForExistence(timeout: 0.5))
XCTAssert(row0.label == "Row 0")
身边 2025-02-08 17:23:23

列出swiftui

swift UI视图代码

struct ContentView: View {
    
    @StateObject var viewModel = ContentViewModel()
    
    var body: some View {
        NavigationView {
            List(viewModel.list, id: \.id) { item in
                NavigationLink(destination: self.detailsView(content: item)) {
                    ContentViewRow(text: item.text)
                        .accessibility(identifier: "FEED_ITEM_\(item.id)")
                }
            }
            .listStyle(.plain)
            .padding(.all, 20)
            .accessibility(identifier: "FEED")
            .onAppear {
                self.viewModel.publishListModel()
            }
            .navigationTitle("List")
        }
    }
    
    func detailsView(content: ListModel) -> some View {
        return ContestDetailsView(content: content)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct ContentViewRow: View {
    let text: String
    var body: some View {
        Text(text)
            .accessibility(identifier: "CONTENT_ROW_TEXT")
    }
}
struct ContestDetailsView: View {
    var content: ListModel
    
    var body: some View {
        Text(content.text)
            .navigationTitle("Details")
            .accessibility(identifier: "FEED_Details")
    }
}

UI测试用例中的uitestcase

func testTableList() throws {
    // UI tests must launch the application that they test.
    let app = XCUIApplication()
    app.launch()
    
    let pred = NSPredicate(format: "identifier == 'FEED'")
    let tableView = app.descendants(matching: .any).matching(pred).firstMatch
    let arrOfTexts = tableView.staticTexts
    XCTAssertGreaterThan(arrOfTexts.count, 10)
    // let feed = app.tables["FEED"]
    XCTAssert(tableView.waitForExistence(timeout: 0.5))
    
    let row7 = tableView.staticTexts["FEED_ITEM_7"].firstMatch
    XCTAssert(row7.waitForExistence(timeout: 0.5))
    
    //let textView = row7.staticTexts["Row 7"].firstMatch
    //XCTAssert(textView.waitForExistence(timeout: 0.5)) // <-- This fails.
    
    row7.tap()
    let textView = app.staticTexts["Row 7"]
    // If the text ran successfully, the the above textView will be != Nil
    XCTAssertEqual(textView.exists, true)
}

List UITestCase in SwiftUI

Swift UI View Code

struct ContentView: View {
    
    @StateObject var viewModel = ContentViewModel()
    
    var body: some View {
        NavigationView {
            List(viewModel.list, id: \.id) { item in
                NavigationLink(destination: self.detailsView(content: item)) {
                    ContentViewRow(text: item.text)
                        .accessibility(identifier: "FEED_ITEM_\(item.id)")
                }
            }
            .listStyle(.plain)
            .padding(.all, 20)
            .accessibility(identifier: "FEED")
            .onAppear {
                self.viewModel.publishListModel()
            }
            .navigationTitle("List")
        }
    }
    
    func detailsView(content: ListModel) -> some View {
        return ContestDetailsView(content: content)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct ContentViewRow: View {
    let text: String
    var body: some View {
        Text(text)
            .accessibility(identifier: "CONTENT_ROW_TEXT")
    }
}
struct ContestDetailsView: View {
    var content: ListModel
    
    var body: some View {
        Text(content.text)
            .navigationTitle("Details")
            .accessibility(identifier: "FEED_Details")
    }
}

UI Test Case

func testTableList() throws {
    // UI tests must launch the application that they test.
    let app = XCUIApplication()
    app.launch()
    
    let pred = NSPredicate(format: "identifier == 'FEED'")
    let tableView = app.descendants(matching: .any).matching(pred).firstMatch
    let arrOfTexts = tableView.staticTexts
    XCTAssertGreaterThan(arrOfTexts.count, 10)
    // let feed = app.tables["FEED"]
    XCTAssert(tableView.waitForExistence(timeout: 0.5))
    
    let row7 = tableView.staticTexts["FEED_ITEM_7"].firstMatch
    XCTAssert(row7.waitForExistence(timeout: 0.5))
    
    //let textView = row7.staticTexts["Row 7"].firstMatch
    //XCTAssert(textView.waitForExistence(timeout: 0.5)) // <-- This fails.
    
    row7.tap()
    let textView = app.staticTexts["Row 7"]
    // If the text ran successfully, the the above textView will be != Nil
    XCTAssertEqual(textView.exists, true)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文