代码覆盖率与代码质量

在软件开发过程中,代码覆盖率常常被用作衡量代码质量的一个重要指标。一些开发者甚至以100%的代码覆盖率为荣,认为这是代码质量的最佳证明。然而,是否真的需要100%的代码覆盖率来证明代码质量呢?

首先,需要了解什么是代码覆盖率。代码覆盖率是指在执行单元测试时,测试用例能够覆盖到的代码行数的比例。要达到100%的代码覆盖率,开发者需要付出大量的努力编写测试用例,并确保所有的代码路径都被覆盖,这无疑是非常耗时的。

那么,如果不追求100%的代码覆盖率,80%或75%的覆盖率是否更现实或更平衡呢?让回到测试的基本原则,问自己一个基本的测试问题:为什么要进行测试?

进行测试是因为存在复杂的代码,这些代码可能会导致缺陷。因此,需要确保这些复杂的代码有测试用例,并且已经被测试过,缺陷在上线前已经被修复。

在这里,可以看到“复杂”这个词被强调了。是的,这应该是驱动代码覆盖率的关键因素。换句话说,确保测试覆盖了代码的复杂部分。

那么,如何定义“复杂”呢?对于某些人来说复杂的东西,对于其他人来说可能很简单。那么,如何判断代码的复杂性呢?

代码行数多就意味着代码复杂吗?大量的IF和SELECT CASE、FOR循环会使代码复杂吗?应该以循环复杂度作为基准吗?如果对循环复杂度不熟悉,可以阅读这里:

大量的继承、聚合和组合会使代码复杂吗?认为应该有一个指标,能够考虑所有上述因素。“维护性指数”就是这样一个指标,它是由Visual Studio代码度量分析器提供的。维护性指数指标考虑了所有上述因素,并得出一个介于0到100之间的数值,数值越大越好。

所以,希望看到维护性指数较低的代码被100%覆盖。例如,在下面的报告中,希望看到“Calculate”方法有100%的测试覆盖率,因为它的维护性指数是65。但是“Cancel”方法的维护性指数值是80,所以可能会排除它。

如果查看“Cancel”方法的代码,它只是初始化了很多变量。所以测试这个方法只会增加单元测试的工作量,而不会有很大的质量提升。

public void Cancel() { Num1 = 0; Num2 = 0; Operation = ""; Pie = 3.14; Num5 = 0; Operation1 = ""; Num20 = 0; Numx = 0; OperationStart = ""; PieMore = 3.145; Num6 = 0; Operationnew = ""; }

现在看看“Calculate”方法,它很复杂,有很多“IF”条件等。所以希望确保这个方法的每个代码分支都被执行。

public int Calculate() { if (Operation.Length == 0) { throw new Exception("Operation not specified"); } if (Operation == "+") { return Num1 + Num2; } else if (Operation == "-") { return Num1 - Num2; } else { return Num2 * Num1; } return 0; }

所以,与其追求100%的代码覆盖率,建议遵循以下过程:

  • 了解代码中哪些部分的维护性指数较低,可以设定一个基准,比如低于80%。
  • 审查这部分代码,检查它是否复杂且关键。
  • 如果关键且重要,那么这部分代码应该被覆盖。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485