当前位置: 首页 > 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…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...