Xcode 16 中 Swift Testing 的参数化(Parameterized)机制趣谈

概述
我们之前曾在 《用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门》系列博文以及《WWDC24(Xcode 16)中全新的 Swift Testing 使用进阶》博文中较为系统地介绍了今年 WWDC 24 中全新的 Swift Testing 测试系统。

不过 Swift Testing 的本领远不止于此!这里我们将会用它“最重量级”的特性之一 参数化(Parameterized) 让多输入样本测试易如反掌、收放自如。
在本篇博文中,您将学到如下内容:
- 概述
- 1. 传统多输入样本测试的弊端
- 2. Swift Testing 中全新的 Parameterized 机制
- 3. 对于可能抛出错误的测试也是不在话下!
- 4. 细粒度管控 Parameterized 中每个参数的测试
- 总结
利用 Swift Testing 中强大的 Parameterized 机制可以让秃头码农们的测试如虎添翼,那还等什么呢?
让我们马上开始测试吧!Let’s Testing!!!😉
1. 传统多输入样本测试的弊端
在以往的 XCTest 测试系统中,要想检测多个输入值的执行结果我们往往需要编写多个测试方法来一一验证。
enum ValidationError: Error {case valueTooSmallcase valueTooBigcase unknown
}struct Validator {static func validate(input: Int) throws(ValidationError) -> Bool {if input < 0 {throw .valueTooSmall} else if input > 100 {throw .valueTooBig} else {true}}
}
比如,上面我们实现了一个 Validator 验证器,并用它的 validate() 静态方法来验证输入值必须在 0 - 100 之间。注意,为了演示之目的我们在输入值超大或超小时抛出了错误。
在下面的代码中,我们期望输入值 5 是有效的:
@Test("验证 5 是否为有效输入")
func testCorrectValue() throws {#expect(try Validator.validate(input: 5), "期待 5 为有效输入")
}
照例,我们还要验证一下无效值是否能够顺利的抛出错误:
@Test("验证 -10 是非法输入")
func testTooSmall() throws {#expect(throws: ValidationError.valueTooSmall) {try Validator.validate(input: -10)}
}
如此这般,我们需要继续验证其它输入值的检测结果:比如 -10, 0, 15, 90, 100, 和 200 等等。照以往来说,此时我们要为每一个输入值写一个测试方法,或是将若干个测试放在一个测试方法中。这样做有一些讨厌的“坏味道”:
- 违反 KISS 和 DRY原则;
- 不适合测试的细粒度管控;
所以,我们该如何是好呢?
2. Swift Testing 中全新的 Parameterized 机制
所幸的是,在 Xcode 16 崭新的 Swift Testing 中我们有了一种更现代化的方法来解决它,这就是 Parameterized(参数化)机制:

从上面文档中可以看到,Swift Testing 的参数化机制其实就是 Test 宏构造器的一种重载形式。我们还可以看到,使用 Parameterized 机制的必备条件为:Swift 6+ 和 Xcode 16+。
回到 Validator 验证器的测试中,我们这回使用 Parameterized 机制来降服一下之前多个输入值的“桀骜不驯”:
@Test("验证一些有效的输入值",arguments: [0, 11, 20, 55, 90, 99, 100]
)
func testRejectsOutOfBoundsValues(input: Int) throws {#expect(try Validator.validate(input: input), "期待 \(input) 要有效哦 ;)")
}
现在,我们可以用同一个方法测试任意数量的输入值了。而且可以看到,其实参数化机制就是将多个输入值以参数数组的形式传入到测试方法里进行集中测试。
3. 对于可能抛出错误的测试也是不在话下!
在上面的代码中,我们仅仅测试了有效的输入值,那么对于无效的输入值我们还需要另外写一个参数化测试方法来“一蹴而就”吗?
答案是:没问题,但不需要!
我们完全可以将有效和无效的测试输入样本统统放到一起考量,即使它们可能抛出错误也“毫无压力”:
@Test("验证有效和无效的输入值",arguments: [(input: -10, expectedError: ValidationError.valueTooSmall),(input: 0, expectedError: nil),(input: 15, expectedError: nil),(input: 55, expectedError: nil),(input: 95, expectedError: nil),(input: 100, expectedError: nil),(input: 200, expectedError: ValidationError.valueTooBig),(input: 29352354, expectedError: ValidationError.valueTooBig),]
)
func testRejectsOutOfBoundsValues(input: Int, error: ValidationError?) throws {if let error {#expect(throws: error) {try Validator.validate(input: input)}} else {#expect(try Validator.validate(input: input), "期待 \(input) 要有效哦 ;)")}
}
从上面代码可以看到:我们将无效值和其对应期望抛出的错误打包到元组(Tuple)中,这样在测试方法中我们即可通过附加的实参取得该错误值并决定如何完成该输入值的测试。
当然,如果小伙伴们愿意的话我们仍然可以保持 testRejectsOutOfBoundsValues 测试方法只含有一个实参:
@Test("验证有效和无效的输入值",arguments: [(input: -10, expectedError: ValidationError.valueTooSmall),(input: 0, expectedError: nil),(input: 15, expectedError: nil),(input: 55, expectedError: nil),(input: 95, expectedError: nil),(input: 100, expectedError: nil),(input: 200, expectedError: ValidationError.valueTooBig),(input: 29352354, expectedError: ValidationError.valueTooBig),]
)
func testRejectsOutOfBoundsValues(condition: (value: Int, error: ValidationError?)) throws {if let error = condition.error{#expect(throws: error) {try Validator.validate(input: condition.value)}} else {#expect(try Validator.validate(input: condition.value), "期待 \(condition.value) 要有效哦 ;)")}
}
4. 细粒度管控 Parameterized 中每个参数的测试
使用 Parameterized 机制来规划 Swift Testing 不但能让海量样本的测试逻辑芟繁就简,而且更为“炸裂”的是我们现在可以:
- 一目了然的观察是哪几个输入值导致测试失败了;
- 继续单独测试任意输入值;
在下面的演示中,我们可以“鸟瞰”参数化方法中所有输入值测试的成功与否;我们可以一次性测试全部输入值,也可以单独测试某几个输入值。我们甚至可以重复测试某一参数值并设定测试结束条件:

看到这里,小伙伴们对 Swift Testing 是否更加“刮目相看”了呢?别再犹豫,马上在自己的项目中放手簪星曳月的使用它们吧!棒棒哒!💯
想要系统学习 Swift 的小伙伴们,欢迎到我的《Swift语言开发精讲》专栏来逛一逛哦:

- 《Swift 语言开发精讲》
总结
在本篇博文中,我们继续介绍了 Xcode 16 全新 Swift Testing 中的参数化(Parameterized)测试机制。有此神兵利器,相信小伙伴们在今后的单元测试中必将出奇制胜、手到擒来!
感谢观赏,再会吧!😎
相关文章:
Xcode 16 中 Swift Testing 的参数化(Parameterized)机制趣谈
概述 我们之前曾在 《用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门》系列博文以及《WWDC24(Xcode 16)中全新的 Swift Testing 使用进阶》博文中较为系统地介绍了今年 WWDC 24 中全新的 Swift Testing 测试系统。 不过 Swift Testing 的本领远…...
Python自动化运维DevSecOps与安全自动化
Python自动化运维DevSecOps与安全自动化 目录 🛡️ DevSecOps概念与实践🔍 自动化安全扫描与漏洞修复🧰 基于Python的安全审计与合规性检查🐳 云平台与容器安全:基于Python的容器扫描工具⚠️ 自定义安全检测与漏洞修…...
2024下半年系统架构师考试【回忆版】
2024年11月10日,系统架构师考试如期举行,屡战屡败的参试倒是把北京的学校转了好几所。 本次考试时间 考试科目考试时间综合知识、案例分析8:30 - 12:30论文14:30 - 16:30 综合知识 1、1-1000以内包含5的数字个数 2、 案例分析 1、RESTful 对于前后…...
UE5.4 PCG 自定义PCG蓝图节点
ExecuteWithContext: PointLoopBody: 效果:点密度值与缩放成正比...
迁移学习相关基础
迁移学习 目标 将某个领域或任务上学习到的知识或模式应用到不同但相关的领域或问题中。 主要思想 从相关领域中迁移标注数据或者知识结构、完成或改进目标领域或任务的学习效果。 概述 Target data:和你的任务有直接关系的数据,但数据量少ÿ…...
华为云计算HCIE-Cloud Computing V3.0试验考试北京考场经验分享
北京试验考场 北京考场位置 1.试验考场地址 北京市海淀区北清路156号中关村环保科技示范园区M地块Q21楼 考试场选择北京,就是上面这个地址,在预约考试的时候会显示地址,另外在临近考试的时候也会给你发邮件,邮件内会提示你考试…...
数据分析——学习框架
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
量化交易系统开发-实时行情自动化交易-3.4.2.Okex行情交易数据
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来聊聊基于Okex交易所API获取行情数…...
pytorch实现深度神经网络DNN与卷积神经网络CNN
DNN概述 深度神经网络DNN来自人脑神经元工作的原理,通过在计算机中逻辑抽象出多个节点,接收处理并向后传递信息,实现计算机的自我学习,类比结构见下图: 该方法通过预测输出与实际值的差异不断调整节点参数࿰…...
芯片测试-LDO测试
LDO测试 💢LDO的简介💢💢压降💢💢决定压降的主要因素💢 💢LDO的分类及原理💢💢PMOS LDO💢💢PMOS LDO工作过程💢💢PMOS LDO…...
期权懂|期权新手看过来:看跌期权该如何交易?
期权小懂每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 期权新手看过来:看跌期权该如何交易? 一、可以直接购买看跌期权: (1)选择预期下跌的标的资产。 (2&#…...
《深入浅出HTTPS》读书笔记(8):密码学Hash算法的分类
密码学Hash算法有很多,比如MD5算法、SHA族类算法,MD5早已被证明是不安全的Hash算法了,目前使用最广泛的Hash算法是SHA族类算法。 1)MD5 MD5是一种比较常用的Hash算法,摘要值长度固定是128比特。 MD5算法目前被证明已…...
大语言模型安全,到底是什么的安全
什么是AI安全 自ChatGPT问世以来,市场上涌现出了众多大型语言模型和多样化的AI应用。这些应用和模型在为我们的生活带来便利的同时,也不可避免地面临着安全挑战。AI安全,即人工智能安全,涉及在人工智能系统的开发、部署和使用全过…...
论文2—《基于柔顺控制的智能神经导航手术机器人系统设计》文献阅读分析报告
论文报告:基于卷积神经网络的手术机器人控制系统设计 摘要 本研究针对机器人辅助微创手术中定向障碍和缺乏导航信息的问题,设计了一种智能控制导航手术机器人系统。该系统采用可靠和安全的定位技术、7自由度机械臂以及避免关节角度限制的逆运动学控制策…...
试编写算法将单链表就地逆置(默认是带头节 点,如果是不带头节点地逆置呢?)
编写一个算法来就地逆置一个单链表。默认情况下,链表是带头节点的,但如果链表不带头节点,逆置的过程会有所不同。 第一步:定义逆置函数 根据题目中的“试编写算法将单链表就地逆置”,我们需要: 定义一个…...
FPGA学习笔记#3 Vitis HLS编程规范、数据类型、基本运算
本笔记根据笔者目前的项目确定学习目标,目前主要集中在Vitis HLS上,使用的Vitis HLS版本为2022.2,在windows11下运行,仿真part为xcku15p_CIV-ffva1156-2LV-e,从这一篇开始是HLS的学习进度,主要根据教程&…...
爬虫 - 二手交易电商平台数据采集 (一)
背景: 近期有一个需求需要采集某电商网站平台的商品数据进行分析。因此,我计划先用Python实现一个简单的版本,以快速测试技术的实现可能性,再用PHP实现一个更完整的版本。文章中涉及的技术仅为学习和测试用途,请勿用于商业或非法用…...
“成交量分布指标“,通过筹码精准锁定价格方向+简单找市场支撑压力位 MT4免费公式!
指标名称:成交量分布指标 版本:MT4 ver. 1.32 之前发布的市场分布图不少朋友反馈不错,希望获得其它版本。 这个版本只有MT4的,MT5可以看之前版本,链接: “市场分布图”,精准把握价格动向 更直…...
简记Vue3(四)—— 路由
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
Python批量合并多个PDF
在日常工作中,处理和合并多个 PDF 文件是一个常见需求,尤其是在需要将大量文件整理成一个完整文档时。本文将详细介绍如何使用 Python 的 PyMuPDF 库来实现批量 PDF 文件合并,并提供针对大文件优化的解决方案。 安装 PyMuPDF 要使用 PyMuPD…...
阿里AI产品经理实习深度解析:从业务痛点到评估体系,手把手拆解求职攻略!
本文详细拆解了阿里AI产品经理实习岗位的核心职责与面试要点,强调理解业务场景、设计AI应用流程、运用Prompt技术、评估产品效果等关键能力。文章指出,该岗位不仅需要掌握AI基础概念,更要具备业务洞察力、问题拆解能力及数据驱动优化能力&…...
GPU资源利用率深度解析与优化实践
1. GPU资源利用率的核心概念与测量方法在HPC(高性能计算)领域,GPU资源利用率是评估计算效率的黄金指标。不同于简单的"使用率"概念,真正的GPU利用率是一个多维度的综合指标,涉及计算核心、内存控制器、缓存体…...
芯片晶圆平面度如何测量?半导体制造中的光学形貌检测方案
晶圆作为集成电路的核心承载基片,表面形貌的精度直接关系到光刻聚焦质量、芯片电学性能及最终良率。从8英寸到12英寸的大尺寸晶圆制造中,平面度、翘曲度(Warp)、总厚度变化(TTV)及局部平面度(SF…...
Go语言安全编码实践:常见漏洞与防护
Go语言安全编码实践:常见漏洞与防护 1. 安全编码原则 安全编码是防止漏洞的根本,包括输入验证、输出编码、最小权限等原则。 2. 安全工具 package securityimport ("regexp""strings" )type Validator struct {emailRegex *regexp.R…...
Python 爬虫反爬突破:CDN 防护节点穿透采集
前言 当下大型互联网站点、电商平台资讯门户、行业数据网站均全面接入 CDN 内容分发网络,借助全球节点缓存、流量调度、智能分流、节点 IP 隐身、区域访问限制等机制构建底层防护体系。传统爬虫直接请求源站 IP 的方式会被 CDN 节点拦截、跳转、限速、IP 封禁、节点…...
对比直接使用官方 API,Taotoken 在批量处理任务中的用量可视化优势
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比直接使用官方 API,Taotoken 在批量处理任务中的用量可视化优势 当开发团队或个人开发者需要处理大量文本生成任务时…...
终极指南:如何使用Harepacker-resurrected打造你的MapleStory游戏Mod
终极指南:如何使用Harepacker-resurrected打造你的MapleStory游戏Mod 【免费下载链接】Harepacker-resurrected All in one .wz file/map editor for MapleStory game files 项目地址: https://gitcode.com/gh_mirrors/ha/Harepacker-resurrected 如果你是一…...
taotoken控制台提供的api调用审计与用量分析功能体验
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 taotoken控制台提供的api调用审计与用量分析功能体验 对于需要统一管理多个大模型API调用的团队而言,清晰掌握调用情况…...
Encounter/Innovus GIFT TCL 脚本流程索引清单
目录 一、 布局阶段 (Placement) 二、 布线阶段 (Routing) 三、 时序阶段 (Timing) 四、 电源阶段 (Power) 五、 IO 与端口处理 六、 调试与辅助工具 一、 布局阶段 (Placement) 脚本名称 核心用途 调用场景 userAddAllHInsts.tcl 为源模块中的每个扇出添加缓冲器 解决高扇…...
《凰标》:写给所有被资本轻视的创作者@凤凰标志
——写给所有不被看见的创作者没有流量即是无用, 没有热度即是不值, 没有商业变现能力即是小众累赘。在资本主导的文娱评价体系里,这条偏见像一道隐形天花板,横亘在每一个草根创作者的头顶。一、被算法淹没的匠心 他们怀揣赤诚热爱…...
