草庐IT

ios - XCTestCase - iOS UI 测试 - 处理具有多个单元格的 UITableViews

coder 2023-07-27 原文

我正在试验 (Xcode 7) UI XCTestCase 测试用例,我偶然发现了一个 UIView 的问题,其中我有一个包含许多单元格(4000+)的 UITableView。

当应用程序正常运行时,仅渲染可见单元格,完全没有性能问题。 但是,如果我在记录 XCTestCase 的上下文中运行该应用程序并导航到此屏幕,模拟器会卡住,这显然是因为每个单元格都呈现为好像它是可见的。 如果我尝试手动编写导航脚本并运行 XCTestCase,则测试用例会在导航到此屏幕后立即失败,并退出并显示“UI 测试失败 - 无法获取刷新的快照”,这显然又是因为所有单元格都被渲染了,这没有及时完成。

我认为这与以下事实有关:测试框架构建了所显示屏幕的完整元模型,将 4000 多个单元格中的每一个单元格添加到 View 树层次结构中。

我尝试添加一个期望值,希望这会给测试容器足够的时间来完成所有单元格的渲染,但这不起作用。

有解决办法吗?是否可以以某种方式跳过构建 UI 树层次结构的一部分或其他内容? 我的目标是能够为此屏幕编写 UI 测试。

最佳答案

如果您可以使用 firstMatch 而不是 element,并且还可以避免 count,您也许可以避免呈现整个表格。

我进行了一项测试,检查表格前两个单元格中的预期标签。起初,我使用 app.table.cells.element(boundBy: 0)app.table.cells.element(boundBy: 1) 找到第一个和第二细胞。这导致在我可以访问单元格之前呈现整个表格。

我调整了我的测试,使其不太精确,但对我来说仍然足够好(考虑到否则会花费大量时间)。相反,我将 matching 与预期标签值上的谓词一起使用,使用 firstMatch 来查找与我想要的条件匹配的第一个单元格。这样一来遍历就停止了(因为它们在表的顶部,所以很快)。

这是前后的代码。

之前(慢,但更精确):

private func checkRhymes(query: String, expectedFirstRhyme: String, expectedSecondRhyme: String) {
    let table = app.tables.element
    let cell0 = table.cells.element(boundBy: 0)
    let cell1 = table.cells.element(boundBy: 1)
    let actualRhyme0 = cell0.staticTexts.matching(identifier: "RhymerCellWordLabel").firstMatch.label
    let actualRhyme1 = cell1.staticTexts.matching(identifier: "RhymerCellWordLabel").firstMatch.label

    XCTAssertEqual(expectedFirstRhyme, actualRhyme0, "Expected first rhyme for \(query) to be \(expectedFirstRhyme) but found \(actualRhyme0)")
    XCTAssertEqual(expectedSecondRhyme, actualRhyme1, "Expected first rhyme for \(query) to be \(expectedSecondRhyme) but found \(actualRhyme1)")
}

更快,但不够精确(但足够好):

private func checkRhymes(query: String, expectedFirstRhyme: String, expectedSecondRhyme: String) {
    let table = app.tables.firstMatch
    let label0 = table.cells.staticTexts.matching(NSPredicate(format: "label = %@", expectedFirstRhyme)).firstMatch
    let label1 = table.cells.staticTexts.matching(NSPredicate(format: "label = %@", expectedSecondRhyme)).firstMatch

    // We query for the first cells that we find with the expected rhymes,
    // instead of directly accessing the 1st and 2nd cells in the table,
    // for performance issues.
    // So we can't add assertions for the "first" and "second" rhymes.
    // But we can at least add assertions that both rhymes are visible,
    // and the first one is above the second one.
    XCTAssertTrue(label0.frame.minY < label1.frame.minY)
    XCTAssertTrue(label0.isHittable)
    XCTAssertTrue(label1.isHittable)
}

引用: https://developer.apple.com/documentation/xctest/xcuielementquery/1500515-element

Use the element property to access a query’s result when you expect a single matching element for the query, but want to check for multiple ambiguous matches before accessing the result. The element property traverses your app’s accessibility tree to check for multiple matching elements before returning, and fails the current test if there is not a single matching element.

In cases where you know categorically that there will be a single matching element, use the XCUIElementTypeQueryProvider firstMatch property instead. firstMatch stops traversing your app’s accessibility hierarchy as soon as it finds a matching element, speeding up element query resolution.

关于ios - XCTestCase - iOS UI 测试 - 处理具有多个单元格的 UITableViews,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33529380/

有关ios - XCTestCase - iOS UI 测试 - 处理具有多个单元格的 UITableViews的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  9. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  10. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

随机推荐