gpt4 book ai didi

vb.net - 代码覆盖率: Why is end marker red (End If,结束尝试,...)

转载 作者:行者123 更新时间:2023-12-02 09:17:16 34 4
gpt4 key购买 nike

我将 MS-Test 与 Visual Studio 2010 和 Visual Basic 结合使用。

在下面的函数中,代码覆盖率告诉我,有一个未检查的 block ,并且带有 “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”行是一个未覆盖的(红色) block (函数末尾的“End If”也是如此)?

我的另一个问题:是否有任何资源可以解释代码覆盖率结果中的不同颜色(蓝色是清晰的,但我见过黄色、深红色和浅红色,...)。

谢谢!

最佳答案

除了丹尼尔关于序列点的观点之外,值得进一步研究一下。如果我们采用一个简单的函数来重复您正在做的事情

07    Function Method() As String
08 Try
09 Return ""
10 Catch ex As Exception
11 Return ""
12 End Try
13 End Function

在调试中,我们得到以下序列点(我为此使用 OpenCover)

<SequencePoints> 
<SequencePoint offset="0" ordinal="0" uspid="261" vc="0" ec="32" el="7" sc="5" sl="7"/>
<SequencePoint offset="1" ordinal="1" uspid="262" vc="0" ec="12" el="8" sc="9" sl="8"/>
<SequencePoint offset="2" ordinal="2" uspid="263" vc="0" ec="22" el="9" sc="13" sl="9"/>
<SequencePoint offset="19" ordinal="3" uspid="264" vc="0" ec="30" el="10" sc="9" sl="10"/>
<SequencePoint offset="20" ordinal="4" uspid="265" vc="0" ec="22" el="11" sc="13" sl="11"/>
<SequencePoint offset="40" ordinal="5" uspid="266" vc="0" ec="16" el="12" sc="9" sl="12"/>
<SequencePoint offset="41" ordinal="6" uspid="267" vc="0" ec="17" el="13" sc="5" sl="13"/>
</SequencePoints>

(其中 sl = 起始行,el = 结束行,sc = 起始列,ec = 结束列,offset = IL 十进制偏移量)

但是,这些只有在查看 IL 时才有意义

.method public static 
string Method () cil managed
{
// Method begins at RVA 0x272c
// Code size 43 (0x2b)
.maxstack 2
.locals init (
[0] string Method,
[1] class [mscorlib]System.Exception ex
)

IL_0000: nop
IL_0001: nop
.try
{
IL_0002: ldstr ""
IL_0007: stloc.0
IL_0008: leave.s IL_0029

IL_000a: leave.s IL_0028
} // end .try
catch [mscorlib]System.Exception
{
IL_000c: dup
IL_000d: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
IL_0012: stloc.1
IL_0013: nop
IL_0014: ldstr ""
IL_0019: stloc.0
IL_001a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_001f: leave.s IL_0029

IL_0021: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_0026: leave.s IL_0028
} // end handler

IL_0028: nop

IL_0029: ldloc.0
IL_002a: ret
} // end of method Module1::Method

现在,您可以看到,如果您在偏移量 40 (IL_0028) 处命中了 IL 指令,那么您所关心的 End Try 行才会被标记为命中,但是当您查看生成的 IL 时,我由于生成了奇怪的 IL(leave.s 是一个类似小跳转的指令,用于退出 try/catch/finally block ),因此无法看到如何到达那里,如果您按照代码操作,请注意,您总是会到达首先跳转到 IL_0029 的 leave.s

发布中 IL 发生变化

.method public static 
string Method () cil managed
{
// Method begins at RVA 0x2274
// Code size 30 (0x1e)
.maxstack 2
.locals init (
[0] string Method,
[1] class [mscorlib]System.Exception ex
)

.try
{
IL_0000: ldstr ""
IL_0005: stloc.0
IL_0006: leave.s IL_001c
} // end .try
catch [mscorlib]System.Exception
{
IL_0008: dup
IL_0009: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
IL_000e: stloc.1
IL_000f: ldstr ""
IL_0014: stloc.0
IL_0015: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_001a: leave.s IL_001c
} // end handler

IL_001c: ldloc.0
IL_001d: ret
} // end of method Module1::Method

序列点也是如此

<SequencePoints> 
<SequencePoint offset="0" ordinal="0" uspid="33" vc="0" ec="22" el="9" sc="13" sl="9"/>
<SequencePoint offset="15" ordinal="1" uspid="34" vc="0" ec="22" el="11" sc="13" sl="11"/>
<SequencePoint offset="28" ordinal="2" uspid="35" vc="0" ec="17" el="13" sc="5" sl="13"/>
</SequencePoints>

所以无论哪种方式,你都有点松散,因为现在你将永远不会看到你的 try/catch 行被标记为覆盖

所以让我们尝试按照 Hans 的建议更改代码并返回调试(因为这是您通常运行覆盖的地方)

15   Function Method2() As String
16 Dim x As String
17 Try
18 x = ""
19 Catch ex As Exception
20 x = ""
21 End Try
22 Return x
23 End Function

我们再次查看序列点

<SequencePoints> 
<SequencePoint offset="0" ordinal="0" uspid="268" vc="0" ec="33" el="15" sc="5" sl="15"/>
<SequencePoint offset="1" ordinal="1" uspid="269" vc="0" ec="12" el="17" sc="9" sl="17"/>
<SequencePoint offset="2" ordinal="2" uspid="270" vc="0" ec="19" el="18" sc="13" sl="18"/>
<SequencePoint offset="17" ordinal="3" uspid="271" vc="0" ec="30" el="19" sc="9" sl="19"/>
<SequencePoint offset="18" ordinal="4" uspid="272" vc="0" ec="19" el="20" sc="13" sl="20"/>
<SequencePoint offset="31" ordinal="5" uspid="273" vc="0" ec="16" el="21" sc="9" sl="21"/>
<SequencePoint offset="32" ordinal="6" uspid="274" vc="0" ec="17" el="22" sc="9" sl="22"/>
<SequencePoint offset="36" ordinal="7" uspid="275" vc="0" ec="17" el="23" sc="5" sl="23"/>
</SequencePoints>

和IL

.method public static 
string Method2 () cil managed
{
// Method begins at RVA 0x282c
// Code size 38 (0x26)
.maxstack 2
.locals init (
[0] string Method2,
[1] string x,
[2] class [mscorlib]System.Exception ex
)

IL_0000: nop
IL_0001: nop
.try
{
IL_0002: ldstr ""
IL_0007: stloc.1
IL_0008: leave.s IL_001f
} // end .try
catch [mscorlib]System.Exception
{
IL_000a: dup
IL_000b: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
IL_0010: stloc.2
IL_0011: nop
IL_0012: ldstr ""
IL_0017: stloc.1
IL_0018: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_001d: leave.s IL_001f
} // end handler

IL_001f: nop
IL_0020: ldloc.1
IL_0021: stloc.0
IL_0022: br.s IL_0024

IL_0024: ldloc.0
IL_0025: ret
} // end of method Module1::Method2

因此,为了覆盖您的 End Try,我们需要命中第 21 行,即偏移量 31 (IL_001F),正如我们所看到的 leave.s 指令跳到该点,现在该行将被标记为已覆盖。

所以汉斯和丹尼尔都是正确的,我希望以上解释了原因

关于vb.net - 代码覆盖率: Why is end marker red (End If,结束尝试,...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8926063/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com