首页 > 其他分享 >iOS单元测试

iOS单元测试

时间:2023-12-08 19:02:08浏览次数:35  
标签:... format 单元测试 iOS a1 a2 测试 expression

一、简介

单元测试通常由软件开发人员自己编写,他们将确认具体功能是否按照设计要求正常工作。单元测试的目标是隔离代码的每个部分,并确保每个独立的部分都能正常工作。

例如,如果你有一个计算器应用程序,你可能会为加法、减法、乘法和除法等每个功能编写单元测试,以确保当给定特定输入时,这些功能能返回正确的结果。

这种测试方法可以帮助找出代码中的错误和问题,确保在整个软件系统中的各个单位都能正常工作,从而提高了代码质量和可维护性。

在 iOS 开发中 XCTestApple 提供的官方测试框架,用于进行单元测试、性能测试以及用户界面测试。

以下是关于 XCTest 的详细介绍:

  • 主要组件XCTest 框架包括 XCTests(单元测试)、XCUItests(用户界面测试)和 XCPPerformanceTests(性能测试)。
  • 单元测试(XCTests:这是最基础的测试类型,主要用于测试应用中的个别方法或计算逻辑是否按预期工作。
  • 用户界面测试(XCUItests:这种测试模拟用户与应用程序的交互操作,例如点击按钮、滑动屏幕等。该测试可确保当用户使用您的应用时,界面和交互功能能正常运行。
  • 性能测试(XCPPerformanceTests:这种测试帮助您量化代码的性能,并在代码更改后跟踪其变化。您可以为某些任务设置基准时间,然后在优化代码后比较新的执行时间。
  • 测试断言XCTest 提供了一套断言供你验证测试结果。这些断言包括 XCTAssertTrue(), XCTAssertFalse(),XCTAssertEqual() 等。
  • 集成和运行XCTest 完全集成在 Xcode 中,且易于使用。你可以直接从 Xcode 的测试导航器运行测试,或者使用快捷键 Cmd + U 运行所有测试。
  • 测试报告Xcode 会为执行的 XCTest

总的来说,XCTest

二、如何项目中添加

Xcode 中添加一个新的 XCTest

1、创建项目是直接创建

创建项目成功过项目目录下即可看到对应的单元测试文件夹

带有 Tests 后缀的文件夹

2、已有的项目添加 XCTest

3、运行 - (void)testExample 方法一直报错 Test Failed

报错 The bundle “...Tests” couldn’t be loaded. Try reinstalling the bundle.

需要设置 team 和 项目的 team 一致来解决

4、'XCTest/XCTest.h' file not found

问题描述:fatal error: 'XCTest/XCTest.h' file not found

解决方法

在报错的 Target 中的 Building settingsFRAMEWORK_SEARCH_PATHS 添加 $(PLATFORM_DIR)/Developer/Library/Frameworks

5、运行项目报错 Library not loaded: @rpath/XCTest.framework/XCTest

三、 方法简单概述:

setUp 方法是当前测试类的初始化方法,我们可以将一些资源准备工作在这个方法中完成;
tearDown 方式在测试结束后会调用,用来进行资源的清理。
测试函数都需要以 text 开头,testExample 是默认生成的一个测试用例函数,可以编辑testXXX方法,只要是 test 开头的方法都可以进行检查。xCTest 框架提供了众多测试断言,可以用来测试,命中断言,则认为当前测试用例失败。
testPerformanceExample 是性能测试的一个案例,其内的 measureBlock 里的代码会被默认执行10次,最终输出每次执行的时间消耗报告。

1.测试函数的要求是:1.必须无返回值;2.实例方法要求:没有入参,没有返回值,以 test 开头

2.测试函数执行的顺序:以函数名中 test 后面的字符大小有关,比如 -(void)test001XXX 会先于 -(void)test002XXX 执行;

3.运行单元测试的快捷键:CMD + U;

4.下面一共18个断言(SDK中也是18个,其含义转自 ios UnitTest 学习笔记,真心佩服原文的博主):

`XCTFail(format…)` 生成一个失败的测试; 

`XCTAssertNil(a1, format...)` 为空判断,a1为空时通过,反之不通过; 

`XCTAssertNotNil(a1, format…)` 不为空判断,a1不为空时通过,反之不通过;

`XCTAssert(expression, format...)` 当 `expression` 求值为 `TRUE` 时通过; 

`XCTAssertTrue(expression, format...)` 当 `expression` 求值为 `TRUE` 时通过; 

`XCTAssertFalse(expression, format...)` 当 `expression` 求值为 `False` 时通过; 

`XCTAssertEqualObjects(a1, a2, format...)` 判断相等, `[a1 isEqual:a2]` 值为TRUE时通过,其中一个不为空时,不通过;

`XCTAssertNotEqualObjects(a1, a2, format...)` 判断不等, `[a1 isEqual:a2]` 值为 `False` 时通过;

`XCTAssertEqual(a1, a2, format...)` 判断相等(当a1和a2是 C语言标量、结构体或联合体时使用,实际测试发现 `NSString` 也可以); 

`XCTAssertNotEqual(a1, a2, format...)` 判断不等(当a1和a2是 C语言标量、结构体或联合体时使用);

`XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...)` 判断相等,(`double`或`float`类型)提供一个误差范围,当在误差范围(`+/-accuracy`)以内相等时通过测试; 

`XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...)` 判断不等,(`double`或`float`类型)提供一个误差范围,当在误差范围以内不等时通过测试; 

`XCTAssertThrows(expression, format...)` 异常测试,当 `expression` 发生异常时通过;反之不通过;(很变态) 

`XCTAssertThrowsSpecific(expression, specificException, format...)` 异常测试,当 `expression` 发生 `specificException` 异常时通过;反之发生其他异常或不发生异常均不通过; 

`XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...)` 异常测试,当 `expression` 发生具体异常、具体异常名称的异常时通过测试,反之不通过; 

`XCTAssertNoThrow(expression, format…)` 异常测试,当 `expression` 没有发生异常时通过测试;

`XCTAssertNoThrowSpecific(expression, specificException, format...)` 异常测试,当 `expression` 没有发生具体异常、具体异常名称的异常时通过测试,反之不通过; 

`XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...)` 异常测试,当 `expression` 没有发生具体异常、具体异常名称的异常时通过测试,反之不通过

特别注意下 XCTAssertEqualObjectsXCTAssertEqual

`XCTAssertEqualObjects(a1, a2, format...)` 的判断条件是 `[a1 isEqual:a2]` 是否返回一个 `YES`。

`XCTAssertEqual(a1, a2, format...)` 的判断条件是`a1 == a2`是否返回一个 `YES`。

对于后者,如果a1和a2都是基本数据类型变量,那么只有a1 == a2才会返回YES。例如下面代码中只有第二行可以通过测试:

// 1.比较基本数据类型变量
XCTAssertEqual(1, 2, @"a1 = a2 shoud be true"); // 无法通过测试
XCTAssertEqual(1, 1, @"a1 = a2 shoud be true"); // 通过测试

但是,如果a1和a2都是指针,那么只有a1和a2指向同一个对象才会返回YES。例如下面的代码中:

// 3.比较NSArray对象
    NSArray *array1 = @[@1];
    NSArray *array2 = @[@1];
    NSArray *array3 = array1;
    XCTAssertEqual(array1, array2, @"a1 and a2 should point to the same object"); // 无法通过测试
    XCTAssertEqual(array1, array3, @"a1 and a2 should point to the same object"); // 通过测试

array1和array2指向不同对象,无法通过测试。

这里比较奇怪的是,NSString 另当别论:

// 2.比较NSString对象
    NSString *str1 = @"1";
    NSString *str2 = @"1";
    NSString *str3 = str1;
    XCTAssertEqual(str1, str2, @"a1 and a2 should point to the same object"); // 通过测试
    XCTAssertEqual(str1, str3, @"a1 and a2 should point to the same object"); // 通过测试

尽管str1和str2指向不同的对象,但是二者的指针比较却能通过测试。 由于str1和str2指向同一常量,常量在内存的 data 段中地址是固定的,所以二者地址相同。

四、异步函数的测试

前面我们演示的测试用例所执行的逻辑都是同步的,但在实际的项目中,异步的操作很多,

- (void)requestData:(void (^)(BOOL))complete {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (complete) {
            complete(YES);
        }
    });
}

测试用例如下:

- (void)testAsync {
    XCTestExpectation *except = [self expectationWithDescription:@"异步请求测试用例"];
    [self.viewModel requestData:^(BOOL success) {
        XCTAssertTrue(success);
        [except fulfill];
    }];
    [self waitForExpectationsWithTimeout:10 handler:^(NSError * _Nullable error) {
        
    }];
}

XCTestExpectation 可以理解为一个期望对象,当使用此对象调用 fulfill 方法后,表示异步逻辑完成。

五、代码覆盖率

与单元测试相关的,还有一个重要的概念:代码覆盖率。代码覆盖率是指在整个测试执行过程中,覆盖到的功能函数与所有功能函数的比例。覆盖率越高说明测试涉及的功能越全。

测试完成后,可以直接在Xcode中查看代码覆盖率,如下图所示:

单元测试保持较高的覆盖率是非常重要的,其从另一个方面也是测试质量的保障。【当然这里是一个示例,所以没有很高的覆盖率】

如果看不到代码覆盖率,点击edit scheme,看对应的tagart-->test-->code Coverage 那个对勾都勾上了没有

六、关于单元测试(逻辑代码部分)的几点建议

不涉及UI方面的自动化测试,只针对逻辑代码的单元测试,下面这些建议可供参考:

  • 在编码时,要尽量按照MVVM的模式进行开发,相比MVC模式,MVVM的逻辑代码都封装在VM里面,更利于进行脱离UI的测试。可以设想,如果将逻辑方法都写在ViewViewController中,则执行测试用例时就不得不引入很多额外的页面UI组件。
  • 编写测试用例时,有3个核心要考虑的点,即输入输出结果判定。我们通过输入来设置测试用例的初始状态,通过对输出的结果判定来决定测试用例是否通过。
  • 在开发中,编写的函数要尽量符合下面的特性:功能单一,有输入有输出。
  • 函数有输入参数,没有返回值时,需要对输入的参数进行修改,则这种场景编写测试用例时,要判断的是执行函数操作后的原始变量是否符合预期。
  • 函数没有输入参数,没有返回值时,其作用只是执行一段逻辑操作,例如存储文件,修改文件等。这时我们可以修改下功能函数,在函数内返回操作成功或失败的结果,测试用例使用此结果来作为是否通过的标准。
七、XCTest 框架中也是有 UI 测试的

例如: 创建一个 UI Test Target

自带会有这样的方法测试启动时长性能方法

生成文件示例

运行查看启动时长

启动时长日志输出

总结:默认会联系多次启动,可以查看每次的时长,方便对比结果。

遇到的 UITest 问题 testExample: Device is not configured for UI testing - use of XCUIApplication is not supported. This can happen when XCUIApplication is used in a unit test bundle instead of a UI test bundle. (NSInternalInconsistencyException)

解决方案: 1、UI test 和 逻辑 test 是不同的 target, 可能选择错了,需要创建 UI test target

更多的使用可以参考iOS单元测试的那些事儿

原博客:https://www.jianshu.com/p/c55f364b3750?v=1702025708466

标签:...,format,单元测试,iOS,a1,a2,测试,expression
From: https://blog.51cto.com/u_16422529/8741267

相关文章

  • 单元测试实战(二)Service 的测试
    单元测试实战(二)Service的测试为鼓励单元测试,特分门别类示例各种组件的测试代码并进行解说,供开发人员参考。本文中的测试均基于JUnit5。单元测试实战(一)Controller的测试单元测试实战(二)Service的测试单元测试实战(三)JPA的测试  单元测试实战(四)MyBatis-Plus的测试单......
  • Java编写单元测试用例
    Java编写单元测试用例01简介Java中可以使用多个测试框架来执行单元测试,其中最流行的测试框架之一是JUnit。下面是一个简单的示例,说明如何使用JUnit框架编写和执行单元测试:02一、JUnit包导入importorg.junit.*;03二、创建测试类这个类需要使用“@RunWith’和@Suite”注......
  • Java单元测试浅析(JUnit+Mockito)
    Java单元测试浅析(JUnit+Mockito)作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作。2)集成测试:在单元测试基础上,整合各个模......
  • java 单元测试之 - Spring框架提供的单元/集成测试注解
    java单元测试之-Spring框架提供的单元/集成测试注解Spring框架提供了很多注解来辅助完成单元测试和集成测试(备注:这里的集成测试指容器内部的集成测试,非系统间的集成测试),先看看Spring框架提供了哪些注解以及对应的作用。@RunWith(SpringRunner.class)/@ExtendWith(Spring......
  • Java Mockito 快速入门指南 Mock是指使用Mockito创建的模拟对象,它模拟真实对象的行为,
    JavaMockito快速入门指南Mock是指使用Mockito创建的模拟对象,它模拟真实对象的行为,用于替代真实对象的依赖项,以便进行独立的单元测试在软件开发中,单元测试对于确保代码的正确性和可靠性至关重要。Mockito是一个强大的Java测试框架,它提供了丰富的功能和方法,使得编写模拟测试变得......
  • 开发APP应用程序到底是选ios好还是Android好?
    哈喽大家好,我是咕噜老尼,现在我们都知道,APP应用已经覆盖了我们的生活,成为我们生活中不可缺少的一部分,手机系统主要分两种,分别是安卓和ios系统,不少APP开发公司在制作手机APP时,都需要将同一款APP做成两种,分别适应安卓和iOS系统。那么,开发APP应用程序到底是选ios好还是Android好,我们一......
  • 单元测试平台搭建:sonarQube+sonarScanner+Jenkins+jacoco
    单元测试平台搭建及结果分析一、方案需求目标:提高单元测试覆盖率和规范代码编写规范选用工具:Sonarqube、sonarqubeScanner、Jenkins、jacoco方案:工程中引入jacoco进行代码覆盖率统计,通过sonarqubescanner扫描工程编写规范,编写单元测试代码后,结合Jenkins每次的编译部署自动......
  • vs+xunit 单元测试
    vs中nuget安装Microsoft.NET.Test.Sdk、xunit、xunit.runner.visualstudioxunit测试demopublicclassHelloTest{//xunit提供默认输出接口privatereadonlyITestOutputHelper_output;publicHelloTest(ITestOutputHelperoutput){_outp......
  • MDM介绍:3. 让我们对macOS/iOS设备了如指掌
    “小李,新出现的勒索比较猖獗,赶快查看一下哪些电脑没有安装杀毒软件,没有安装的尽快安装,安装了没有更新的也尽快更新一下,今天完成!下班前给我汇报一下进度。”一到单位部门经理就对小李说道。“好的,我这就检查。”小李回答。1个小时过后,小李来到经理办公室说:“领导,检查完了,所有电脑都......
  • 苹果iOS 17.2 RC准正式版发布!iPhone 15 Pro系列独占空间视频来了
    今天凌晨,苹果面向开发者和公测用户发布iOS17.2RC版本,内部版本号为21C62。iOS17.2RC也就是iOS17.2准正式版,如果没有大的Bug,这将是iOS17.2正式版发布前最后一次更新。升级日志显示,iOS17.2RC新增iPhone15Pro系列空间视频拍摄功能、iPhone15Pro系列操作按钮新增“翻译......