在计算机编程中,单元测试是一种软件测试方法,通过这种方法对各个源代码单元进行测试,以确定它们是否适合使用。 换句话说,这是一个软件开发过程,在这个过程中,应用程序中最小的可测试部分(称为单元)被单独和独立地审查以便正确执行和操作。
在程序编程中,一个单元可以是一个完整的模块,但更常见的是一个单独的功能或过程。 在面向对象编程中,一个单元通常是一个完整的接口,比如一个类,但可能是一个单独的方法。
单元测试通常是自动的,但也可以手动完成。
单元测试的主要目标是在应用程序中使用最小的可测试软件,并确定其行为是否与期望的完全一致。每个单元在将它们集成到模块之前分别进行测试,以测试模块之间的接口。
我们来看一个单元测试的简单例子,在这个例子中使用单元测试选项来创建一个新的asp.net mvc应用程序。
第1步 - 打开visual studio,然后单击:文件 -> 新建 -> 项目 菜单选项。一个新的项目对话框打开。
第2步 - 在左侧窗格中,选择:模板 -> visual c# -> web 。
第3步 - 在中间窗格中,选择:asp.net web应用程序。

第4步 - 在名称字段中输入项目名称为:mvcunittesting,然后单击确定 继续。
然后将看到下面的对话框,要求设置asp.net项目的初始内容。
第5步 - 选择mvc作为模板,不要忘记选中对话框底部的添加单元测试复选框。也可以更改测试项目名称,但在此示例中,我们将其保持原样,因为它是默认名称。

项目由visual studio创建后,将在“解决方案资源管理器”窗口中看到许多文件和文件夹。
第6步 - 可以看到在解决方案资源管理器中有两个项目。 一个是asp.net web项目,另一个是单元测试项目。

第7步 - 运行这个应用程序,会看到下面的输出。

如上图所示,导航栏上有“首页”,“关于”和“联系人”按钮。这里点击“关于”链接,会看到下面的视图。

现在展开mvcunittestingdemo 项目,将看到 controllers 文件夹下的homecontroller.cs 文件。

homecontroller 包含三个操作方法,如下面的代码所示。
using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.mvc;
namespace mvcunittesting.controllers
{
public class homecontroller : controller
{
public actionresult index()
{
return view();
}
public actionresult about()
{
viewbag.message = "your application description page.";
return view();
}
public actionresult contact()
{
viewbag.message = "your contact page.";
return view();
}
}
}
展开mvcunittestingdemo.tests 项目,controllers文件夹下的homecontrollertest.cs文件。

在这个homecontrollertest类中有三个方法,如下面的代码所示。
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.web.mvc;
using microsoft.visualstudio.testtools.unittesting;
using mvcunittesting;
using mvcunittesting.controllers;
namespace mvcunittesting.tests.controllers
{
[testclass]
public class homecontrollertest
{
[testmethod]
public void index()
{
// arrange
homecontroller controller = new homecontroller();
// act
viewresult result = controller.index() as viewresult;
// assert
assert.isnotnull(result);
}
[testmethod]
public void about()
{
// arrange
homecontroller controller = new homecontroller();
// act
viewresult result = controller.about() as viewresult;
// assert
assert.areequal("your application description page.", result.viewbag.message);
}
[testmethod]
public void contact()
{
// arrange
homecontroller controller = new homecontroller();
// act
viewresult result = controller.contact() as viewresult;
// assert
assert.isnotnull(result);
}
}
}
这三个方法将测试index,about和contact操作方法是否正常工作。要测试这三个操作方法,请转到测试 菜单。选择:运行 -> 所有测试 项来测试这些操作方法。

现在会看到左边的测试资源管理器,可以看到所有的测试都通过了。再添加一个动作方法,它用于列出所有的员工。首先,需要在models 文件夹中添加一个employee类。
以下是employee类的实现 -
using system;
using system.collections.generic;
using system.linq;
using system.web;
namespace mvcunittesting.models
{
public class employee
{
public int id { get; set; }
public string name { get; set; }
public datetime joiningdate { get; set; }
public int age { get; set; }
}
}
添加employeecontroller 。 右键单击解决方案资源管理器 中的controllers 文件夹,然后选择:添加 -> 控制器 ,它将显示“添加基架”对话框。选择:mvc 5控制器 - 空 选项,然后点击“添加” 按钮,如下图所示 -

添加控制器对话框将出现。将名称设置为:employeecontroller,然后单击“添加”按钮。

在controllers 文件夹中看到一个新的 c# 文件 -employeecontroller.cs,该文件夹在visual studio中打开并进行编辑。这里使用下面的代码更新employeecontroller。
using mvcunittesting.models;
using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.mvc;
namespace mvcunittesting.controllers
{
public class employeecontroller : controller
{
[nonaction]
public list<employee> getemployeelist()
{
return new list<employee>{
new employee{
id = 1,
name = "maxsu",
joiningdate = datetime.parse(datetime.today.tostring()),
age = 23
},
new employee{
id = 2,
name = "carson",
joiningdate = datetime.parse(datetime.today.tostring()),
age = 45
},
new employee{
id = 3,
name = "kobe bryant",
joiningdate = datetime.parse(datetime.today.tostring()),
age = 37
},
new employee{
id = 4,
name = "laura",
joiningdate = datetime.parse(datetime.today.tostring()),
age = 26
},
};
}
// get: employee
public actionresult index()
{
return view();
}
public actionresult employees()
{
var employees = from e in getemployeelist()
orderby e.id
select e;
return view(employees);
}
}
}
要为employee操作方法添加视图,请右键单击employees方法并选择:添加视图…

您将看到视图的默认名称。从“模板”下拉列表中选择“list”,从“模型类”下拉列表中选择“employee”,然后单击“确定”。
现在需要添加一个链接到employees列表,打开views/shared 文件夹下的_layout.cshtml 文件,并在联系人 链接下面添加员工列表 链接。
<li>@html.actionlink("员工列表", "employees", "employee")</li>
以下是_layout.cshtml 的完整实现 -
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@viewbag.title - 我的 asp.net 应用程序</title>
@styles.render("~/content/css")
@scripts.render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@html.actionlink("应用程序名称", "index", "home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@html.actionlink("主页", "index", "home")</li>
<li>@html.actionlink("关于", "about", "home")</li>
<li>@html.actionlink("联系方式", "contact", "home")</li>
<li>@html.actionlink("员工列表", "employees", "employee")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@renderbody()
<hr />
<footer>
<p>© @datetime.now.year - 我的 asp.net 应用程序</p>
</footer>
</div>
@scripts.render("~/bundles/jquery")
@scripts.render("~/bundles/bootstrap")
@rendersection("scripts", required: false)
</body>
</html>
要从employee控制器测试employees动作方法,需要在单元测试项目中添加另一个测试方法。在homecontrollertest.cs文件中的employeecontrollertest类代码之后,如下所示 -
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.web.mvc;
using microsoft.visualstudio.testtools.unittesting;
using mvcunittesting;
using mvcunittesting.controllers;
namespace mvcunittesting.tests.controllers
{
[testclass]
public class homecontrollertest
{
[testmethod]
public void index()
{
// arrange
homecontroller controller = new homecontroller();
// act
viewresult result = controller.index() as viewresult;
// assert
assert.isnotnull(result);
}
[testmethod]
public void about()
{
// arrange
homecontroller controller = new homecontroller();
// act
viewresult result = controller.about() as viewresult;
// assert
assert.areequal("your application description page.", result.viewbag.message);
}
[testmethod]
public void contact()
{
// arrange
homecontroller controller = new homecontroller();
// act
viewresult result = controller.contact() as viewresult;
// assert
assert.isnotnull(result);
}
}
[testclass]
public class employeecontrollertest
{
[testmethod]
public void employees()
{
// arrange
employeecontroller controller = new employeecontroller();
// act
viewresult result = controller.index() as viewresult;
// assert
assert.isnotnull(result);
}
}
}
从测试 菜单中选择:运行 -> 所有测试 项来测试这些操作方法。

可以看到employees测试方法现在也通过了。运行应用程序时将看到以下输出。

点击导航栏中的“员工列表”选项,将看到员工列表信息,如下图所示 -
