Peter's Den

悲观者只见到机会后面的问题,乐观者却看见问题后面的机会

Hello,在下2012年涉足Apple Developer,至今在iOS/OSX领域混迹多年,本职工作以iOS为主


精通Objective-c/Swift,对Python/Java/.Net/JavaScript也略懂一二,会与大家在这里记录分享

iOS代码测试覆盖率(一)初探

Code Coverage

我们平时开发过程中,有多少同学有纠结过这些问题:

  • 我们写的代码或功能,测试同学有没有测试过呢?
  • 测试同学是否把所有case都跑过了呢?
  • 测试同学有没有漏测了什么功能呢?
  • 我们设计的代码有没有多余的?

其实这些疑问不是怀疑自己或他人的工作能力,只是我们希望自己的代码能够被全部测试,从而不会出现线上的故障,一个体量庞大的App若在线上出现一个故障,影响面有多广可想而知。

像之前苹果没有封杀热修复的时候,若我们的代码覆盖率能够做到100%(假设,虽然很难),那么热修复就没有那么的重要了,甚至可以说没有必要了。

代码覆盖是软件测试中的一种度量,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率。

常用度量方式

  • 函数覆盖率(Function coverage)
  • 语句覆盖率(Statement coverage):又称行覆盖
  • 判断覆盖率(Decision coverage)
  • 条件覆盖率(Condition coverage)
  • 路径覆盖率(Path Coverage)

举个例子

1.函数覆盖与语句覆盖,应该很好理解,函数覆盖就是这个函数有没有被调用过;语句/行覆盖就是这行有没有被调用过

2.判断覆盖:这个很容易与下面的条件覆盖弄混淆

func add(int a , int b) {
	if (a < 15 || b > 20) {
		print('a');
	}
}
//test case
//a = 5, b = 10 
//其实不管a与b是什么值,这个if判断都会执行,所以这个判断覆盖率是100%

3.条件覆盖:使用上面同一个add函数

//test case 1
//a = 5, b = 10
因为a小于15已经成立,不管b是什么值,都会打印a,b的判断不会被执行,所以此时条件覆盖率只有50%
//test case 2
//a = 15, b = 30
此时2个判断都会被执行,所以此时条件覆盖率是100%

4.路径覆盖率:这个也比较好理解,代表这个函数内所有是否都被执行过,还是以上面的add函数为例

这个函数总共有4条路径,想要达到100%覆盖率,那么就需要4个测试用例

  • a = 5, b = 5
  • a = 30, b = 5
  • a = 30, b = 30
  • a = 5, b = 30

这样才能达到100%的路径覆盖率

覆盖率高低

代码被测试覆盖了,并不能代表这个代码是无缺陷的,也不能代表这个代码被测试完成了,所以我们不能以是否覆盖也考量测试的质量,覆盖率高≠测试质量好,覆盖率低≠测试质量不好

路径覆盖率 > 判定覆盖 > 语句覆盖

虽说不能太相信覆盖率数据,但至少可以作为一个参考,下来我们来看看一个iOS工程如何实现覆盖率统计。

XCode & Coverage

在XCode 7上,支持了Code Coverage

覆盖率场景

  • 单元测试覆盖率:统计case的覆盖率
  • 远程多设备测试覆盖率:大量测试设备将覆盖统计汇总,生成一份总的覆盖率报告

今天我们这两种场景都会介绍一下,单测相对简单,负责的远程统计分析,也是本章的重点。

单元测试覆盖率

首先开启覆盖率:Edit Scheme -> Test -> Options -> Code Coverage for xxx (这个xxx可以自行配置需要的target)

我们来写一个简单的UnitCase,先创建一个CoverageManager

#import "CoverageManager.h"
@implementation CoverageManager
- (instancetype)init
{
    self = [super init];
    if (self) {
    }
    return self;
}
- (void)test {
    NSLog(@"test execute");
}
@end 

然后写一个Case,执行

执行成功后,在Show The Report里面可以看到如下

点击Coverage就可以看到本次Case的覆盖情况(如果需要看所有case的覆盖情况,就执行 Product -> Test

OK,单元测试的覆盖率是不是很简单,不过它缺点很明显,只能在本机执行Case的时候才能看到报告,也只能统计单测的覆盖了,对于客户端而言,可能更多的是关注提测后代码的测试覆盖率,下一章节就来重点来讲讲远程多端测试覆盖率

最近的文章

iOS逆向开发

iOS逆向开发 现在越狱的同学越来越少了,因为苹果经过这么多年借鉴越狱开发者的功能使得iOS本身已经很方便,以至于用户没有太大的必要去越狱了。 但是作为一名iOS开发者,逆向开发还有必要的,不管是学习他人的App还是自己想做一些功能,例如微信抢红包啥的。 下面所提到的所有逆向都支持安装在非越狱的iPhone上准备工具 一台已越狱的iPhone(用来砸壳):本文用的是iOS13.2.2 yololib:https://github.com/gaoshilei/yololib fr...…

iOS继续阅读
更早的文章

XTerminal - XCode终端命令插件

###XTerminal是什么? 它就是终端Terminal,只不过它是简单阉割版,部分命令暂时不能支持。 它虽是终端,但不止于终端,会集成各种快捷命令 插件下载地址在本文最后###为什么要造一个XTerminal? Apple很吝啬,始终不肯将terminal嵌入XCode中,像Android Studio,IDEA等都支持了。 我们是否需要它? 假如git操作常用SourceTree等客户端,可能对此插件需求不高。 当然我们也可以使用XCode的Behavio...…

iOS/OSX继续阅读