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

news2024/11/9 3:53:49

在这里插入图片描述

概述

从 WWDC 24 开始,苹果推出了全新的测试机制:Swift Testing。利用它我们可以大幅度简化之前“老态龙钟”的 XCTest 编码范式,并且使得单元测试更加灵动自由,更符合 Swift 语言的优雅品味。

在这里插入图片描述

在这里我们会和大家一起初涉并领略 Swift Testing 的测试之美。

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

  • 概述
  • 4. #expect 宏
  • 5. #require 宏
  • 6. Swift Testing 目前的不足
  • 总结

测试为先,质量为王!无测试,不软件!

那还等什么呢?Let’s testing!!!😉


4. #expect 宏

如果说前面介绍的 @Test 宏为测试奠定了基调,那么 #expect 宏则无疑是当之无愧的测试核心所在。

在这里插入图片描述

在以往“陈言老套”的 XCTest 体系中,我们往往需要用超多 XCTAssertXXX 之类的方法来验证测试通过与否:

在这里插入图片描述

记住这些“聚蚊成雷”般的方法可不是件容易的活。不过这一切在 Swift Testing 都不是事儿了,因为不管现实如何千变万化我们都只需一个 #expect 宏即可统统搞定!

import Testing

func add(_ a: Int, _ b: Int) -> Int {
    a + b
}

@Test func verifyAdd() {
    let result = add(1, 2)
    #expect(result == 3)
}

上面是 #expect 宏最简单的形式,即验证结果是否为真。如此这般,多个 #expect 连续助攻自然也是不在话下:

@Test func verifyMagicNumber() {
    let number = magicNumber()
    
    #expect(number != 0)
    #expect(number > 10)
    #expect(number <= 100)
}

我们还可以利用 #expect 来验证被测试方法是否抛出错误、以及是否抛出指定错误:

enum MyError: Error {
    case invalidInput
}

func throwingFunction() throws {
    throw MyError.invalidInput
}

@Test func verifyThrowingFunction() {
    #expect(throws: MyError.self) {
        try throwingFunction()
    }
}

在上面的代码中,如果 throwingFunction 抛出 MyError 错误则表示测试通过!

我们还可以更进一步,细粒度控制方法抛出错误时的测试行为,比如仅当抛出指定 MyError.invalidInput 错误时才能使测试 Pass:

@Test func verifyThrowingFunction() {
    #expect {
        try throwingFunction()
    } throws: { error in
        guard let myError = error as? MyError else {
            return false
        }
        return myError == .invalidInput
    }
}

Swift Testing 中 #expect 的能耐远不止于此,更多它的使用介绍请小伙伴们参考苹果官方开发文档。

5. #require 宏

除了 #expect 之外,在 Swift Testing 中还有另一个不可或缺的“超级助手”,那就是 #require 宏:

在这里插入图片描述

简单来说,#require 宏的精妙之处在于它可以让我们立即判断条件是否满足,并提早结束测试。具体来说,它会在测试可选值(Optional Value)为 nil (或者其它条件不满足)时让测试失败并抛出错误。

@Test func verifyOptionalFunc() throws {
    let result = optionalFunc()
    try #require(result != nil)
    
    #expect(result! > 0)
}

还拿之前博文中 Item 的“栗子”来说,我们可以写一个验证 Model 中第一个 Item 名称的方法,不过由于我们忘记了创建 Model 中的 items,所以下面的测试会在 #require 那行抛出错误,因为此时 items 数组为空:

@Test
func firstItemCheck() throws {
    let model = Model.shared
    let firstItem = try #require(model.items.first)
    #expect(firstItem.name == "大熊猫侯佩")
}

失败的测试结果如下图所示:
在这里插入图片描述

更进一步,我们还可以利用 Issue 对象来记录测试遇到的任何问题,它们都会在测试日志中分毫不差的反映出来:

@Test
func firstItemCheck() {
    let model = Model.shared
    
    do {
        let firstItem = try #require(model.items.first)
        #expect(firstItem.name == "大熊猫侯佩")
    } catch {
        Issue.record("Model 中没有任何数据,忘记创建了???")
    }
}

测试 firstItemCheck() 方法依旧失败,不过此时我们可以在 Xcode 控制台中看到具体失败的信息:

在这里插入图片描述

现在,借助于 Swift Testing 中这些宏的“古道热肠”,我们编写的单元测试必将大放异彩、拔山盖世!棒棒哒!💯

6. Swift Testing 目前的不足

虽然 Swift Testing 较之以前的 XCTest 测试系统有诸多好处,但我们仍不能完全否定后者。而且, Swift Testing 还缺失测试中至关重要的一环:UI 测试。

对于 WWDC 23 中推出 Swift 宏(Macros)的单元测试,目前我们也无法使用 Swift Testing 来完成,这不能不说是一个遗憾。

这些问题在 Swift Testing 2.0 中是否能够解决?Swift Testing 能否在 WWDC 25 里从 XCTest 中完全凤凰涅槃呢?让我们拭目以待吧!


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

在这里插入图片描述

  • 《Swift 语言开发精讲》

总结

在本篇博文中,我们继续讨论了 Swift Testing 中另外两个非常重要的宏:#expect 和 #require,我们还顺带介绍了目前 Swift Testing 的一个“短板”。至此 Swift Testing 测试大冒险圆满落幕啦!

感谢观赏,再会啦!😎

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

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

相关文章

【案例】Excel使用宏来批量插入图片

一、场景介绍 我有一个excel文件&#xff0c;需要通过一列的文件名称&#xff0c;按照规则给批量上传图片附件。 原始文件&#xff1a; 成功后文件&#xff1a; 二、实现方法 1. 使用【wps】工具打开Excel文件&#xff0c;将其保存为启用宏的文件。 2.找到编辑宏的【VB编辑器…

Springboot项目报错记录

SpringBoot测试报错&#xff1a;Unable to find a SpringBootConfiguration, you need to use Context 该测试类所在测试包test下的包名和类路径java下的包名不一致导致的 引发以下报错 java.lang.IllegalStateException: Unable to find a SpringBootConfiguration, you need…

RabbitMQ 高级特性——消息分发

文章目录 前言消息分发RabbitMQ 分发机制的应用场景1. 限流2. 负载均衡 前言 当 RabbitMQ 的队列绑定了多个消费者的时候&#xff0c;队列会把消息分发给不同的消费者&#xff0c;每条消息只会发送给订阅列表的一个消费者&#xff0c;但是呢&#xff0c;RabbitMQ 默认是以轮询…

深度学习:bert模型

multi-headed机制 1、通过不同的head得到多个特征表达&#xff0c;一般8个head 2、将所有特征拼接在一起 3、降维&#xff0c;将Z0~Z7连接一个FC全连接实现降维 多层堆叠 位置编码 如何实现位置编码&#xff1f; &#xff08;1&#xff09;为每个时间步添加一个0-1范围内的数…

Vue实战学习(2)(Vue快速入门(快速构建一个局部Vue项目))

目录 一、Vue快速入门。 &#xff08;1&#xff09;快速入门的案例需求。 &#xff08;2&#xff09;原生js解决。 &#xff08;3&#xff09;使用Vue解决。 1、准备一个html页面。且该页面需要引入Vue模块。 2、创建Vue程序的应用实例。 3、准备html元素&#xff08;如div&…

SpringMVC学习记录(三)之响应数据

SpringMVC学习记录&#xff08;三&#xff09;之响应数据 一、页面跳转控制1、快速返回模板视图2、转发和重定向 二、返回JSON数据1、前置准备2、ResponseBody 三、返回静态资源1、静态资源概念2、访问静态资源 /*** TODO: 一个controller的方法是控制层的一个处理器,我们称为h…

Spring WebFlux 核心原理(2-3)

1、Project Reactor 高级 1.1、响应式流的生命周期 要理解多线程的工作原理以及 Reactor 中实现的各种内部优化&#xff0c;首先必须了解 Reactor 中响应式类型的生命周期。 1.1.1、组装时 流生命周期的第一部分是组装时&#xff08;assembly-time&#xff09;。 Reactor 提供…

Python爬虫与Web渗透测试入门指南——初学者防踩雷

目录 Python爬虫与Web渗透测试入门指南一、学习方向和基础知识Python爬虫学习方向Web渗透学习方向 二、具体知识点总结三、学习流程和典型案例案例1&#xff1a;Python爬虫 - 简单网页数据爬取案例2&#xff1a;Web渗透 - SQL注入漏洞检测与利用案例3&#xff1a;Python爬虫 - …

apache-seata-2.1.0 AT模式使用篇(配置简单)

最近在研究seata的AT模式&#xff0c;先在本地搭建了一个演示demo&#xff0c;看看seata是如何使用的。在网上搜的demo&#xff0c;配置相对来说都比较多。我最终搭建的版本&#xff0c;配置较少&#xff0c;所以写篇文章分享下&#xff0c;希望能帮到对seata感兴趣的小伙伴。先…

Java代码与数据库纽带——JDBC

ok&#xff0c;看了题目&#xff0c;就可以知道今天要分享的是JDBC 讲这个这之前&#xff0c;想讲讲之前的。 之前我们操作数据库基本都是通过MySQL客户端&#xff0c;进行编写sql语句来操作的。 但是我们在开发中一般都是通过代码来操控数据库的。 而且在我们日常开发中&a…

navicat pg库安装mysql fdw 外表扩展

在Windows上手动安装mysql_fdw&#xff08;MySQL Foreign Data Wrapper&#xff09;通常涉及一系列步骤&#xff0c;包括下载源码、编译、配置和测试。以下是一个详细的指南&#xff1a; 一、下载mysql_fdw源码 访问mysql_fdw的GitHub发布页面&#xff0c;选择最新版本的源码…

智能提醒助理系列-jdk8升级到21,springboot2.3升级到3.3

本系列文章记录“智能提醒助理”产品建设历程&#xff0c;记录实践经验、巩固知识点、锻炼总结能力。 本篇介绍技术栈升级的过程&#xff0c;遇到的问题和解决方案。 一、需求出发点 智能提醒小程序 当前使用的是jdk8&#xff0c;springboot2.3,升级到jdk21和springboot3.3 学…

雷军-2022.8小米创业思考-11-新零售:用电商思维做新零售,极致的效率+极致的体验。也有弯路,重回极致效率的轨道上。

第十一章 新零售 当我们说到小米模式的时候&#xff0c;其实我们说的是两件东西&#xff1a; 一是小米模式的本质&#xff0c;即高效率的商业模式&#xff1b; 另一件是小米这家公司具象的商业模式&#xff0c;这是小米在实践中摸索、建立的一整套业务模型。 从2015年到202…

人工智能——小白学习指南

知孤云出岫 目录 1. **智能评测系统**2. **个性化学习路径推荐**3. **虚拟学习助手**4. **学习行为分析**5. **数据驱动的教学决策**6. **自动化课程推荐**7. **数据隐私与安全保护** 人工智能知识点的总结和学习路线&#xff0c;以数据表格形式呈现&#xff0c;并附带在教育行…

【深度学习基础】常用图像卷积核类型

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 常…

SpringCloud框架学习(第一部分:初始项目搭建)

目录 一、SpringBoot和SpringCloud版本选型 1.Springcloud版本选择 2.Springcloud版本选择 3.Springcloud Alibaba版本选择 4.SpringCloud VS SpringBoot VS SpringCloud Alibaba版本三者制约对应关系 二、SpringCloud介绍 1.单体架构 2.微服务架构 3.springcloud 4.S…

【动手学运动规划】 4.1 图搜的基础

&#x1f3f0;代码及环境配置&#xff1a;请参考 环境配置和代码运行! 4.1.1 基础概念 4.1.1.1 Configuration Space(配置空间) configuration: 机器人上每一点位置的完整说明degrees of freedom: 机器人能够独立移动或旋转的关节数量&#xff08;下图所示有4个自由度&#x…

如何用彩屏显示精美的动画

1什么样的动画是精美的&#xff1f; 1&#xff09;视觉暂留 视频播放的原理基于人眼的视觉暂留现象。‌视频是由一系列静态图像&#xff08;帧&#xff09;组成的&#xff0c;这些图像以特定的频率&#xff08;帧率&#xff09;连续播放&#xff0c;使得人眼无法区分单帧图像&…

信息安全工程师(81)网络安全测评质量管理与标准

一、网络安全测评质量管理 遵循标准和流程 网络安全测评应严格遵循国家相关标准和流程&#xff0c;确保测评工作的规范性和一致性。这些标准和流程通常包括测评方法、测评步骤、测评指标等&#xff0c;为测评工作提供明确的指导和依据。 选择合格的测评团队 测评团队应具备相关…

【CTFN】基于耦合翻译融合网络的多模态情感分析的层次学习

同样用了翻译模块的论文->MTMSA 代码地址->github地址 abstract 多模态情感分析是一个具有挑战性的研究领域&#xff0c;涉及多个异构模态的融合。主要的挑战是在多模式融合过程中出现一些缺失的模式。然而&#xff0c;现有的技术需要所有的模态作为输入&#xff0c;因…