当前位置: 首页 > news >正文

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 等等。照以往来说,此时我们要为每一个输入值写一个测试方法,或是将若干个测试放在一个测试方法中。这样做有一些讨厌的“坏味道”:

  1. 违反 KISS 和 DRY原则;
  2. 不适合测试的细粒度管控;

所以,我们该如何是好呢?

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&#xff08;Xcode 16&#xff09;中全新的 Swift Testing 使用进阶》博文中较为系统地介绍了今年 WWDC 24 中全新的 Swift Testing 测试系统。 不过 Swift Testing 的本领远…...

Python自动化运维DevSecOps与安全自动化

Python自动化运维DevSecOps与安全自动化 目录 &#x1f6e1;️ DevSecOps概念与实践&#x1f50d; 自动化安全扫描与漏洞修复&#x1f9f0; 基于Python的安全审计与合规性检查&#x1f433; 云平台与容器安全&#xff1a;基于Python的容器扫描工具⚠️ 自定义安全检测与漏洞修…...

2024下半年系统架构师考试【回忆版】

2024年11月10日&#xff0c;系统架构师考试如期举行&#xff0c;屡战屡败的参试倒是把北京的学校转了好几所。 本次考试时间 考试科目考试时间综合知识、案例分析8:30 - 12:30论文14:30 - 16:30 综合知识 1、1-1000以内包含5的数字个数 2、 案例分析 1、RESTful 对于前后…...

UE5.4 PCG 自定义PCG蓝图节点

ExecuteWithContext&#xff1a; PointLoopBody&#xff1a; 效果&#xff1a;点密度值与缩放成正比...

迁移学习相关基础

迁移学习 目标 将某个领域或任务上学习到的知识或模式应用到不同但相关的领域或问题中。 主要思想 从相关领域中迁移标注数据或者知识结构、完成或改进目标领域或任务的学习效果。 概述 Target data&#xff1a;和你的任务有直接关系的数据&#xff0c;但数据量少&#xff…...

华为云计算HCIE-Cloud Computing V3.0试验考试北京考场经验分享

北京试验考场 北京考场位置 1.试验考场地址 北京市海淀区北清路156号中关村环保科技示范园区M地块Q21楼 考试场选择北京&#xff0c;就是上面这个地址&#xff0c;在预约考试的时候会显示地址&#xff0c;另外在临近考试的时候也会给你发邮件&#xff0c;邮件内会提示你考试…...

数据分析——学习框架

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

量化交易系统开发-实时行情自动化交易-3.4.2.Okex行情交易数据

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来聊聊基于Okex交易所API获取行情数…...

pytorch实现深度神经网络DNN与卷积神经网络CNN

DNN概述 深度神经网络DNN来自人脑神经元工作的原理&#xff0c;通过在计算机中逻辑抽象出多个节点&#xff0c;接收处理并向后传递信息&#xff0c;实现计算机的自我学习&#xff0c;类比结构见下图&#xff1a; 该方法通过预测输出与实际值的差异不断调整节点参数&#xff0…...

芯片测试-LDO测试

LDO测试 &#x1f4a2;LDO的简介&#x1f4a2;&#x1f4a2;压降&#x1f4a2;&#x1f4a2;决定压降的主要因素&#x1f4a2; &#x1f4a2;LDO的分类及原理&#x1f4a2;&#x1f4a2;PMOS LDO&#x1f4a2;&#x1f4a2;PMOS LDO工作过程&#x1f4a2;&#x1f4a2;PMOS LDO…...

期权懂|期权新手看过来:看跌期权该如何交易?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 期权新手看过来&#xff1a;看跌期权该如何交易&#xff1f; 一、可以直接购买看跌期权‌&#xff1a; &#xff08;1&#xff09;选择预期下跌的标的资产。 &#xff08;2&#…...

《深入浅出HTTPS​​​​​​​​》读书笔记(8):密码学Hash算法的分类

密码学Hash算法有很多&#xff0c;比如MD5算法、SHA族类算法&#xff0c;MD5早已被证明是不安全的Hash算法了&#xff0c;目前使用最广泛的Hash算法是SHA族类算法。 1&#xff09;MD5 MD5是一种比较常用的Hash算法&#xff0c;摘要值长度固定是128比特。 MD5算法目前被证明已…...

大语言模型安全,到底是什么的安全

什么是AI安全 自ChatGPT问世以来&#xff0c;市场上涌现出了众多大型语言模型和多样化的AI应用。这些应用和模型在为我们的生活带来便利的同时&#xff0c;也不可避免地面临着安全挑战。AI安全&#xff0c;即人工智能安全&#xff0c;涉及在人工智能系统的开发、部署和使用全过…...

论文2—《基于柔顺控制的智能神经导航手术机器人系统设计》文献阅读分析报告

论文报告&#xff1a;基于卷积神经网络的手术机器人控制系统设计 摘要 本研究针对机器人辅助微创手术中定向障碍和缺乏导航信息的问题&#xff0c;设计了一种智能控制导航手术机器人系统。该系统采用可靠和安全的定位技术、7自由度机械臂以及避免关节角度限制的逆运动学控制策…...

试编写算法将单链表就地逆置(默认是带头节 点,如果是不带头节点地逆置呢?)

编写一个算法来就地逆置一个单链表。默认情况下&#xff0c;链表是带头节点的&#xff0c;但如果链表不带头节点&#xff0c;逆置的过程会有所不同。 第一步&#xff1a;定义逆置函数 根据题目中的“试编写算法将单链表就地逆置”&#xff0c;我们需要&#xff1a; 定义一个…...

FPGA学习笔记#3 Vitis HLS编程规范、数据类型、基本运算

本笔记根据笔者目前的项目确定学习目标&#xff0c;目前主要集中在Vitis HLS上&#xff0c;使用的Vitis HLS版本为2022.2&#xff0c;在windows11下运行&#xff0c;仿真part为xcku15p_CIV-ffva1156-2LV-e&#xff0c;从这一篇开始是HLS的学习进度&#xff0c;主要根据教程&…...

爬虫 - 二手交易电商平台数据采集 (一)

背景: 近期有一个需求需要采集某电商网站平台的商品数据进行分析。因此&#xff0c;我计划先用Python实现一个简单的版本&#xff0c;以快速测试技术的实现可能性&#xff0c;再用PHP实现一个更完整的版本。文章中涉及的技术仅为学习和测试用途&#xff0c;请勿用于商业或非法用…...

“成交量分布指标“,通过筹码精准锁定价格方向+简单找市场支撑压力位 MT4免费公式!

指标名称&#xff1a;成交量分布指标 版本&#xff1a;MT4 ver. 1.32 之前发布的市场分布图不少朋友反馈不错&#xff0c;希望获得其它版本。 这个版本只有MT4的&#xff0c;MT5可以看之前版本&#xff0c;链接&#xff1a; “市场分布图”&#xff0c;精准把握价格动向 更直…...

简记Vue3(四)—— 路由

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

Python批量合并多个PDF

在日常工作中&#xff0c;处理和合并多个 PDF 文件是一个常见需求&#xff0c;尤其是在需要将大量文件整理成一个完整文档时。本文将详细介绍如何使用 Python 的 PyMuPDF 库来实现批量 PDF 文件合并&#xff0c;并提供针对大文件优化的解决方案。 安装 PyMuPDF 要使用 PyMuPD…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...