什么是 JavaScript 单元测试的代码覆盖分支
Posted
技术标签:
【中文标题】什么是 JavaScript 单元测试的代码覆盖分支【英文标题】:What is a branch in code coverage for JavaScript unit testing 【发布时间】:2016-05-04 06:19:51 【问题描述】:我使用 Istanbul 来覆盖 AngularJS 项目中单元测试的代码覆盖率。有 4 种类型的覆盖范围,它们是
声明 分支 功能 行语句、函数和行都可以,但我不明白“分支”是什么。什么是分支?
【问题讨论】:
【参考方案1】:分支是运行时可以选择是否采用一条路径或另一条路径的地方。举个例子:
if(a)
Foo();
if(b)
Bar();
Yay();
当到达第一行时,它可以决定是否要进入if(a)
-statement 的主体。此外,它可以决定不这样做。在这个阶段,我们已经看到了两条路径(一个分支)。
之后的下一个语句变得更有趣。它可以进入if
主体并执行Bar
。它也不能那样做。但请记住,我们之前已经有一个分支。如果Foo
被调用,结果可能会有所不同。
所以我们最终得到了四种可能的路径:
不打电话给Foo
,也不打电话给Bar
呼叫Foo
,不呼叫Bar
不调用Foo
,调用Bar
同时调用Foo
和Bar
最后一个Yay
总是被执行,不管是Foo
还是Bar
被调用,所以这不算作一个分支。所以上面的代码sn-p包含四个路径/两个分支(调用Foo()
与否,调用Bar()
与否)。
就像已经提到的其他答案一样,有许多语句可能导致分支 (if
/switch
)。一些(但不是全部)包括:
while
/for
/do-while
)
break
或 continue
声明
二进制短路运算符(即&&
/||
)
例如。给定foo && bar
,如果foo
是false
,则不必评估bar
。同样对于foo || bar
,如果foo
是true
,bar
也不必进行评估。
默认参数(即function A(someVar = []) ...
)
这是因为对该方法的调用被解释为if
-语句。对于此方法的每次调用,都会检查参数是否为undefined
。如果是,则为someVar
设置默认参数(对于上面的示例)。这会导致分支存在。
代码覆盖率工具希望确保您已经测试了所有分支。最好的情况是所有路径都经过测试,甚至所有(边缘情况)值,而不仅仅是分支。这是为了确保不会执行不需要的行为。
【讨论】:
感谢您的详细回答。 @Arseniy-II 默认参数值如何导致分支?这只是一个不同的价值/电话。不过我可能是错的。 @Caramiriel 我刚刚在测试时将其作为分支。而且我认为从开玩笑的角度来看,它与:let actualVar = someVar || []
相同。所以基本上它是“使用[ ]
IF someVar
是undefined
”。但如果你能检查一下就好了:)【参考方案2】:
来自Wikipedia:
是否每个控制结构(例如 if 和 case 语句)的每个分支(也称为 DD 路径)都已执行?例如,给定一个 if 语句,是否同时执行了 true 和 false 分支?另一种说法是,程序中的每一条边都被执行了吗?
您必须为每个控制结构测试所有可能的情况(在 if 语句、f.e. 和 switch 的所有情况下输入/不输入)。分支覆盖率是衡量(通常以百分比表示)测试覆盖的总分支数量的指标。
【讨论】:
【参考方案3】:代码可以采用多条路径的地方,即它的分支。分支语句的几个示例是 if
/else
和 switch
语句。
分支覆盖跟踪哪些分支已执行,因此您可以确保正确测试所有路由。
【讨论】:
以上是关于什么是 JavaScript 单元测试的代码覆盖分支的主要内容,如果未能解决你的问题,请参考以下文章
Karma +Jasmine+ require JS进行单元测试并生成测试报告代码覆盖率报告