WWDC24(Xcode 16)中全新的 Swift Testing 使用进阶

在这里插入图片描述

概述

WWDC 24 祭出的全新单元测试系统着实让苹果开发者们眼前一亮。“原来测试还可以这么爽!?”,日渐逼近蟋蟀发型的某位码农如是说。

在这里插入图片描述

Swift Testing 在简洁性以及灵活性全面超越老大哥 XCTest 的同时,也让秃头码农们真正见识到了 Swifty 范儿测试的灵魂。

在本篇博文中,您将学到如下内容:

  • 概述
  • 1. 如何为测试加上“构造”和“析构”器
  • 2. 如何依次串行测试?
  • 总结

本篇是《用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门》系列博文的进阶学习,希望大家喜欢。

那还等什么呢?Let‘s Testing!!!😉


1. 如何为测试加上“构造”和“析构”器

在以往的 XCTest 测试系统中,我们是用 XCTestCase 派生子类中的特定方法来完成每个测试的初始化和清理操作的:

final class MyUnitTests: XCTestCase {// 初始化测试override func setUpWithError() throws {continueAfterFailure = false}// 清理测试override func tearDownWithError() throws {}
}

而在新的 Swift Testing 中,我们只需使用类型本就具有的构造和析构器即可。

比如在下面的测试中,我们将所有独立的测试方法一并放到 ModelTests 结构中,然后借助结构的构造器来完成测试的初始化工作:

struct ModelTests {let container: ModelContainer// 测试前的所有初始化操作统统进来!!!init() throws {let config = ModelConfiguration(isStoredInMemoryOnly: true)container = try ModelContainer(for: User.self, configurations: config)}@Test func verifyBulkImport() throws {User.bulkImport()let modelContext = ModelContext(container)let count = try modelContext.fetchCount(FetchDescriptor<User>())#expect(count == 100)}
}

类似的,如果我们需要在测试之后完成一些必要的清理工作,同样可以将上面的结构“升级”为类,然后利用类的析构方法来搞定它们:

class ModelTests {let container: ModelContainerinit() throws {let config = ModelConfiguration(isStoredInMemoryOnly: true)container = try ModelContainer(for: User.self, configurations: config)}// 利用类的析构器来将测试之后的一切清理干净!deinit {container.deleteAllData()}@Test func verifyBulkImport() throws {User.bulkImport()let modelContext = ModelContext(container)let count = try modelContext.fetchCount(FetchDescriptor<User>())#expect(count == 100)}
}

如您所见:在 Swift Testing 中我们没有搞任何“特殊行为”,仅仅借助结构和类的“原始本能”即可轻松将测试的初始化和清扫工作化为无形,就问大家赞不赞呢?

2. 如何依次串行测试?

在包含海量 Testing 方法的单元测试中,为了达到客观的“公平公正”,我们往往需要这些方法随机执行:即每次测试它们的执行顺序都是不确定的。这样做到好处是可以将可能出现的代码依赖关系降到最低。

这还不算完!为了最大化保证测试的“实事求是”,我们还需要这些测试的执行可以重叠,即它们可以并发运行

struct ModelTests {var model = Model.shared@Test("测试创建 Itmes", .tags(.createItem))mutating func createItems() {print("#1 start")model.createItems()#expect(!model.items.isEmpty, "应该成功创建若干 Items!")print("#1 end")}@Test("测试删除所有 Item")mutating func delItem(){print("#2 start")model.createItems()#expect(!model.items.isEmpty)model.deleteAllItems()#expect(model.items.isEmpty, "应该成功删除所有 Items!")print("#2 end")}@Test("无厘头测试")mutating func noHead(){print("#3 start")#expect(true)print("#3 end")}
}

在上面的 ModelTests 测试中,多次运行可以发现其中 3 个测试方法的执行顺序皆是变幻无穷。甚至某个方法还未完成,另一个方法就“跃跃欲试”了:

Test run started.Testing Library Version: 102 (arm64-apple-ios13.0-simulator)Suite ModelTests started.Test "测试创建 Itmes" started.Test "测试删除所有 Item" started.Test "无厘头测试" started.
#2 start
#3 start
#2 end
#3 end
✔ Test "测试删除所有 Item" passed after 0.001 seconds.Test "无厘头测试" passed after 0.001 seconds.
#1 start
#1 end
✔ Test "测试创建 Itmes" passed after 0.001 seconds.Suite ModelTests passed after 0.001 seconds.Test run with 3 tests passed after 0.001 seconds.

但在某些场景中,我们可能也需要测试方法能够按照它们定义的顺序依次串行执行。这在 Swift Testing 里非常容易,简直轻而易举!

只需使用 @Suite 宏即可优雅的“樽前月下”:

在这里插入图片描述

更具体的说,在 @Suite 宏的若干 SuiteTrait 中包含一个 serialized 特性,它就是测试里我们那个“真命天子”:

在这里插入图片描述

还拿上面的 ModelTests 测试结构来说,其中的内容无需做任何改变,只需用 @Suite 宏如此这般修饰它即可:

@Suite(.serialized)
struct ModelTests {...}

再次运行测试可以看到,所有测试方法都会“言听计从”的自上而下串行执行了:

Test run started.Testing Library Version: 102 (arm64-apple-ios13.0-simulator)Suite ModelTests started.Test "测试创建 Itmes" started.
#1 start
#1 end
✔ Test "测试创建 Itmes" passed after 0.001 seconds.Test "测试删除所有 Item" started.
#2 start
#2 end
✔ Test "测试删除所有 Item" passed after 0.001 seconds.Test "无厘头测试" started.
#3 start
#3 end
✔ Test "无厘头测试" passed after 0.001 seconds.Suite ModelTests passed after 0.001 seconds.Test run with 3 tests passed after 0.001 seconds.

当然如果我们希望的话,还可以利用 @Suite 宏丰富多彩的构造器来让测试更加“银杏化”:

@Suite("大熊猫侯佩的大测试", .serialized)
struct ModelTests {...}

在这里插入图片描述

现在,相信小伙伴们对 Xcode 16 中崭新的 Swift Testing 都轻车熟路、了如指掌了吧?棒棒哒!💯


更多关于 Swift Testing 测试系统的介绍,请小伙伴们移步如下链接观赏精彩的内容:

  • 用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门(一)
  • 用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门(二)
  • 用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门(三)

想要系统学习 Swift 的小伙伴们,欢迎到我的《Swift语言开发精讲》专栏来逛一逛哦:

在这里插入图片描述

  • 《Swift语言开发精讲》

总结

在本篇博文中,我们进一步讨论了 WWDC24(Xcode 16)中全新 Swift Testing 的驾驭之道,并用多个轻巧的“栗子”让小伙伴们明白晓畅。

感谢观赏,再会啦!😎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot驱动的多维分类知识管理系统

1 绪论 1.1 研究背景 在这个推荐个性化的时代&#xff0c;采用新技术开发一个多维分类的知识管理系统来分享和展示内容是一个永恒不变的需求。本次设计的多维分类的知识管理系统有管理员和用户两个角色。 管理员可以管理用户信息&#xff0c;知识分类&#xff0c;知识信息等&am…

Linux mint系统推荐软件

最近无意中&#xff0c;找到了多年前的老笔记本电脑&#xff0c;用个windows卡死所以想装个linux玩&#xff0c;感觉用这个来打代码是足够的了&#xff0c;装了linux最明显的特点就是&#xff0c;笔记本风扇不转了&#xff0c;且耗电量明显降低&#xff0c;有些软件可以推荐一下…

k8s-service、endpoints、pod之间是怎么进行网络互通的

k8s-service、endpoints、pod之间是怎么进行网络互通的 1、service2、endpoints3、service、endpoints、pod通信图4、不同服务pod内部间访问 1、service 在K8S中&#xff0c;Service是一种抽象&#xff0c;定义了一组Pod的逻辑集合和访问这些Pod的策略。首先&#xff0c;我们需…

命令行工具PowerShell使用体验

命令行工具PowerShell使用 PowerShell是微软开发的一种面向对象的命令行Shell和脚本语言环境&#xff0c;它允许用户通过命令行的方式管理操作系统。相较于传统CMD&#xff0c;PowerShell增加了面向对象的程序设计框架&#xff0c;拥有更强大的功能和扩展性。使用PowerShell可…

企业IT架构转型之道:阿里巴巴中台战略思想与架构实战感想

文章目录 第一章&#xff1a;数据库水平扩展第二章&#xff1a;中台战略第三章&#xff1a;阿里分布式服务架构HSF&#xff08;high speed Framework&#xff09;、早期Dubbo第四章&#xff1a;共享服务中心建设原则第五章&#xff1a;数据拆分实现数据库能力线性扩展第六章&am…

【优选算法篇】微位至简,数之恢宏——解构 C++ 位运算中的理与美

文章目录 C 位运算详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;位运算基础应用1.1 判断字符是否唯一&#xff08;easy&#xff09;解法&#xff08;位图的思想&#xff09;C 代码实现易错点提示时间复杂度和空间复杂度 1.2 丢失的数字&#xff08;easy&#xff0…

在 WPF 中,绑定机制是如何工作的?WPF数据绑定机制解析

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;数据绑定机制是其核心功能之一&#xff0c;广泛用于连接应用程序的UI&#xff08;用户界面&#xff09;和应用程序的业务逻辑层。数据绑定允许你将UI元素与数据源&#xff08;如对象、集合或其他数…

基于 STM32 的天气时钟项目中添加天气数据的网络获取功能

基于 STM32 的天气时钟项目中添加天气数据的网络获取功能&#xff0c;您需要确保您的开发环境具备网络连接能力。这里以 ESP8266 Wi-Fi 模块为例&#xff0c;详细说明如何实现网络获取天气数据的功能。 1. 硬件连接 连接 ESP8266 模块 请参考以下连接方式&#xff0c;将 ESP82…

删除conda和 pip 缓存的包

一般情况下&#xff0c;如我们在不同的cuda环境下不同的虚拟环境安装包时&#xff0c;系统会检测到之前其他cuda环境下缓存包安装&#xff0c;运行程序可能会报错。 那就要删掉缓存在装包。 删除 pip 缓存的包 pip cache purge2.或者安装某个包不使用缓存 pip install mmcv2…

Vosk 进行中文语音识别实例

这个示例展示了如何在 Qt 中集成 Vosk 进行中文语音识别。该示例不仅涵盖了录音的设置与保存,还确保录制的音频文件符合 Vosk 的要求格式。通过 Vosk 的中文模型,我们可以对音频内容进行识别,获取准确的中文转写结果。此外,示例中通过 QString::fromUtf8 来正确解析 Vosk 返…

晓宇电视 1.9 | 电视直播软件,几千频道,高清秒播

晓宇电视是一款电视直播软件&#xff0c;提供数千个高清频道&#xff0c;支持秒播。最大的特色是没有广告&#xff0c;且不需要用户手动更新源地址。安装后即可使用&#xff0c;频道节目丰富&#xff0c;包括影视剧轮播专区&#xff0c;用户可以轻松观看喜爱的电影和电视剧。软…

双指针算法的妙用:提高代码效率的秘密(2)

双指针算法的妙用&#xff1a;提高代码效率的秘密&#xff08;2&#xff09; 前言&#xff1a; 小编在前几日讲述了有关双指针算法两道题目的讲解&#xff0c;今天小编继续进行有关双指针算法习题的讲解&#xff0c;老规矩&#xff0c;今天还是两道题目的讲解&#xff0c;希望…

mysql删除语句:@Update(“TRUNCATE TABLE employee“)讲解

这个 SQL 语句&#xff1a; TRUNCATE TABLE employee是一个 SQL DDL&#xff08;数据定义语言&#xff09; 操作&#xff0c;用于清空数据库表中的所有记录&#xff0c;但不会删除表结构&#xff08;即列和索引等&#xff09;。 逐部分解释&#xff1a; TRUNCATE&#xff1a;…

前端实现数据下载为json文件

数据be like const res [{xxx:111,ccc:[]}]实现&#xff1a; const data JSON.stringify(res, null, 4)const file new Blob([data], { type: text/json })const link document.createElement(a)link.download 名称.jsonlink.href URL.createObjectURL(file)link.click()…

MySQL:客户端工具创建数据库

MySQL 是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;用于存储、管理和检索数据。MySQL是基于SQL语言的&#xff0c;它具有高效、可靠、易用的特点。 客户端工具 这个mysqld.exe就在计算机安装的数据可服务&#xff0c;启动之后&#xff0c;mys…

使用python向钉钉群聊发送消息

使用python向钉钉群聊发送消息 一、在钉钉群中新建机器人二、使用代码发送消息 一、在钉钉群中新建机器人 在群设置中添加机器人 选择自定义 勾选对应的安全设置 完成后会展示webhook&#xff0c;将地址复制出来&#xff0c;并记录&#xff0c;后面会用到 二、使用代码发送消…

【芯智雲城】Sigmastar星宸科技图传编/解码方案

一、图传技术简介 图传是指将图像或媒体内容从一个设备传输到另外一个设备的技术&#xff0c;传输的媒介可以是无线电波、光纤、以太网等。图传系统主要由图像采集设备、传输设备和接收设备组成&#xff0c;图像采集设备负责采集实时图像&#xff0c;传输设备将采集到的图像转…

【计网不挂科】计算机网络期末考试(综合)——【选择题&填空题&判断题&简述题】完整题库

前言 大家好吖&#xff0c;欢迎来到 YY 滴计算机网络 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 本博客主要内容&#xff0c;收纳了一部门基本的计算机网络题目&#xff0c;供yy应对期中考试复习。大家可以参考 欢迎订阅 YY滴其他专栏&#xff01;…

C#核心(9)静态类和静态构造函数

前言 我们先前已经了解了静态成员的基本构成&#xff0c;也简单了解了一下静态变量&#xff0c;现在我们就要来看一下静态类和静态构造函数了&#xff0c;这些其实在上一节我已经在例子里有提到过&#xff0c;相信聪明的你甚至已经发现了一些规律。 GPT对c#中静态类和静态构造…

SSRF〈2〉

SSRF的进阶 1.Gopher协议的利用 1.gopher协议可以通过url指向指定IP端口发送任意内容&#xff0c;模拟大多数TCP协议&#xff0c;是SSRF中的一把利刃。 gopher协议URL&#xff1a; gopher://<host>:<port>/_<url编码的TCP数据> 这个url编码的TCP数据是goph…