如何在 Visual Studio 2010 Ultimate 中为 VB.NET 中的 "catch with rethrow" 块获得 100% 的代码覆盖率?
How do I get 100% code coverage for "catch with rethrow" block in VB.NET in Visual Studio 2010 Ultimate?
我的 VB.NET 源代码中的 "catch with rethrow" 块无法实现 100% 的代码覆盖率。我的工作场所 IDE 是 Visual Studio 2010 Ultimate。下面的例子代表了我实际问题的简化版本。
C# 中的源代码:(light-blue 背景表示完全代码覆盖)
VB.NET中的等效源:(黄色背景表示部分代码覆盖)
C# 和 VB.NET 源代码的 MSTest(旨在实现 100% 的代码覆盖率)
代码覆盖率报告
代码覆盖率报告显示 C# 为 100%,但 VB.NET 仅为 91.67%。它还显示了 1 个代码块,在 VB.NET 中发现了 0 行。
这是工具的问题吗?还是我遗漏了一些明显的东西?
编辑 #1: 根据@Raptor 的要求共享源代码
C#源代码
public class CodeCoverage
{
public void DoWork(bool flag = false)
{
try
{
Thread.Sleep(1);
if (flag)
{
throw new Exception("test");
}
}
catch (Exception ex)
{
throw new Exception(string.Format("something happened: {0}", ex.Message));
}
}
}
源代码在VB.NET
Public Class CodeCoverage2
Public Sub DoWork(Optional ByVal flag As Boolean = False)
Try
Thread.Sleep(1)
If flag Then
Throw New Exception("test")
End If
Catch ex As Exception
Throw New Exception(String.Format("something happened: {0}", ex.Message))
End Try
End Sub
End Class
MSTest 的源代码
[TestClass]
public class CodeCoverageTest
{
[TestMethod]
public void DoWorkTest()
{
var obj = new CodeCoverage();
obj.DoWork();
}
[TestMethod]
[ExpectedException(typeof(Exception))]
public void DoWorkTest2()
{
var obj = new CodeCoverage();
obj.DoWork(true);
}
[TestMethod]
public void DoWorkTest3()
{
var obj = new CodeCoverage2();
obj.DoWork();
}
[TestMethod]
[ExpectedException(typeof(Exception))]
public void DoWorkTest4()
{
var obj = new CodeCoverage2();
obj.DoWork(true);
}
}
如果您在调试模式下查看为 VB 项目生成的 IL,您将在 catch 块中看到以下内容:
IL_002f: call string [mscorlib]System.String::Format(string, object)
IL_0034: newobj instance void [mscorlib]System.Exception::.ctor(string)
IL_0039: throw
IL_003a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_003f: leave.s IL_0041
因为 IL_0039
抛出,你永远不会命中 IL_003a
,所以你有永远不会被执行的代码。
在发布模式下,不会生成 ClearProjectError 的 IL。
没有足够的声誉来评论 John Koerner 的回复,这是正确的,但补充 - 我们通过让我们的测试目标 运行 处于发布模式来解决这个问题。这会导致代码覆盖率正常工作。
EG:
DEBUG Configuration:
MyApplication - RELEASE ANY CPU
MyTests - DEBUG ANY CPU
结果:
Old: DEBUG/DEBUG - 1 line missed N-1/N % coverage
New: RELEASE/DEBUG - 0 lines missed, 100 % coverage
感谢 John 为我们指明了看待 IL 的正确方向。
我的 VB.NET 源代码中的 "catch with rethrow" 块无法实现 100% 的代码覆盖率。我的工作场所 IDE 是 Visual Studio 2010 Ultimate。下面的例子代表了我实际问题的简化版本。
C# 中的源代码:(light-blue 背景表示完全代码覆盖)
VB.NET中的等效源:(黄色背景表示部分代码覆盖)
C# 和 VB.NET 源代码的 MSTest(旨在实现 100% 的代码覆盖率)
代码覆盖率报告
代码覆盖率报告显示 C# 为 100%,但 VB.NET 仅为 91.67%。它还显示了 1 个代码块,在 VB.NET 中发现了 0 行。
这是工具的问题吗?还是我遗漏了一些明显的东西?
编辑 #1: 根据@Raptor 的要求共享源代码
C#源代码
public class CodeCoverage
{
public void DoWork(bool flag = false)
{
try
{
Thread.Sleep(1);
if (flag)
{
throw new Exception("test");
}
}
catch (Exception ex)
{
throw new Exception(string.Format("something happened: {0}", ex.Message));
}
}
}
源代码在VB.NET
Public Class CodeCoverage2
Public Sub DoWork(Optional ByVal flag As Boolean = False)
Try
Thread.Sleep(1)
If flag Then
Throw New Exception("test")
End If
Catch ex As Exception
Throw New Exception(String.Format("something happened: {0}", ex.Message))
End Try
End Sub
End Class
MSTest 的源代码
[TestClass]
public class CodeCoverageTest
{
[TestMethod]
public void DoWorkTest()
{
var obj = new CodeCoverage();
obj.DoWork();
}
[TestMethod]
[ExpectedException(typeof(Exception))]
public void DoWorkTest2()
{
var obj = new CodeCoverage();
obj.DoWork(true);
}
[TestMethod]
public void DoWorkTest3()
{
var obj = new CodeCoverage2();
obj.DoWork();
}
[TestMethod]
[ExpectedException(typeof(Exception))]
public void DoWorkTest4()
{
var obj = new CodeCoverage2();
obj.DoWork(true);
}
}
如果您在调试模式下查看为 VB 项目生成的 IL,您将在 catch 块中看到以下内容:
IL_002f: call string [mscorlib]System.String::Format(string, object)
IL_0034: newobj instance void [mscorlib]System.Exception::.ctor(string)
IL_0039: throw
IL_003a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_003f: leave.s IL_0041
因为 IL_0039
抛出,你永远不会命中 IL_003a
,所以你有永远不会被执行的代码。
在发布模式下,不会生成 ClearProjectError 的 IL。
没有足够的声誉来评论 John Koerner 的回复,这是正确的,但补充 - 我们通过让我们的测试目标 运行 处于发布模式来解决这个问题。这会导致代码覆盖率正常工作。
EG:
DEBUG Configuration:
MyApplication - RELEASE ANY CPU
MyTests - DEBUG ANY CPU
结果:
Old: DEBUG/DEBUG - 1 line missed N-1/N % coverage
New: RELEASE/DEBUG - 0 lines missed, 100 % coverage
感谢 John 为我们指明了看待 IL 的正确方向。