zoukankan      html  css  js  c++  java
  • .NET 的单元测试之路 之三:计算代码覆盖率

    1. 准备业务代码和测试代码

      1. 新建一个.net framework类库,创建Calc.cs文件,添加如下代码:

        public class Calc
        {
            public int AbsAdd(int a, int b)
            {
                if (a > 0)
                    return a + b;
                else
                    return (-1) * a + b;
            }
            public int Abs(int a)
            {
                if (a > 0)
                    return a;
                return -1 * a;
            }
        }
      2. 新建一个UT项目,对Calc的方法添加测试

        [TestClass]
        public class CalcTest
        {
            [TestMethod]
            public void Add_Test()
            {
                Calc calc = new Calc();
                var s = calc.AbsAdd(3, 6);
                Assert.AreEqual(s, 9);
            }
            [TestMethod]
            public void AbsAdd_Test()
            {
                Calc calc = new Calc();
                var s = calc.Abs(-3);
                Assert.AreEqual(s, 3);
            }
        }
    2. 在VS中执行测试、并检查测试覆盖度,用颜色标记覆盖代码行

      1. 在测试资源管理器中,点相应测试用例,右键“分析所选测试的代码覆盖率”
      2. 可以看到覆盖率、双击相应方法,可以看到哪些代码被覆盖,哪些没被覆盖
    3. 用命令行执行单元测试,并检查代码覆盖度。

      1. 添加环境变量。执行单元测试要用到vstest.console.exe,检查覆盖度要用到CodeCoverage.exe。它们都在visual studio的安装目录中,只是没有把路径加到系统环境变量中。因此,需要先把它们加到环境变量的Path里。
        1. vstest.console.exe:VisualStudio安装目录Team ToolsDynamic Code Coverage Tools;
        2. CodeCoverage.exe:VisualStudio安装目录Common7IDEExtensionsTestPlatform;
      2. 运行命令:
        1. 收集:CodeCoverage collect /output:D:1Files3.coverage vstest.console.exe D:1UTUTinDebugUT.dll
          参数:
          1. 3.coverage 是要生成的覆盖度文件,2进制文件,需要用vs查看。
          2. UT.dll 是测试项目编译后的文件
        2. 分析:CodeCoverage analyze /output:D:1Files3.xml D:1Files3.coverage
          该命令会把3.coverage转成可读的文件3.xml。

          <?xml version="1.0" encoding="UTF-8" ?>
          <results>
            <modules>
              <module name="ut.dll" path="ut.dll" id="1F16FE5964AEE54C9413C7FB6B33EDAC01000000" block_coverage="100.00" line_coverage="100.00" blocks_covered="8" blocks_not_covered="0" lines_covered="10" lines_partially_covered="0" lines_not_covered="0">
                <functions>
                  <function id="8272" token="0x6000001" name="Add_Test()" namespace="UT" type_name="CalcTest" block_coverage="100.00" line_coverage="100.00" blocks_covered="4" blocks_not_covered="0" lines_covered="5" lines_partially_covered="0" lines_not_covered="0">
                    <ranges>
                      <range source_id="0" covered="yes" start_line="12" start_column="9" end_line="12" end_column="10" />
                      <range source_id="0" covered="yes" start_line="13" start_column="13" end_line="13" end_column="36" />
                      <range source_id="0" covered="yes" start_line="14" start_column="13" end_line="14" end_column="39" />
                      <range source_id="0" covered="yes" start_line="15" start_column="13" end_line="15" end_column="35" />
                      <range source_id="0" covered="yes" start_line="16" start_column="9" end_line="16" end_column="10" />
                    </ranges>
                  </function>
                  <function id="8312" token="0x6000002" name="AbsAdd_Test()" namespace="UT" type_name="CalcTest" block_coverage="100.00" line_coverage="100.00" blocks_covered="4" blocks_not_covered="0" lines_covered="5" lines_partially_covered="0" lines_not_covered="0">
                    <ranges>
                      <range source_id="0" covered="yes" start_line="19" start_column="9" end_line="19" end_column="10" />
                      <range source_id="0" covered="yes" start_line="20" start_column="13" end_line="20" end_column="36" />
                      <range source_id="0" covered="yes" start_line="21" start_column="13" end_line="21" end_column="34" />
                      <range source_id="0" covered="yes" start_line="22" start_column="13" end_line="22" end_column="35" />
                      <range source_id="0" covered="yes" start_line="23" start_column="9" end_line="23" end_column="10" />
                    </ranges>
                  </function>
                </functions>
                <source_files>
                  <source_file id="0" path="D:1UTUTUnitTest1.cs">
                  </source_file>
                </source_files>
              </module>
              <module name="bizlogic.dll" path="bizlogic.dll" id="3CCBE3B7A33CB441A19683A78A499F7901000000" block_coverage="75.00" line_coverage="80.00" blocks_covered="6" blocks_not_covered="2" lines_covered="8" lines_partially_covered="0" lines_not_covered="2">
                <functions>
                  <function id="8272" token="0x6000001" name="AbsAdd(int, int)" namespace="BizLogic" type_name="Calc" block_coverage="75.00" line_coverage="80.00" blocks_covered="3" blocks_not_covered="1" lines_covered="4" lines_partially_covered="0" lines_not_covered="1">
                    <ranges>
                      <range source_id="0" covered="yes" start_line="12" start_column="9" end_line="12" end_column="10" />
                      <range source_id="0" covered="yes" start_line="13" start_column="13" end_line="13" end_column="23" />
                      <range source_id="0" covered="yes" start_line="14" start_column="17" end_line="14" end_column="30" />
                      <range source_id="0" covered="no" start_line="16" start_column="17" end_line="16" end_column="37" />
                      <range source_id="0" covered="yes" start_line="17" start_column="9" end_line="17" end_column="10" />
                    </ranges>
                  </function>
                  <function id="8312" token="0x6000002" name="Abs(int)" namespace="BizLogic" type_name="Calc" block_coverage="75.00" line_coverage="80.00" blocks_covered="3" blocks_not_covered="1" lines_covered="4" lines_partially_covered="0" lines_not_covered="1">
                    <ranges>
                      <range source_id="0" covered="yes" start_line="19" start_column="9" end_line="19" end_column="10" />
                      <range source_id="0" covered="yes" start_line="20" start_column="13" end_line="20" end_column="23" />
                      <range source_id="0" covered="no" start_line="21" start_column="17" end_line="21" end_column="26" />
                      <range source_id="0" covered="yes" start_line="22" start_column="13" end_line="22" end_column="27" />
                      <range source_id="0" covered="yes" start_line="23" start_column="9" end_line="23" end_column="10" />
                    </ranges>
                  </function>
                </functions>
                <source_files>
                  <source_file id="0" path="D:1UTBizLogicCalc.cs">
                  </source_file>
                </source_files>
              </module>
            </modules>
          </results>
    4. 只计算指定dll的覆盖率:

      默认情况下,vstest会把指定dll目录下的所有有pdb文件的dll都计算一遍覆盖率。

      这样就会掺杂进去我们不关心的基础dll、第三方dll,导致计算时间长、总覆盖率不准确。

      因此,我们需要指定我们想要计算覆盖率的dll,或者排除掉我们不关心的dll。

      方法是,在CodeCoverage命令上,指定config文件,在config文件中,排除掉指定dll、或只计算特定dll。支持正则表达式。。

      排除包含Foundation的dll

      <ModulePaths>
        <Exclude>
          <ModulePath>.*Foundation.*</ModulePath>
        </Exclude>
      </ModulePaths>

      配置文件的模板,不要用微软官方给的,要到CodeCoverage.exe目录下找配置,复制过来。目录: C:Program Files (x86)Microsoft Visual Studio2017EnterpriseTeam ToolsDynamic Code Coverage Tools

    5. 常见问题:

      1. 有的VisualStudio 2017 环境下,命令行生成的报告显示“生成了空结果: 未检测任何二进制文件。请确保测试已运行,所需二进制文件已加载,具有匹配的符号文件,并且未通过自定义设置排除”。

        这个问题是由于VisualStudio2017的bug,不要纠结。升级你的VS版本就好。
        https://developercommunity.visualstudio.com/content/problem/97029/code-coverage-not-working-in-153.html?childToView=124999#comment-124999
  • 相关阅读:
    OpenGL------光照+染色
    sicily 1345 能量项链
    sicily 1193 Up the Stairs
    sicily 1172 Queens, Knights and Pawns
    sicily 1206 Stacking Cylinders
    模拟退火算法解tsp问题
    js对象的属性可以是一个变量
    vue中/deep/的使用
    MySQL中DATEDIFF函数使用
    js中的this
  • 原文地址:https://www.cnblogs.com/cc299/p/12131924.html
Copyright © 2011-2022 走看看