`
bingtears
  • 浏览: 185185 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

【ZZ】创建并运行单元测试

阅读更多
演练:创建并运行单元测试
Visual Studio 2010
其他版本

    * Visual Studio 2008
    * Visual Studio 2005

本演练将逐步指导您使用 Microsoft Visual Studio 2010 来创建、运行和自定义一系列测试。 您将从正处于开发过程中的 C# 项目开始,创建执行该项目代码的测试,运行测试并检查结果。 然后,可以更改项目代码并重新运行测试。
说明 说明

有关如何从命令行运行测试的信息,请参见演练:使用命令行测试实用工具。

在本演练中,您将完成以下任务:

    *

      准备一个要在演练中使用的“银行帐户”项目。
    *

      打开一个现有项目。
    *

      为公共和私有方法创建单元测试。
    *

      对代码运行这些测试。
    *

      在测试中查找错误并进行更正。
    *

      在代码中查找错误并进行更正。

系统必备

    *

      Woodgrove Bank 项目。 请参见用于创建单元测试的示例项目。

准备演练
准备演练

   1.

      打开 Visual Studio 2010 高级版。
   2.

      在“文件”菜单上指向“新建”,然后单击“项目”。

      此时将出现“新建项目”对话框。
   3.

      在“已安装的模板”下单击“Visual C#”。
   4.

      在应用程序类型的列表中单击“类库”。
   5.

      在“名称”框中键入 Bank,然后单击“确定”。
      说明 说明

      如果名称“Bank”已被使用,请为该项目选择其他名称。

      将创建新的 Bank 项目并将其显示在解决方案资源管理器中,而且将在代码编辑器中打开 Class1.cs 文件。
      说明 说明

      如果代码编辑器中未打开 Class1.cs 文件,请在解决方案资源管理器中双击文件 Class1.cs 将其打开。
   6.

      从用于创建单元测试的示例项目中复制源代码。
   7.

      用用于创建单元测试的示例项目中的代码替换 Class1.cs 的原始内容。
   8.

      在“生成”菜单上,单击“生成解决方案”。

现在您有一个名为“Bank”的项目。 它包含要测试的源代码和用于对该源代码进行测试的工具。 Bank 的命名空间“BankAccountNS”包含公共类“BankAccount”,在以下过程中将对该类的方法进行测试。
创建单元测试

系统必备:按照准备演练过程中的步骤执行操作。
创建单元测试

   1.

      如果代码编辑器中未打开 Class1.cs 文件,请在解决方案资源管理器中双击 Bank 项目中的 Class1.cs 文件。
   2.

      在 Class1.cs 文件的“BankAccount”类中,滚动到“Debit()”方法。
   3.

      右击“Debit()”方法,然后选择“创建单元测试”。

      将显示“创建单元测试”对话框。

      在“当前选择”下,树结构将显示保存“BankAccount”类的程序集的类和成员层次结构。 使用此页可以为选定的任何成员生成单元测试,并可以选择要在其中放置生成的单元测试的测试项目。

      在该树结构中,只选择了“Debit()”方法。 将其保留选定状态并选择“Credit()”方法。
   4.

      对于“输出项目”,请选择“创建新的 Visual C# 测试项目”。
   5.

      单击“设置”。

      随即出现“测试生成设置”对话框。 在“命名设置”下,可以更改测试文件、测试类和测试方法在生成时的命名方式。 在“常规”下,可以更改测试生成的其他方面。 将这些设置保留为默认值,然后单击“确定”。
   6.

      在“创建单元测试”对话框中单击“确定”。

      随即出现“新建测试项目”对话框。
   7.

      接受默认名称,然后单击“创建”。

      这将创建一个名为 TestProject1 的项目,该项目将显示在解决方案资源管理器中。

      一个名为 BankAccountTest.cs 的文件添加到 TestProject1 中,该文件包含一个测试类。 该类中填充有一个 TestContext 属性以及测试“Debit()”和“Credit()”方法的方法。
      说明 说明

      将自动为每个测试方法分配“TestMethod()”特性。 每个测试都与要测试的测试代码中的一个方法相对应。 测试方法保存在已分配“TestClass()”特性的测试类中。
   8.

      在 BankAccountTest.cs 中,指定要测试的变量的值。 滚动到“DebitTest”方法,在此可以看到 // TODO 行,它们指示要设置的变量。
   9.

      若要了解 DebitTest 方法将使用哪些值,请打开 Class1.cs 文件并滚动到“Main”方法。 请注意,客户名称初始化为“Mr. Bryan Walton”, 帐户余额初始化为“11.99”,调用“Credit”方法时使用参数“5.77”,调用“Debit”方法时使用参数“11.22”。 因此,如果此帐户开始时“Balance”为“11.99”,则在传递“11.22”时调用“Debit”方法应生成新“Balance”值“0.77”。
      说明 说明

      在本演练后面的部分中,您将使用此预期的“Balance”值 (0.77)。
  10.

      在 BankAccountTest.cs 文件中,滚动到“DebitTest”方法。
  11.

      设置下列值:
      复制

      BankAccount target = new BankAccount("Mr.Bryan Walton", 11.99);
      double amount = 11.22;

  12.

      在“CreditTest”方法中,将“Mr. Bryan Walton”和 11.99 添加到新的 BankAccount 中。
  13.

      保存 BankAccountTest.cs 文件。

您已创建了一个源代码文件,其中包含 Bank 项目的测试。 现在可以对 Bank 项目的代码运行“BankAccountTest”类中的测试了。
运行和自定义单元测试

系统必备:执行创建单元测试过程中的步骤。
运行和自定义单元测试

   1.

      在“测试”菜单上,单击“窗口”,然后选择“测试视图”。

      将显示“测试视图”窗口。
   2.

      右击“DebitTest”,再单击“运行选定内容”。

      如果“测试结果”窗口尚未打开,则它现在将打开。 “DebitTest”测试运行。

      在“测试结果”窗口的“结果”列中,当测试运行时,测试状态将显示为“正在运行”。 测试运行完成后,测试的结果将更改为“没有结论”。
   3.

      在“测试结果”窗口中右击表示测试的行,然后单击“查看测试结果详细信息”。
   4.

      在“测试结果详细信息”页中,将显示错误消息“Assert.Inconclusive 失败。 无法验证不返回值的方法。”若要创建成功的测试,请先查找并评估此“Assert”语句。
   5.

      若要查找包含“Assert”语句的测试方法,请打开 BankAccountTest.cs 文件并滚动到“DebitTest()”方法。
   6.

      Assert 语句是“DebitTest”方法中的最后一行。 它显示如下内容:
      复制

      Assert.Inconclusive("A method that does not return a value cannot be verified.");

      注释掉此 Assert 语句。
   7.

      如果现在运行测试,则会得出“已通过”结果,但这仅仅是因为它没有对任何内容进行测试。 必须添加对预期的结果进行测试的代码。 向“DebitTest”方法的末尾添加以下语句:
      复制

      Assert.AreEqual((System.Convert.ToDouble(0.77)), target.Balance, 0.05);

      此语句将预期结果 (0.77) 与调用“BankAccount”类的“Balance”方法所产生的实际结果进行比较。 如果两个值不相等,则“Assert”返回“False”,从而使测试失败。
      说明 说明

      此“Assert”语句还包括第三个参数“delta”,其值为 0.05。 在“Assert.AreEqual”方法的此重载中需要该 delta 参数;它可以补偿“Doubles”等浮点型所固有的舍入错误。

您已运行了“BankAccountTest”测试类的生成的“DebitTest”方法,注意它需要做的更改,请就此做出这些更改。 现在,可以测试您应用程序中“Debit”方法的精确性。
运行单元测试并修复代码

系统必备:执行运行和自定义单元测试过程中的步骤。
运行单元测试并修复代码

   1.

      再次运行 Debit 测试:在文件 BankAccountTest.cs 中,右击“DebitTest()”方法,然后单击“运行测试”。

      在“测试结果”窗口的“结果”列中,当测试运行时,测试状态将显示为“正在运行”。 测试运行完成后,测试的结果将更改为“未通过”。
   2.

      在“测试结果”窗口中右击表示测试的行,然后单击“查看测试结果详细信息”。

      这将打开“测试结果详细信息”页,其中显示以下错误消息:“Assert.AreEqual 失败。 预期值 <0.77> 和实际值 <23.21> 之间的差不应大于 <0.05>”。 这些数字似乎表明数学运算不正确。 由于“BankAccountTest”类的“DebitTest”方法测试“BankAccount”类的“Debit”方法,所以从检查“Debit”方法开始。
   3.

      打开 Class1.cs 文件并滚动到“Debit”方法。
   4.

      请注意以下赋值:
      复制

      m_balance += amount;

      此赋值向余额增加金额,在“Debit”方法中,应当减去赋值。 将此行更改为:
      复制

      m_balance -= amount;

   5.

      再次运行“Debit”测试。

      在“测试结果”窗口的“结果”列中,将为“DebitTest”显示“已通过”。
      说明 说明

      更改源代码后不必重新生成测试项目,因为运行测试时会生成项目而不进行提示。

您创建了一个可以运行的单元测试,并通过它查找和修复了代码中的错误。
为私有方法创建和运行单元测试

系统必备:执行运行单元测试并修复代码过程中的步骤。
为私有方法创建和运行单元测试

   1.

      打开 Bank 项目中的 Class1.cs 文件。
   2.

      右击“FreezeAccount()”方法,然后选择“创建单元测试”。

      随即出现“创建单元测试”对话框。

      在显示的树结构中,只有“FreezeAccount()”方法处于选定状态。
   3.

      (可选)单击“筛选器”,然后清除“显示非公共项”。 注意,“FreezeAccount()”方法已从 BankAccount 类的子方法列表中移除。 再次单击“筛选器”,然后选择“显示非公共项”以重新显示“FreezeAccount()”方法。
   4.

      确保“FreezeAccount()”方法处于选中状态,然后单击“确定”。

      此时将新建一个名为 Bank.accessor 的专用访问器文件。 该文件中包含特殊的访问器方法,测试使用这些方法间接调用 BankAccount 类中的私有方法。 在解决方案资源管理器的“测试引用”文件夹中可以看到这个新文件。
   5.

      打开 BankAccountTest.cs 文件并滚动到“FreezeAccountTest()”方法。
   6.

      更改“FreezeAccountTest()”方法的代码,使其与下面所示的代码一致。 更改过的区域或新区域有相应的指示:
      复制

      public void FreezeAccountTest()
      {
          BankAccount_Accessor target = new BankAccount_Accessor("Mr.Bryan Walton", 11.99); // TODO: Initialize to an appropriate value
      target.FreezeAccount();
          // Assert.Inconclusive("A method that does not return a value cannot be verified.");        bool creditAccount = false; // False means account could be credited: Fail test.     // Try to credit account    try    {        target.Credit(1.00);     }    catch (System.Exception)    {// Threw exception.FreezeAccount worked correctly: Pass test.        creditAccount = true;    }    // Assert fails if 'creditAccount' condition is false.Fail test.    Assert.IsTrue(creditAccount, "Was able to credit account.");
      }

   7.

      运行“FreezeAccountTest”测试。

      在“测试结果”窗口的“结果”列中,最终测试状态显示为“已通过”。 该结果与预期结果一致,原因是测试在调用“FreezeAccount()”方法冻结帐户之后调用了“Credit()”方法。

您已经添加了一个私有方法,为其创建了新的单元测试并运行了该测试。 可以对 balance 变量使用其他边界值(如 15.00)来多次运行该测试。
后续步骤

对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分。 有关更多信息,请参见演练:运行测试并查看代码覆盖率。

可以在命令行中(而不是在 Visual Studio 中)运行测试。 有关更多信息,请参见演练:使用命令行测试实用工具。

如果正在使用 Visual Studio 2010 旗舰版,则可以使用单元测试创建负载测试以隔离压力和性能问题。

Walkthrough: Creating and Running a Load Test Containing Unit Tests
此处提供的是该示例的最新代码:
复制

using System;

namespace BankAccountNS
{
    /// <summary>
    /// Bank Account demo class./// </summary>
    public class BankAccount
    {
        private string m_customerName;

        private double m_balance;

        private bool m_frozen = false;

        private BankAccount()
        {
        }

        public BankAccount(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;
        }

        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()
        {
            BankAccount ba = new BankAccount("Mr.Bryan Walton", 11.99);

            ba.Credit(5.77);
            ba.Debit(11.22);
            Console.WriteLine("Current balance is ${0}", ba.Balance);
        }

    }
}

/* 此处描述的示例公司、组织、产品、域名、电子邮件地址、徽标、人物、地点和事件都是虚构的, 无意与任何真实的公司、组织、产品、域名、电子邮件地址、徽标、人物、地点或事件相关联,也不应进行这方面的推断。 */
使用代码

若要使用这些代码,您必须首先在 Visual Studio 中为其创建一个项目。 按照演练:创建并运行单元测试中“准备演练”部分所述的步骤进行操作。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics