软件工程(2019)第二次作业

0.什么是单元测试

单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。

比如对函数abs(),我们可以编写出以下几个测试用例:

  1. 输入正数,比如11.20.99,期待返回值与输入相同;

  2. 输入负数,比如-1-1.2-0.99,期待返回值与输入相反;

  3. 输入0,期待返回0

  4. 输入非数值类型,比如None[]{},期待抛出TypeError

把上面的测试用例放到一个测试模块里,就是一个完整的单元测试。

如果单元测试通过,说明我们测试的这个函数能够正常工作。如果单元测试不通过,要么函数有bug,要么测试条件输入不正确,总之,需要修复使单元测试能够通过。

单元测试通过后有什么意义呢?如果我们对abs()函数代码做了修改,只需要再跑一遍单元测试,如果通过,说明我们的修改不会对abs()函数原有的行为造成影响,如果测试不通过,说明我们的修改与原有行为不一致,要么修改代码,要么修改测试。

 

这种以测试为驱动的开发模式最大的好处就是确保一个程序模块的行为符合我们设计的测试用例。在将来修改的时候,可以极大程度地保证该模块行为仍然是正确的。

以上来自廖雪峰的官方网站

也可以看一下其他的定义:

百度百科的单元测试定义 知乎的一些关于单元测试的回答 

1.开发工具

Visual Studio 2017 社区版 +AxoCover插件

注:因为社区版不提供代码覆盖率的功能,使用VSMarket的AxoCover 插件进行了补全

插件下载地址如下:

https://github.com/axodox/AxoCover

https://marketplace.visualstudio.com/items?itemName=axodox1.AxoCover

或者直接在VS插件与扩展选项里搜索AxoCover下载重启即可

 

其他的选择:

和AxoCover一样,NCrunch也是一款提供代码覆盖率的插件

NCrunch

至于使用哪个可以自行决定,使用说明请看官方文档

 

吐槽:本来找了一个叫OpenCover的插件,但是官方支持只适用到VS2015,VS2015的小伙伴可以用这个。

它的github和VS marketplace如下:

OpenCover.UI

marketplace.OpenCoverUI

 

 

参考文章1:https://www.cnblogs.com/SivilTaram/p/vs_opencover_unit_coverage.html

虽然插件不同,但是基本步骤是一样的

微软官方文档

2. 练习自动单元测试技术

参考文章:现代软件工程讲义 2 开发技术 - 单元测试 & 回归测试

1.创建C#的类库(Class Library

文件->新建->项目

在VS里创建C#类库

 

 

2.在创建的C#文件里编写代码

如图所示:

 

代码如下:

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace ClassLibrary1
 8 {
 9     public class User
10 
11     {
12         public User(string userEmail)
13 
14         {
15             m_email = userEmail;
16         }
17 
18         private string m_email; //user email as user id
19 
20     }
21 }

3.创建单元测试:

右键选中User创建单元测试。

 

 可以看到资源管理器生成了如下所示的项目:

4.修改单元测试UserTests.cs里的代码:

代码如下:

 1 using Microsoft.VisualStudio.TestTools.UnitTesting;
 2 using ClassLibrary1;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace ClassLibrary1.Tests
10 {
11     [TestClass()]
12     public class UserTests
13     {   
14         [TestMethod()]
15         public void UserTest()
16         {
17             string userEmail = "someone@somewhere.com";
18         
19             User target = new User(userEmail);
20 
21             Assert.IsTrue(target != null);
22         }
23 
24     }
25 
26 }

5.运行单元测试,测试结果如下

 

 

可以看到测试通过以及100%的代码覆盖率

导出测试报告如下所示:

 

当然这样的测试远远不够,考虑周全,我们还需要增加一些测试方法

 

6.增加测试方法

完整代码如下所示,在第4步的基础上增加了3个方法:

 1 using Microsoft.VisualStudio.TestTools.UnitTesting;
 2 using ClassLibrary1;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace ClassLibrary1.Tests
10 {
11     [TestClass()]
12     public class UserTests
13     {   
14         [TestMethod()]//方法1
15         public void UserTest()
16         {
17             string userEmail = "someone@somewhere.com";
18         
19             User target = new User(userEmail);
20 
21             Assert.IsTrue(target != null);
22         }
23 
24         [TestMethod()]//方法2
25         [ExpectedException(typeof(ArgumentNullException))]
26         public void ConstructorTestNull()
27         {
28             User target = new User(null);
29         }
30 
31         [TestMethod()]//方法3
32         [ExpectedException(typeof(ArgumentException))]
33         public void ConstructorTestEmpty()
34         {
35             User target = new User("");
36         }
37 
38         [TestMethod()]//方法4
39         [ExpectedException(typeof(ArgumentNullException))]
40         public void ConstructorTestBlank()
41         {
42             User target = new User("     ");
43         }
44     }
45 }

 

测试结果会和参考文章所说的一样报错:

 

和参考所说的一样在Class1.cs里增加几行代码,完整代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class User
    {
        public User(string userEmail)
        {
            m_email = userEmail;
            if (!m_email.Contains("@"))
            
            {
                throw new ArgumentException();
            }
        }
        private string m_email; //user email as user id
    }
}

7.运行结果

 

可以看到覆盖率为85.71%,基本和参考文章的一样

posted @ 2019-04-13 10:51  molers  阅读(226)  评论(0编辑  收藏  举报
Live2D