iOS单元测试详解

发表于:2018-2-02 10:22

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:赵先生Try    来源:简书

  5. 运行测试及查看测试结果
  ●快捷键:Command + U 即Xcode菜单中 Product -> Test
  特点:会运行所有测试类中所有的测试方法。
  ●Test navigation区:点击测试类或者测试方法的右测运行按钮
  点击测试类右侧运行按钮:运行此测试类中的所有测试方法。
  点击测试方法右侧运行按钮:运行此测试方法。
  ●Source editor区:点击测试方法或者测试类名字左侧的运行按钮。
  ●运行当前鼠标所在测试方法:control + option + command + U
  ●Test again(运行刚刚运行过的测试方法):control + option + command + G
  ●修改MZBayTests类,添加以下三个测试方法。
  step1.MZBayTests类中的测试方法
  现在选择Command + U运行测试,测试结果可以在Test Navigation和Source editor中直观看到。绿色的钩代表测试成功,红色的叉表示测试失败。普通测试和性能测试都测试成功,异步测试因为超时失败了。
  测试结果
  点击Source editor中testAdditionPerformance测试方法左侧灰色图标,进行最大标准差和baseline的设置。还可查看性能测试运行10次代码所花费的时长。
  step1.性能测试
  输入Max STDDEV(最大标准差)和baseline并保存。
  step2.性能测试
  在Reports navigation中,选中你要查看的测试即可查看更详细的测试结果信息。
  Reports navigation
  Tests 用来查看详细的测试过程
  Coverage 用来查看代码覆盖率
  Logs 用来查看测试的日志
  6. 代码覆盖率
  Xcode中的代码覆盖是LLVM提供的的测试选项。 当您启用代码覆盖时,LLVM将根据调用方法和函数的频率,对代码收集覆盖数据。 代码覆盖选项可以收集数据以报告正确性和性能的测试,无论是单元测试还是UI测试。
  在 scheme editor 菜单中选中 Edit Scheme .
  选中 Edit Scheme
  选中Test action,启用代码覆盖复选框以收集覆盖率数据。
  启用代码覆盖率
  注意:代码覆盖率数据收集会导致性能损失。当启动代码覆盖时,它以线性方式影响代码的执行。当严格评估测试的性能时,应该考虑是否启用代码覆盖。
  Reports navigator中 Coverage 菜单中可以查看代码覆盖的相关数据。
  Coverage
  用鼠标选中 - [Calculator input:]方法,将显示一个按钮,点击该按钮将带您进入带注解的源代码。
  Coverage
  Source editor显示文件中每行代码,在测试期间特定部分代码被调用的次数的注解在Source editor右侧绘制。
  Coverage
  并突出显示未执行的代码。 它突出了需要覆盖的代码领域,而不是已经涵盖的领域。
  Coverage
  代码覆盖率的意义在于告诉我们,运行测试时实际运行什么代码?代码的哪些部分未被测试?换句话说,是否已经设计了足够的测试,以确保正在检查您的所有代码的正确性和性能?
  7. 别人家的测试
  ●FMDB
  创建一个基类FMDBTempDBTests,让它实现创建数据库,及关闭数据库操作。
  其他测试类都继承FMDBTempDBTests基类。按照功能划分创建了多个测试类。
  FMDatabaseAdditionsTests对应着插入数据测试
  FMDatabaseQueueTests对应着多线程下进行数据库操作测试。
  FMDBTempDBTests.h
  ●FMDBTempDBTests.m的实现
  FMDBTempDBTests.m
  ●+setUp: 创建了一个空的数据库,然后调用实现的协议方法[self populateDatabase:db],进行创建表,并插入数据。
  ●-setUp: 将+setUp创建好的数据库拷贝到每个测试方法都使用的数据库地址,保证每个测试方法使用的数据库数据都是+setUp配置好的初始数据库,没有被别的测试方法污染。
  ●-tearDown:关闭数据库。
  FMDBTempDBTests的子类只要实现populateDatabase:db方法就配置好测试所需要的数据,可以直接写测试代码了。
  FMDatabaseQueueTests.m
  编写测试代码
  ●定义API要求:添加到项目中的每个方法或函数定义需求和结果很重要。对于需求,包括输入和输出范围,抛出的异常以及引发它们的条件以及返回的值的类型。
  ●在编写代码时编写测试用例:在设计和编写每个方法或函数时,请编写一个或多个测试用例以确保满足API的要求。
  ●检查边界条件。如果方法的参数必须具有特定范围内的值,则测试应传递包含范围的最低和最高值的值。例如,如果一个过程具有可以具有0到100之间的值的整数参数,则该方法的测试代码应该为参数传递值0,50和100。
  ●使用负面测试。负面测试确保您的代码适当地响应错误条件。验证您的代码在收到无效或意外输入值时的行为是否正确。还要验证它是否返回错误代码或引发异常。例如,如果一个整数参数的值必须在0到100之间,包括值,则创建传递值为-1和101的测试用例,以确保该过程引发异常或返回错误代码。
  ●编写综合测试用例。综合测试结合不同的代码模块来实现一些更复杂的API行为。虽然简单,孤立的测试提供价值,堆叠测试运行复杂的行为,并倾向于捕获更多的问题。这些类型的测试在更现实的条件下模拟您的代码的行为。例如,除了向数组添加对象之外,您还可以创建数组,向其中添加多个对象,使用不同的方法删除其中的一些对象,然后确保剩余对象的集合和数量正确。
  ●用测试用例覆盖您的错误修复。每当您修复错误时,请编写一个或多个验证修补程序的测试用例。
  ●测试用例分为三部分:
  1.配置测试的初始状态
  2.对要测试的目标执行代码
  3.对测试结果进行断言(成功 or 失败)
  ●测试代码结构
  当测试用例多了,你会发现测试代码编写和维护也是一个技术活。通常,我们会从几个角度考虑:
  1.不要测试私有方法(封装是OOP的核心思想之一,不要为了测试破坏封装)
  2.对用例分组(功能,业务相似)
  3.对单个用例保证测试独立(不受之前测试的影响,不影响之后的测试),这也是测试是否准确的核心。
  4.提取公共的代码和操作,减少copy/paste这类工作。
  让你的代码更容易单元测试
  通常,为了单元测试的准确性,一个方法对于同样的输入,输出是一致的。如果你写了一个没有参数,或者没有返回值的方法。那这个方法就很难测试了。
  如果项目框架使用的是MVC,
  View只做纯粹的展示型工作,把用户交互通过各种方式传递到外部
  Model只做数据存储类工作
  Controller作为View和Model的枢纽,往往要和很多View和Model进行交互,也是测试的痛点。
  对Controller瘦身是iOS架构中比较重要的一环。可参考更轻量的ViewController
  1.把 UITableViewDataSource 的代码提取出来放到一个单独的类中,你可以单独测试这个类,可以复用,再也不用写第二遍。也适用于其他的protocol,如UICollectionViewDataSource。
  2.将业务逻辑移到 Model 中,查找一个用户的目前的优先事项的列表,做为User的一个Category方法,而不是vc中直接写。
  3.创建Store类,Store 对象会关心数据加载、缓存和设置数据栈。它也经常被称为服务层或者仓库。
  4.把网络请求逻辑移到 Model 层,要在 view controller 中做网络请求的逻辑。取而代之,你应该将它们封装到另一个类中。这样,你的 view controller 就可以在之后通过使用回调(比如一个 completion 的 block)来请求网络了。这样的好处是,缓存和错误控制也可以在这个类里面完成。
  5.把View 代码移到 View 层。不应该在 view controller 中构建复杂的 view 层次结构。你可以使用 Interface Builder 或者把 views 封装到一个 UIView 子类当中。
  6.通讯:其他在 view controllers 中经常发生的事是与其他 view controllers,model,和 views 之间进行通讯。这当然是 controller 应该做的,但我们还是希望以尽可能少的代码来完成它。
  这块内容很空洞,可以参考更轻量的ViewController来做。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号