[Swift]单元测试

news2024/12/23 23:49:23

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

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

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 GameDeDemo

final 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 = true
    XCTAssert(result, "Result should be true")
}

2.XCTAssertTrue 和 XCTAssertFalse

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

示例

func testBooleanLogic() {
    let success = true
    let failure = false
    XCTAssertTrue(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? = nil
    XCTAssertNil(optionalValue, "Value should be nil")

    optionalValue = 10
    XCTAssertNotNil(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.coloradmin.cn/o/1622266.html

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

相关文章

ARM DMIPS算力说明

ARM DMIPS算力说明 ARM算力参考官网地址 https://en.wikipedia.org/wiki/List_of_ARM_processors Product familyARM architectureProcessorFeatureCache (I / D), MMUTypical MIPS MHzReferenceARM1ARMv1ARM1First implementationNoneARM2ARMv2ARM2ARMv2 added the MUL (mu…

一文带你了解MySQL的DCL语句

文章目录 ☃️DCL☃️管理用户☃️权限控制☃️DCL的重要性 欢迎来到 请回答1024 的博客 🍎🍎🍎欢迎来到 请回答1024的博客 关于博主: 我是 请回答1024,一个追求数学与计算的边界、时间与空间的平衡,0与1的…

【MySQL】A01、性能优化-结构设计与配置

1、数据库设计原则 1.1、核心原则 不在数据库做运算; cpu计算务必移至业务层; 控制列数量(字段少而精,字段数建议在20以内); 平衡范式与冗余(效率优先;往往牺牲范式) 拒绝3B(拒绝大sql语句:big sql、拒绝大事务:big transaction、拒绝大…

【漏洞复现】Palo Alto Networks PAN-OS GlobalProtect 命令注入漏洞 CVE-2024-3400

漏洞描述 Palo Alto Networks PAN-OS GlobalProtect 命令 Palo Alto Networks PAN-OS GlobalProtect 是Palo Alto Networks 的一款防火墙产品。2024年4月12日,官方披露CVE-2024-3400 Palo Alto Networks GlobalProtect 命令注入漏洞。在特定PAN-OS版本和不同功能配置下,未经…

618哪些好物值得入手?收下这份必买清单!

很快618就要来啦,在这之前一定要好好做攻略。在这个特别的时刻,我们不仅有机会淘到心仪已久的商品,还能享受到超值的折扣和优惠。为了让大家的购物体验更加愉快,我特意整理了一份618必买清单,里面汇聚了各类热门好物&a…

【算法入门-Python】02_递归

一、递归 递归的两个特点:调用自身;结束条件。 def func1(x):print(x)func1(x-1)没有结束条件,si递归。不是递归。 def func2(x):if x > 0:print(x)func2(x1)递归调用的x1,没有结束条件。不是递归 def func3(x)…

2024最新版本FL Studio21水果编曲软件破解版激活许可证

FL Studio 21水果编曲软件适合广泛的人群使用,包括但不限于以下几类人: 音乐制作人:对于专业的音乐制作人来说,FL Studio 21提供了全面的音乐制作工具和功能,能够满足他们在音乐创作、编曲、混音等方面的需求。他们可以…

VUE父组件向子组件传递值

创作灵感 最近在写一个项目时,遇到了这样的一个需求。我封装了一个组件,这个组件需要被以下两个地方使用,一个是搜索用户时用到,一个是修改用户信息时需要用到。其中,在搜索用户时,可以根据姓名或者账号进…

Git TortoiseGit 详细安装使用教程

前言 Git 是一个免费的开源分布式版本控制系统,是用来保存工程源代码历史状态的命令行工具,旨在处理从小型到非常大型的项目,速度快、效率高。《请查阅Git详细说明》。TortoiseGit 是 Git 的 Windows Shell 界面工具,基于 Tortoi…

Mybatis入门(入门案例,IDEA配置SQL提示,JDBC介绍,lombok介绍)

目录 一、Mybatis入门案例介绍整体步骤创建SpringBoot项目pom依赖准备测试数据新建实体类配置Mybatis数据库连接信息新建接口类,编写SQL代码单元测试 二、IDEA配置SQL提示三、JDBC是什么案例JDBC和Mybatis对比 四、数据库连接池介绍如何实现一个数据库连接池切换数据库连接池 五…

【SpringCloud】LoadBalance负载均衡服务调用快速入门

【SpringCloud】LoadBalance负载均衡服务调用快速入门 文章目录 【SpringCloud】LoadBalance负载均衡服务调用快速入门1. 概述2. 引入依赖3. 配置、验证3.1 配置3.2 验证 1. 概述 官网地址:点击跳转 Spring Cloud LoadBalancer 是由 SpringCloud 官方提供的一个开…

自动化测试用例设计

知人者智,自知者明。大家好,给大家分享一下关于自动化测试用例的设计心得,首先完整的熟悉业务是第一步要做的,不熟悉业务的前提下不会设计出高效且合理的用例,其次是我们要有明确的测试目标,确保我们写的每…

CentOS 7.9.2009 中 Docker 使用 GPU

一、安装nvidia驱动 1.1,查看显卡驱动 # 查看显卡型号 lspci | grep -i nvidia 1.2,进入 PCI devices ,输入上一步查询到的 2204 1.3,进入 官方驱动 | NVIDIA,查询 Geforce RTX 3090 驱动并下载 1.4,禁用…

Redis入门到通关之数据结构解析-QuickList

文章目录 ☃️前提概要☃️ 配置项相关☃️简要源码☃️总结 欢迎来到 请回答1024 的博客 🍓🍓🍓欢迎来到 请回答1024的博客 关于博主: 我是 请回答1024,一个追求数学与计算的边界、时间与空间的平衡,0与1…

第十五届蓝桥杯省赛第二场C/C++B组A题【进制】题解(AC)

解题思路 按照题意进行模拟&#xff0c;计算 x x x 的 b b b 进制过程中&#xff0c;若出现余数大于 9 9 9&#xff0c;则说明 x x x 的 b b b 进制一定要用字母进行表示。 #include <iostream> #include <cstring> #include <algorithm> #include &l…

探索UWB模块的潜力:智能家居与物联网的连接者

UWB模块具有精准定位、快速响应、低能耗等特点&#xff0c;在智能家居领域展现出了巨大的潜力&#xff0c;正逐渐成为智能家居与物联网的重要连接者。本文将探讨UWB模块在智能家居与物联网中的关键作用、应用场景以及未来发展趋势&#xff0c;旨在为推动智能家居技术的创新和发…

基于Springboot的租房网站

基于SpringbootVue的租房网站的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 房屋信息 交流论坛 房屋资讯 后台登录 用户管理 房屋类型管理 房屋信息管理 预…

2、选择什么样的机器人本体

如果说世界是物质的&#xff0c;那么应该先制造出机器人的本体&#xff0c;再让她产生灵魂。如果是精神的呢&#xff0c;世界是无中生有的呢&#xff0c;那就先在仿真中研究算法吧。 而我比较崇尚初中哲学的一句话&#xff0c;世界是物质的&#xff0c;物质是运动的&am…

25考研数学可以全程跟张宇吗?

先说结论&#xff1a;25可以全程跟张宇。除了这三种情况。 总的来说&#xff0c;张宇的知识点是全的&#xff0c;不需要担心漏知识点、漏经典方法。不单高数&#xff0c;线代概率也是这样。 但是&#xff0c;老师讲得好&#xff0c;不能保证你上岸。 如果遇到这三种情况&…

【计算机网络】网络模型

OSI七层网络模型 七层模型如图所示 每层的概念和功能 物理层 职责&#xff1a;将数据以比特为单位&#xff0c;通过不同的传输介质将数据传输出去。 主要协议&#xff1a;物理媒介相关的协议&#xff0c;如RS232&#xff0c;V.35&#xff0c;以太网等。 数据链路层 职责&…