在計(jì)算機(jī)編程中,單元測試是一種軟件測試方法,通過這種方法對各個(gè)源代碼單元進(jìn)行測試,以確定它們是否適合使用。 換句話說,這是一個(gè)軟件開發(fā)過程,在這個(gè)過程中,應(yīng)用程序中最小的可測試部分(稱為單元)被單獨(dú)和獨(dú)立地審查以便正確執(zhí)行和操作。
在程序編程中,一個(gè)單元可以是一個(gè)完整的模塊,但更常見的是一個(gè)單獨(dú)的功能或過程。 在面向?qū)ο缶幊讨?,一個(gè)單元通常是一個(gè)完整的接口,比如一個(gè)類,但可能是一個(gè)單獨(dú)的方法。
單元測試通常是自動(dòng)的,但也可以手動(dòng)完成。
單元測試的主要目標(biāo)是在應(yīng)用程序中使用最小的可測試軟件,并確定其行為是否與期望的完全一致。每個(gè)單元在將它們集成到模塊之前分別進(jìn)行測試,以測試模塊之間的接口。
我們來看一個(gè)單元測試的簡單例子,在這個(gè)例子中使用單元測試選項(xiàng)來創(chuàng)建一個(gè)新的ASP.NET MVC應(yīng)用程序。
第1步 - 打開Visual Studio,然后單擊:文件 -> 新建 -> 項(xiàng)目 菜單選項(xiàng)。一個(gè)新的項(xiàng)目對話框打開。
第2步 - 在左側(cè)窗格中,選擇:模板 -> Visual C# -> Web 。
第3步 - 在中間窗格中,選擇:ASP.NET Web應(yīng)用程序。
第4步 - 在名稱字段中輸入項(xiàng)目名稱為:MVCUnitTesting,然后單擊確定 繼續(xù)。
然后將看到下面的對話框,要求設(shè)置ASP.NET項(xiàng)目的初始內(nèi)容。
第5步 - 選擇MVC作為模板,不要忘記選中對話框底部的添加單元測試復(fù)選框。也可以更改測試項(xiàng)目名稱,但在此示例中,我們將其保持原樣,因?yàn)樗悄J(rèn)名稱。
項(xiàng)目由Visual Studio創(chuàng)建后,將在“解決方案資源管理器”窗口中看到許多文件和文件夾。
第6步 - 可以看到在解決方案資源管理器中有兩個(gè)項(xiàng)目。 一個(gè)是ASP.NET Web項(xiàng)目,另一個(gè)是單元測試項(xiàng)目。
第7步 - 運(yùn)行這個(gè)應(yīng)用程序,會(huì)看到下面的輸出。
如上圖所示,導(dǎo)航欄上有“首頁”,“關(guān)于”和“聯(lián)系人”按鈕。這里點(diǎn)擊“關(guān)于”鏈接,會(huì)看到下面的視圖。
現(xiàn)在展開MVCUnitTestingDemo 項(xiàng)目,將看到 Controllers 文件夾下的HomeController.cs 文件。
HomeController 包含三個(gè)操作方法,如下面的代碼所示。
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 項(xiàng)目,Controllers文件夾下的HomeControllerTest.cs文件。
在這個(gè)HomeControllerTest類中有三個(gè)方法,如下面的代碼所示。
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);
}
}
}
這三個(gè)方法將測試Index,About和Contact操作方法是否正常工作。要測試這三個(gè)操作方法,請轉(zhuǎn)到測試 菜單。選擇:運(yùn)行 -> 所有測試 項(xiàng)來測試這些操作方法。
現(xiàn)在會(huì)看到左邊的測試資源管理器,可以看到所有的測試都通過了。再添加一個(gè)動(dòng)作方法,它用于列出所有的員工。首先,需要在Models 文件夾中添加一個(gè)Employee類。
以下是Employee類的實(shí)現(xiàn) -
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控制器 - 空 選項(xiàng),然后點(diǎn)擊“添加” 按鈕,如下圖所示 -
添加控制器對話框?qū)⒊霈F(xiàn)。將名稱設(shè)置為:EmployeeController,然后單擊“添加”按鈕。
在Controllers 文件夾中看到一個(gè)新的 C# 文件 - EmployeeController.cs,該文件夾在Visual Studio中打開并進(jìn)行編輯。這里使用下面的代碼更新 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方法并選擇:添加視圖…
您將看到視圖的默認(rèn)名稱。從“模板”下拉列表中選擇“List”,從“模型類”下拉列表中選擇“Employee”,然后單擊“確定”。
現(xiàn)在需要添加一個(gè)鏈接到Employees列表,打開Views/Shared 文件夾下的_layout.cshtml 文件,并在聯(lián)系人 鏈接下面添加員工列表 鏈接。
<li>@Html.ActionLink("員工列表", "Employees", "Employee")</li>
以下是_layout.cshtml 的完整實(shí)現(xiàn) -
<!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 應(yīng)用程序</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("應(yīng)用程序名稱", "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("關(guān)于", "About", "Home")</li>
<li>@Html.ActionLink("聯(lián)系方式", "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 應(yīng)用程序</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
要從Employee控制器測試Employees動(dòng)作方法,需要在單元測試項(xiàng)目中添加另一個(gè)測試方法。在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);
}
}
}
從測試 菜單中選擇:運(yùn)行 -> 所有測試 項(xiàng)來測試這些操作方法。
可以看到Employees測試方法現(xiàn)在也通過了。運(yùn)行應(yīng)用程序時(shí)將看到以下輸出。
點(diǎn)擊導(dǎo)航欄中的“員工列表”選項(xiàng),將看到員工列表信息,如下圖所示 -