关于单元测试
单元测试是自动测试,用于验证组件级别、类级别、方法级别或属性级别的功能。单元测试是自动测试和回归测试的基础,可提供项目的长期稳定性和未来可维护性。
每个编写代码的团队成员都应为所生成的组件创建单元测试,并将单元测试代码签入到 Visual Studio 项目内的版本控制中。将测试用例工作项归档到在每次生成过程中通过持续集成而运行的版本测试验证套件中,并归档到验证对应用户情景的测试套件中。
Visual Studio 专业测试工具版 2010 提供了用于编写数据驱动的单元测试和编码的 UI 测试的功能。
所有用于单元测试的类和函数都定义在Microsoft.VisualStudio.TestTools.UnitTesting命名空间中。
MSDN有很多单元测试参考资料。比如:msdn.microsoft/zh-cn/library/ms379625(v=VS.80).aspx


一个完整的类方法级单元测试示例
1、 如下图所示,创建一个新项目
2、 项目创建好后,IDE环境如下图所示
3、 将Class1.cs中的代码更改为如下示例代码。其中,为方法Debit设置了一个错误,后续的单元测试就是要检测出该错误。
using System;
namespaceBankAccountNS
{
    /// Bank Account demo class.
public class BankAccount
    {
private string m_customerName;
private double m_balance;
privateboolm_frozen = false;
privateBankAccount()
        {
        }
publicBankAccount(string customerName, double balance)
        {
m_customerName = customerName;
m_balance = balance;
        }
public string CustomerName
        {
get { return m_customerName; }
        }
public double Balance
        {
get { return m_balance; }
        }
public void Debit(double amount)
        {
if (m_frozen)
            {
throw new Exception("Account frozen");
            }
if (amount >m_balance)
            {
throw new ArgumentOutOfRangeException("amount");
            }
if (amount < 0)
            {
throw new ArgumentOutOfRangeException("amount");
            }
m_balance += amount;
            //故意设置的错误,正确代码应为:m_balance -= amount;
        }
public void Credit(double amount)
        {
if (m_frozen)
            {
throw new Exception("Account frozen");
            }
if (amount < 0)
            {
throw new ArgumentOutOfRangeException("amount");
            }
m_balance += amount;
        }
private void FreezeAccount()
        {
m_frozen = true;
        }
private void UnfreezeAccount()
        {
m_frozen = false;
        }
public static void Main()
        {
BankAccountba = new BankAccount("Mr. Bryan Walton", 11.99);
ba.Credit(5.77);
ba.Debit(11.22);
Console.WriteLine("Current balance is ${0}", ba.Balance);
        }
bank文件    }
}
4、 在“生成”菜单上,单击“生成解决方案”。
现在有一个名为“Bank”的项目。它包含要测试的源代码和用于对该源代码进行测试的工具。
Bank 的命名空间“BankAccountNS”包含公共类“BankAccount”,在以下步骤中将对该类的方法进行测试。
5、 在解决方案资源管理器中双击 Bank 项目中的 Class1.cs 文件
6、 在 Class1.cs 文件的“BankAccount”类中,滚动到“Debit()”方法。
7、 右击“Debit()”方法,然后选择“创建单元测试”。
将显示“创建单元测试”对话框。在“当前选择”下,树结构将显示保存“BankAccount”类的程序集的类和成员层次结构。使用此页可以为选定的任何成员生成单元测试,并可以选择要在其中放置生成的单元测试的测试项目。
在该树结构中,只选择了“Debit()”方法。将其保留选定状态并选择“Credit()”方法。
8、 对于“输出项目”,请选择“创建新的 Visual C# 测试项目”。7、8完成后界面如下所示:
单击“设置”。随即出现“测试生成设置”对话框。
在“命名设置”下,可以更改测试文件、测试类和测试方法在生成时的命名方式。
在“常规”下,可以更改测试生成的其他方面。将这些设置保留为默认值,然后单击“确定”。“常规”选项的说明如下:
“默认情况下将所有测试结果标记为没有结论”:选中该复选框可为每个测试方法提供 Assert.Inconclusive() 语句作为占位符 Assert。清除该复选框可消除占位符 Assert
“启用生成警告”:在测试函数创建中如果遇到任何的错误,代码生成器会将这些错误信息以注释的形式写在生成的代码中。
“全局限定所有类型”:这个选项是用来解决多个类可能有相同名字的函数问题,单元测试文件可能包含有多个类的测试函数,所以有可能会有同名的冲突,所以为了区分开同名的函数,会在测试命名中添加namespaces
“启用文档注释”:选中此复选框可为每个测试方法提供占位符注释。清除该复选框可消除占位符注释。
“允许InternalsVisibleTo特性”:选中该复选框可使标为 Friend Internal 的方法被视为公共方法(推荐)。清除该复选框则需要使用专用访问器测试这些方法。
9、 在“创建单元测试”对话框中单击“确定”。随即出现“新建测试项目”对话框。
10、 接受默认名称,然后单击“创建”。
这将创建一个名为 TestProject1 的项目,该项目将显示在解决方案资源管理器中。一个名为 BankAccountTest.cs 的文件添加到 TestProject1 中,该文件包含一个测试类。该类中填充有一个 TestContext 属性以及测试“Debit()”和“Credit()”方法的方法。 完成如上操作,界面如下所示:
将自动为每个测试方法分配“TestMethod()”特性。每个测试都与要测试的测试代码中的一个方法相对应。测试方法保存在已分配“TestClass()”特性的测试类中。
11、 在 BankAccountTest.cs 中,指定要测试的变量的值。滚动到“DebitTest”方法,在此可以看到// TODO 行,它们指示要设置的变量。
12、 若要了解 DebitTest 方法将使用哪些值,请打开 Class1.cs 文件并滚动到“Main”方法。请注意,客户名称初始化为“Mr. Bryan Walton”,帐户余额初始化为“11.99”,调用“Credit”方法时使用参数“5.77”,调用“Debit”方法时使用参数“11.22”。因此,如果此帐户开始时“Balance”为“11.99”,则在传递“11.22”时调用“Debit”方法应生成新“Balance”值“0.77”。
13、 在 BankAccountTest.cs 文件中,滚动到“DebitTest”方法。
14、 将代码
BankAccount target = new BankAccount(); // TODO: 初始化为适当的值
double amount = 0F; // TODO: 初始化为适当的值
修改为:
BankAccount target = new BankAccount("Mr. Bryan Walton", 11.99);
double amount = 11.22;
15、 在“CreditTest”方法中,如14所示,将“Mr.Bryan Walton”和 11.99 添加到新的 BankAccount 中。
16、 保存 BankAccountTest.cs 文件。
17、 在“测试”菜单上,单击“窗口”,然后选择“测试视图”。将显示“测试视图”窗口。操作完毕,测试视图如下所示:
18、 右击“DebitTest”,再单击“运行选定内容”。
在“测试结果”窗口的“结果”列中,当测试运行时,测试状态将显示为“正在运行”。测试运行完成后,测试的结果将更改为“没有结论”。
19、 如下图,在“测试结果”窗口中右击表示测试的行,然后单击“查看测试结果详细信息”。
20、 在“测试结果详细信息”页中,将显示错误消息“Assert.Inconclusive 失败。无法验证不返回值的方法。”若要创建成功的测试,请先查并评估此“Assert”语句。