{"id":44121,"date":"2024-07-17T14:52:20","date_gmt":"2024-07-17T18:52:20","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=44121"},"modified":"2024-07-17T14:52:20","modified_gmt":"2024-07-17T18:52:20","slug":"xctest-in-xcode-16","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2024\/07\/17\/xctest-in-xcode-16\/","title":{"rendered":"XCTest in Xcode 16"},"content":{"rendered":"<p><a href=\"https:\/\/www.jessesquires.com\/blog\/2024\/07\/09\/uitest-improvements-in-xcode-16\/\">Jesse Squires<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.jessesquires.com\/blog\/2024\/07\/09\/uitest-improvements-in-xcode-16\/\"><p>The first is <a href=\"https:\/\/developer.apple.com\/documentation\/xctest\/xcuielement\/4391535-waitfornonexistence\"><code>waitForNonExistence(withTimeout:)<\/code><\/a>, which provides the inverse of the existing <code>waitForExistence(timeout:)<\/code> API. Finally! This is such a welcome change. Often in UI testing it is more semantic to wait for an element to <em>disappear<\/em> rather than <em>appear<\/em> &mdash; for example, waiting for a loading indicator or waiting for a <a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uicontentunavailableview\"><code>UIContentUnavailableView<\/code><\/a> to disappear. Previously, you would have to roll your own implementation or awkwardly use <code>waitForExistence(timeout:)<\/code> and negate the result &mdash; both options are cumbersome and inefficient.<\/p><p>[&#8230;]<\/p><p>The second new API is <a href=\"https:\/\/developer.apple.com\/documentation\/xctest\/xcuielement\/4395161-wait\"><code>wait(for:toEqual:timeout:)<\/code><\/a>, which waits for a property value of an element to equal a new value. This is useful for when the contents of an existing view should be updated and you want to verify the update happened. The most common use case here is likely for checking the contents of labels, text fields, or text views that change based on state updates or user interaction. Previously, there was not a great way to achieve this without introducing artificial timeouts in your test, or changing the UI element&rsquo;s <a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uiaccessibilityidentification\/1623132-accessibilityidentifier\"><code>.accessibilityIdentifier<\/code><\/a> in your app when its contents updated and then checking for the existence of the new identifier.<\/p><\/blockquote>\n<p>But he says that the latter currently doesn&rsquo;t work.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/07\/17\/swift-testing-in-xcode-16\/\">Swift Testing in Xcode 16<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/07\/17\/xcode-16-announced\/\">Xcode 16 Announced<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Jesse Squires: The first is waitForNonExistence(withTimeout:), which provides the inverse of the existing waitForExistence(timeout:) API. Finally! This is such a welcome change. Often in UI testing it is more semantic to wait for an element to disappear rather than appear &mdash; for example, waiting for a loading indicator or waiting for a UIContentUnavailableView to disappear. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2024-07-17T18:52:25Z","apple_news_api_id":"0e895d76-1978-455d-a5c9-024a5348ae38","apple_news_api_modified_at":"2024-07-17T18:52:25Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/ADolddhl4RV2lyQJKU0iuOA","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[30,2598,71,268,226],"class_list":["post-44121","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-mac","tag-macos-15-sequoia","tag-programming","tag-testing","tag-xcode"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/44121","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=44121"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/44121\/revisions"}],"predecessor-version":[{"id":44122,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/44121\/revisions\/44122"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=44121"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=44121"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=44121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}