[Swift]单元测试

编写单元测试是确保你的代码质量和功能正确性的重要步骤

一、编写单元测试的详细流程

1. 创建一个新的Xcode项目

如果你尚未创建一个项目,首先你需要在Xcode中创建一个新的iOS项目:

  • 打开Xcode,选择“File” > “New” > “Project”。

  • 选择一个适合的项目模板,例如“App”,然后点击“Next”。

  • 填写项目的详细信息(如项目名称、团队、组织名称和语言选择Swift),确保勾选“Include Tests”选项,然后点击创建。

2. 理解测试目标和框架

创建项目时,如果你选择了“Include Tests”,Xcode会自动为你的项目生成一个测试目标(Target)。这个测试目标使用XCTest框架,这是Apple提供的用于编写单元测试的框架。

3. 编写测试用例

单元测试通常是围绕你的应用程序的单一功能或类来编写的。

下面是编写单元测试的基本步骤:

(1).找到测试文件

在Xcode的项目导航器中,找到以“Tests”结尾的目标文件夹。默认的测试文件可能类似于YourProjectNameTests.swift。

(2).导入测试模块

在测试文件的顶部,确保导入了XCTest框架和你的主项目模块。例如:

import XCTest
@testable import YourProjectName

(3).创建测试类

Xcode默认创建的测试类继承自XCTestCase。你可以在这个类中添加测试方法。

(4).编写测试方法

每个测试方法都必须以test开头。方法内部使用断言来验证代码的功能。例如,测试一个简单的加法函数:

func testAddition() {let result = Calculator.add(1, 2)XCTAssertEqual(result, 3, "The addition function failed.")
}

这里,XCTAssertEqual是一个断言,用于检查Calculator.add(1, 2)的结果是否等于3。

(5).默认生成的代码

一般上面几步不用手动敲代码,YourProjectNameTests.swift文件中会包含如下代码,XCTestCase类提供了多个方法来帮助设置、执行和拆分测试。

import XCTest
@testable import GameDeDemofinal class GameDeDemoTests: XCTestCase {/**将设置代码放在这里。此方法在类中的每个测试方法调用之前被调用。用途:这个方法在每个测试方法之前被调用。它用于设置测试环境,确保每个测试都在干净且已知的状态下开始。例子:在这个方法中,你可以初始化一些对象,设置或重置模拟数据,或配置环境(如数据库连接、网络环境等)。*/override func setUpWithError() throws {}/**把拆卸代码放在这里。在调用类中的每个测试方法之后调用此方法。用途:这个方法在每个测试方法之后被调用。它用于清理或拆分测试后的环境,确保一个测试的执行不会影响到其他测试。例子:释放在setUpWithError()中创建的对象,关闭数据库连接,清理模拟数据等。*/override func tearDownWithError() throws {}/**这是一个功能测试用例。使用XCTAssert和相关函数来验证测试是否产生正确的结果。为XCTest编写的任何测试都可以被注释为抛出和async。当测试遇到未捕获的错误时,标记测试抛出以产生意外失败。将测试标记为async,允许等待异步代码完成。之后用断言检查结果。*/func testExample() throws {}/**用途:这个方法用于性能测试,主要用来测量一段代码的执行时间。通过measure方法,Xcode会多次执行代码块,并记录执行时间,从而帮助开发者了解代码的性能。例子:测量一个复杂算法的执行时间,或者评估一个数据处理函数的性能。*/func testPerformanceExample() throws {// 这是一个性能测试用例的示例。self.measure {// 把要测量时间的代码写在这里。}}}

4. 运行测试

(1).使用快捷键

可以直接在Xcode中使用快捷键Command + U来运行所有测试。

(2).切换运行按钮

长按运行按钮,切换到Build for Testing,后面点击运行就是运行所有测试。

(3).使用测试导航器

在Xcode的侧边栏中,切换到测试导航器(测试图标),然后可以单独运行某个测试类或测试方法。

(4).单元测试文件运行

文件中,选择方法前面的“开始”,就是重新运行某个方法。选择文件名前面的“开始”,就是重新运行某个类。

5. 查看测试结果

测试完成后,Xcode会在编辑器左侧的测试导航器中显示测试结果。成功的测试会标记为绿色勾选,失败的测试会标记为红色叉号。如果测试失败,可以查看失败原因,并根据失败信息调整代码或测试逻辑。

除此之外,调试面板还会打印详细日志。 会展示每个方法执行时间,整个文件所执行的时间,以及报错信息。

Test Suite 'GameDeDemoTests' started at 2024-04-24 23:08:55.753.Test Case '-[GameDeDemoTests.GameDeDemoTests testExample1]' started.
/Users/gamin/Desktop/GameDeDemo/GameDeDemoTests/GameDeDemoTests.swift:53: error: -[GameDeDemoTests.GameDeDemoTests testExample1] : XCTAssertTrue failed - Result should be true
Test Case '-[GameDeDemoTests.GameDeDemoTests testExample1]' failed (0.023 seconds).Test Case '-[GameDeDemoTests.GameDeDemoTests testExample]' started.
Test Case '-[GameDeDemoTests.GameDeDemoTests testExample]' passed (0.002 seconds).Test Case '-[GameDeDemoTests.GameDeDemoTests testOneExample]' started.
Test Case '-[GameDeDemoTests.GameDeDemoTests testOneExample]' passed (1.351 seconds).Test Case '-[GameDeDemoTests.GameDeDemoTests testPerformanceExample]' started.
/Users/gamin/Desktop/GameDeDemo/GameDeDemoTests/GameDeDemoTests.swift:62: Test Case '-[GameDeDemoTests.GameDeDemoTests testPerformanceExample]' measured [Time, seconds] average: 0.000, relative standard deviation: 179.574%, values: [0.000083, 0.000009, 0.000006, 0.000005, 0.000005, 0.000005, 0.000004, 0.000004, 0.000005, 0.000004], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , polarity: prefers smaller, maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[GameDeDemoTests.GameDeDemoTests testPerformanceExample]' passed (0.258 seconds).Test Suite 'GameDeDemoTests' failed at 2024-04-24 23:08:57.389.Executed 4 tests, with 1 failure (0 unexpected) in 1.634 (1.636) seconds

6. 重构和维护测试

随着项目的发展,持续维护和更新单元测试是非常重要的。确保在添加新功能或修改现有代码后更新相应的测试,以保持测试覆盖率和代码质量。

二、如何组织单元测试代码?

在进行单元测试时,组织和结构化测试代码是非常重要的。虽然技术上可以将所有测试写入一个单一的测试类中,但这通常不是最佳实践。

以下是一些关于如何组织单元测试代码的建议和优点:

1.分开测试文件的理由

(1).可维护性

将测试分散到不同的文件中可以提高代码的可维护性。当测试文件专注于特定的功能模块时,相关的测试更容易查找和更新。

(2).可读性

小型、专注的测试文件比一个庞大的测试文件更易于阅读和理解。每个测试类可以对应于应用程序中的一个模块或类,这样代码结构会更清晰。

(3).避免冲突

在团队环境中,多个开发者可能同时工作在不同的模块上。分开测试文件可以减少版本控制中的合并冲突。

(4).并行测试

当测试被组织到多个文件中时,运行测试的工具(如Xcode)可能能更有效地并行执行这些测试,从而减少总的测试时间。

2.如何组织测试?

(1).按类或模块组织

对于每个主要的类或功能模块,都应该有一个对应的测试类。例如,如果你有一个Game类和一个Player类,你可以创建GameTests.swiftPlayerTests.swift

(2).遵守命名约定

保持一致的命名约定有助于团队成员快速理解测试结构。通常,测试文件的命名应与被测试的类相对应,并加上Tests后缀。

(3).利用XCTest的设置和拆解方法

使用setUp()tearDown()方法来为每个测试案例配置必要的环境,这可以在每个测试类中独立进行。

三、XCTest中各种断言如何使用?

在XCTest框架中,断言是用来验证单元测试中条件是否符合预期的关键工具。每个断言都会对表达式或条件进行评估,如果条件不满足则会引发一个失败,这有助于开发者识别和修复错误。

这些断言是XCTest框架的核心部分,通过使用它们,你可以确保你的代码按照预期工作,及时发现和修正潜在的问题。

1.XCTAssert

用途:验证一个条件是否为真。

示例

func testExample() {let result = trueXCTAssert(result, "Result should be true")
}

2.XCTAssertTrue 和 XCTAssertFalse

用途:XCTAssertTrue 用来验证条件是否为真;XCTAssertFalse 用来验证条件是否为假。

示例

func testBooleanLogic() {let success = truelet failure = falseXCTAssertTrue(success, "Success should be true")XCTAssertFalse(failure, "Failure should be false")
}

3.XCTAssertEqual 和 XCTAssertNotEqual

用途:XCTAssertEqual 用来验证两个表达式的值是否相等;XCTAssertNotEqual 用来验证两个表达式的值是否不相等。

示例

func testEquality() {XCTAssertEqual(1 + 1, 2, "One plus one should equal two")XCTAssertNotEqual(1 + 1, 3, "One plus one should not equal three")
}

4.XCTAssertNil 和 XCTAssertNotNil

用途:XCTAssertNil 用来验证一个表达式的结果是否为nil;XCTAssertNotNil 用来验证一个表达式的结果是否不为nil。

示例

func testOptional() {var optionalValue: Int? = nilXCTAssertNil(optionalValue, "Value should be nil")optionalValue = 10XCTAssertNotNil(optionalValue, "Value should not be nil")
}

5.XCTAssertThrowsError 和 XCTAssertNoThrow

用途:XCTAssertThrowsError 用来验证一个表达式是否抛出错误;XCTAssertNoThrow 用来验证一个表达式是否没有抛出错误。

示例

func testThrowingFunction() {XCTAssertThrowsError(try throwingFunction(), "Function should throw an error")XCTAssertNoThrow(try nonThrowingFunction(), "Function should not throw an error")
}func throwingFunction() throws {throw NSError(domain: "", code: 0, userInfo: nil)
}func nonThrowingFunction() throws {// No error is thrown here
}

6.XCTAssertGreaterThan, XCTAssertGreaterThanOrEqual, XCTAssertLessThan, XCTAssertLessThanOrEqual

用途:这些断言用于比较数值,检查一个值是否大于、大于或等于、小于、小于或等于另一个值。

示例

func testComparisons() {XCTAssertGreaterThan(10, 9, "10 should be greater than 9")XCTAssertGreaterThanOrEqual(10, 10, "10 should be greater than or equal to 10")XCTAssertLessThan(9, 10, "9 should be less than 10")XCTAssertLessThanOrEqual(9, 9, "9 should be less than or equal to 9")
}

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

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

相关文章

重生之我是Nginx服务专家

nginx服务访问页面白色 问题描述 访问一个域名服务返回页面空白,非响应404。报错如下图。 排查问题 域名解析正常,网络通讯正常,绕过解析地址访问源站IP地址端口访问正常,nginx无异常报错。 在打开文件时,发现无法…

R可视化:ggplot2绘制双y轴图

介绍 ggplot2绘制双y轴图加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE) library(tidyverse) library(readxl)# rm(list = ls()) options(stringsAsFactors = F) options(future.globals.maxSize = 10000 * 1024^2)Importing data 下载Underdetection of c…

IDEA实现Springboot项目自动热部署

每当我们在修改代码时,往往需要重新启动项目,这样不仅浪费时间而且很麻烦,我们可以通过IDEA的热部署来提高效率 1、首先点file >> settings >> Build Excution >> Compire,选择Build project auto matically 2.…

CMakeLists.txt中如何添加编译选项?

1. 引子 编译器有多种可供选择,如g、c、clang等,如下以c作为示例。 2. 使用CMAKE_CXX_FLAGS添加编译选项 在Makefile中可能用类似如下的指令来添加编译选项: /usr/bin/c -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unuse…

flutter笔记-主要控件及布局

文章目录 1. 富文本实例2. Image2.1 本地图片2.2 网络图片 笔记3. 布局4. 滑动相关view4.1 GridView类似九宫格view4.2 ListView 关于widget的生命周期的相关知识这里就不做介绍,和很多语言类似; 1. 富文本实例 Dart中使用richtext,示例如下…

Vue3+Vite开发的项目进行加密打包

本文主要介绍Vue3+Vite开发的项目如何进行加密打包。 目录 一、vite简介二、混淆工具三、使用方法1. 安装插件:2. 配置插件:3. 运行构建:4. 自定义混淆选项:5. 排除文件:下面是Vue 3+Vite开发的项目进行加密打包的方法。 一、vite简介 Vite 是一个由 Evan You 创造的现代…

XBoot:基于Spring Boot 2.x的一站式前后端分离快速开发平台

XBoot:基于Spring Boot 2.x的一站式前后端分离快速开发平台 摘要 随着信息技术的迅速发展,快速构建高质量、高可靠性的企业级应用成为了迫切需求。XBoot,作为一个基于Spring Boot 2.x的一站式前后端分离快速开发平台,通过整合微信…

针对icon报错

针对上篇文章生成图标链接中图标报错 C# winfrom应用程序添加图标-CSDN博客 问题:参数“picture”必须是可用作Icon的参数 原因:生成的ico图标类型不匹配 解决方法: 更改导出的ico类型

iOS - 多线程-读写安全

文章目录 iOS - 多线程-读写安全1. 多读单写1.1 场景1.2 实现方案1.2.1 pthread_rwlock:读写锁1.2.1.1 示例 1.2.2 dispatch_barrier_async:异步栅栏调用1.2.2.1 示例 iOS - 多线程-读写安全 假设有一个文件,A线程进行读取操作,B…

数智时代的AI人才粮仓模型解读白皮书(2024版)

来源:极客邦科技 自 2023 年上半年起,ChatGPT 等大模型技术蓬勃发展,AI 技术不断突破边界,展现 出惊人的潜力和发展速度。从早期的逻辑推理、专家系统,到如今的深度学习、神经网络, AI 技术显著缩小了科学…

ASP.NET企业投资价值分析系统

摘 要 本文将影响股票投资价值的宏观因素、行业因素、企业内部等诸多因素予以量化分析,对钢铁板块和汽车板块各上市公司进行综合评估,为广大股民的投资方向和资金安全提供了有力的支持。本文还阐述了企业投资价值分析的必要性,说明了企业投…

分类算法——模型评估(八)

1混淆矩阵 在分类任务下,预测结果与正确标记之间存在四种不同的组合,构成混淆矩阵(适用于多分类) TP True Possitive FN False Negative 2精确率(Precision)与召回率(Recall) 精…

mysql-sql-练习题-2

日期topN 日期最值 topN 任意区间topN 每年温度top2建表排名函数万能公式(条关) 任意区间 各科第1,3,5名排名函数万能公式 日期 本周过生日 -- 本周表示 加减日期 格式化 拼接 select * from student where date_format(s_age,concat(year(curdate()),…

微信小程序开发六(自定义组件)

自定义组件的创建: 如何创建: 右键选择新建component 创建完成之后需要打开app.json,这是全局使用这个组件,想要单独的页面使用,就在当前页面的json文件中定义 "usingComponents": {"my-zj": &quo…

冰箱主控 32位MCU,多通道、高精度的AD采样配合温度传感器,实现冰箱各温室的精确控温;低功耗设计

概览 小华高性价比32位MCU,多通道、高精度的AD采样配合温度传感器,实现冰箱各温室的精确控温;低功耗设计,绿色低碳、节能环保;模块化设计,充分利用丰富的通讯接口,使主控板、显示板和驱动板灵活…

远程连接docker,实现本地发布版本到服务器

最近在学jenkins的时候,发现涉及到了docker的远程发布调用。后续应该还要自己搭建一个docker的本地仓库。 简单描述一下具体是如何实现的: 1、将docker的服务器开启2375端口(注意,这里的开启是将端口直接暴露出去,不用…

38-1 防火墙了解

一、防火墙的概念: 防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网(US5606668 [A]1993-12-15)。它是一种位于内部网络与外部网络之间的网络安全系统,是一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。…

移远通信推出“全系统+全频段”GNSS定位模组LG290P,赋能高精度导航应用

近日,全球领先的物联网整体解决方案供应商移远通信正式对外宣布,其将推出全新款支持“全系统全频段”的工规级RTK高精度GNSS定位模组LG290P,用于满足智能机器人、无人机、精准农业、测量测绘等高精度定位应用场景所需。 高精度 LG290P 作为移…

Ubuntu+Systemd服务+实现开机自启/关机启动脚本

开机自启 1.创建一个新的 systemd 服务文件 现在随便一个地方创建txt文档 如果想要启动sh脚本,就把下面的代码输入到txt文档中 [Unit] DescriptionRun Python script on specific executable run Afternetwork.target[Service] Typesimple ExecStart/home/tech/…

记录些AI Agents设计模式和NL2SQL知识

吴恩达分享的四种 自我反思(Reflection):可以自我修正;使用工具(Tool Use):链接其他系统去做一些事情,比如把电脑里面的未归档文件做好归档;规划(Planning&a…