代码覆盖率:为什么结束标记是红色的(End If、End Try,...)
我将 MS-Test 与 Visual Studio 2010 和 Visual Basic 结合使用。
在下面的函数中,代码覆盖率告诉我,有一个未检查的块,并且带有 “End Try” 的行是红色的(请参见 http://lts.cr/BVvP):
Private Function GetLatestVersionInfoForAsync()
Try
Return GetLatestVersionInfo()
Catch ex As Exception
RaiseEvent UnhandledAsyncException(Me, New UnhandledExceptionEventArgs(ex, False))
Return New VersionInfo() With {.ExceptionOccoured = True, .Exception = ex}
End Try
End Function
那么,为什么这个“End Try”行是一个未覆盖的(红色)块(同样的情况也发生在最后的“End If”上)的函数)?
我的另一个问题:是否有任何资源可以解释代码覆盖率结果中的不同颜色(蓝色是清晰的,但我看到了黄色、深红色和浅红色,...)。
谢谢!
I use MS-Test with Visual Studio 2010 and Visual Basic.
In the following function the Code Coverage tells me, that there is one unchecked block and the line with the "End Try" is red (see http://lts.cr/BVvP):
Private Function GetLatestVersionInfoForAsync()
Try
Return GetLatestVersionInfo()
Catch ex As Exception
RaiseEvent UnhandledAsyncException(Me, New UnhandledExceptionEventArgs(ex, False))
Return New VersionInfo() With {.ExceptionOccoured = True, .Exception = ex}
End Try
End Function
So, why is this "End Try" line an uncovered (red) block (the same happens to "End If" at the end of a function)?
Another question I have: Is there any resource that explains the different colors of in the code coverage results (blue is clear, but I have seen yellow, dark and light red, ...).
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除了丹尼尔关于序列点的观点之外,值得进一步研究这一点。如果我们采用一个简单的函数来重复您在调试中所做的事情
,我们会得到以下序列点(我正在使用 OpenCover 为此)
(其中 sl = 起始行,el = 结束行,sc = 起始列,ec = 结束列,offset = IL 十进制偏移量)
但是,这些只有当您查看 IL
Now 时才有意义,如您所见
结束如果您在偏移量 40 (IL_0028) 处命中 IL 指令,那么您担心的 Try
行只会被标记为命中,但是当您查看生成的 IL 时,由于奇怪的 IL,我看不到您将如何到达那里生成(leave.s
是一个类似指令的小跳转,用于退出 try/catch/finally 块),如果您遵循代码,您会发现您总是会到达leave.s
跳转到首先是IL_0029。在发布中,IL 发生了变化
,序列点也发生了变化,
所以无论哪种方式,你都有点松散,因为现在你永远不会看到你的 try/catch 行被标记为覆盖
所以让我们尝试按照 Hans 的建议更改你的代码并返回调试(因为那是通常,您将在其中运行覆盖)
我们再次查看序列点
和 IL
,因此为了覆盖您的
End Try
,我们需要命中第 21 行,即偏移量 31 (IL_001F) 和正如我们所看到的leave.s
指令跳转到该点,因此现在该行将被标记为已覆盖。所以汉斯和丹尼尔都是正确的,我希望以上解释了原因
Further to Daniel's point on sequence points it's worth looking at this further. If we take a simple function that repeats what you are doing
In Debug we get the following sequence points (I am using OpenCover for this)
(where sl = start line, el = end line, sc = start column, ec = end column and offset = IL offset in decimal)
However these only make sense when you look at the IL
Now as you can see the
End Try
line you are concerned about would only be marked as hit if you hit the IL instruction at offset 40 (IL_0028) however when you look at the IL produced I cant see how you would ever get there due to the odd IL produced (leave.s
is a small jump like instruction that is used to exit try/catch/finally blocks) and if you follow the code you see that you will always reach aleave.s
that jumps to IL_0029 first.In release the IL changes
and so do the sequence points
So you sort of loose either way as now you will never see your try/catch lines marked covered
So lets try changing your code as suggested by Hans and go back to debug (because that is where you will be running coverage from usually)
Again we look at the sequence points
and the IL
So for your
End Try
to be covered we need line 21 to be hit and that is offset 31 (IL_001F) and as we can see bothleave.s
instructions jump to that point so now that line will be marked as covered.So both Hans and Daniel are correct and I hope the above explains why
在控制传递到
End Try
行之前,它会到达Return
行并退出该函数。所以(就代码覆盖率而言)你永远不会达到那条线。在这种情况下这并不是什么问题。解决方法是将 VersionInfo 保存在单个临时变量中,并在 End Try 之后返回该信息。一个猜测(我习惯了 C#,而不是 VB):
Before control passes that
End Try
line, it reaches theReturn
line and exits the function. So (as far as Code coverage is concerned) you never reach that line. Not that it is any problem in this case.A workaround would be to hold that VersionInfo in a single temp variable and return that after the End Try. A guess (I'm used to C#, not VB):
程序集的 PDB 文件包含 IL 指令对应于原始源代码的哪一行的信息。这条信息称为序列点。
但并非代码中的每一行都与一个序列点完全对应。
您的测试覆盖率是根据序列点计算的,因此可能会发生代码行显示为未被覆盖的情况,尽管它们是在测试期间执行的。
The PDB file of your assembly contains the information which IL instructions corresponds to which line(s) of your original source code. This piece of information is called a sequence point.
But not every line in your code corresponds exactly to one sequence point.
Your test coverage is calculated based on the sequence points, so it could happen that lines of your code appear uncovered although they were executed during your test.
我从未使用过 MS-Test,但它会将“New VersionInfo()”标记为未选中。
I have never used MS-Test but it will be flagging "New VersionInfo()" as unchecked.