ALM 开发人员生活中的一天:为用户情景编写新代码

无论您是Visual Studio application lifecycle management (ALM)的新用户和Team Foundation server (TFS)? 您想知道您和您的团队如何从生成app的这些工具的最新版本的以获得最大好处?

然后逐步请需要几分钟到框架通过此指南的两个章节并遵循一天在针对和茱莉亚中,提供电缆电视和相关服务的Fabrikam纤程虚构的两个开发人员生命周期。 您将看到示例中如何使用Visual Studio和TFS检查和更新代码,挂起操作,则中断时,请求代码评审,签入的更改,并执行其他任务。

到目前为止情景

团队最近已启动 使用Visual Studio和Team Foundation server application lifecycle management的(ALM)。 这些设置它们的服务器,并且客户端,创建了积压工作,计划迭代和完成其他计划需要开始开发其app。

本章概述

针对简要检查他的积压工作并选择他现在要处理的任务。 他编写单元测试来计划开发的代码。 通常,他在1小时中运行测试若干次,逐步编写详细测试然后编写使它们传递的代码。 他与将使用方法来编写的同事通常讨论他的代码接口。

备注

本主题讨论"我的工作和代码复盖率功能只可用于 Visual Studio 高级专业版 和 Visual Studio 旗舰版。

主题内容

  • 查看私有积压工作并准备任务开始工作

  • 创建第一个单元测试

  • 创建新的代码存根

  • 运行第一个测试

  • 授予API

  • 红色,绿色,重构…

  • 代码覆盖率

  • 我们在执行?

  • 签入更改

查看私有积压工作并准备任务开始工作

*** 团队资源管理器 ***,针对打开 *** 我的工作 *** 页。 团队同意在当前冲刺(sprint)期间,,针对在Evaluate发票状态将工作,在产品积压工作中的一个称为"高速跟踪执行的最高优先级别项目。 针对确定将实现数学函数,应予执行的最高优先级别积压工作项的子任务启动。 他从拖动 *** 可用的工作项 *** 的此任务列表。*** 正在工作项并更改 *** 列表。

Hh543900.collapse_all(zh-cn,VS.110).gif查看私有积压工作和准备任务开始工作

团队导航器中的“我的工作”页上的“任务”列表

  1. 在**“团队资源管理器”**中:

    1. 如果尚未连接到您想要在其中工作的团队项目,请选择 连接到团队项目

    2. 选择 “主页”图标主页,然后选择 “我的工作”图标*** 我的工作 ***

  2. *** 我的工作 *** 页,将从 *** 可用的工作项 *** 的任务列表。*** 正在进行的工作项 *** 部分。

    还可以在 *** 可用的工作项 *** 的任务列表然后选择 *** 开始 ***

Hh543900.collapse_all(zh-cn,VS.110).gifgroup增量工作计划

针对通常在开发一系列小步骤的代码。 每个步骤不长于1小时通常采用,并且可能采用一点与十分钟。 在每个步骤,他新的单元测试中编写,并将他开发的代码,通过新的测试,以及测试他已写入。 有时他新在更改代码之前测试编写,因此,他在编写测试之前在某些情况下更改代码。 有时他重构。 他模拟提高代码,而不添加新测试。 他不更改通过的测试,除非,他认为没有正确地表示需求。

在每个小的步骤末尾,他运行所有个单元测试的代码的此区域相关。 他不会将完整步骤,直到每个测试通过。

但是,他不会检查代码添加到Team Foundation server,直到直到完成了整个任务。

针对以下小的步骤此顺序的一个大致的计划。 他知道后面的部分的具体详细信息和命令可能会更改,他工作。 这是他的初始列表此特定任务的步骤:

  1. 创建测试方法存根为,签名方法。

  2. 满足特定典型的大小写。

  3. 测试大范围。 确保该代码正确地响应各种值。

  4. 在负值时引发的异常。 正常处理不正确的参数。

  5. 代码复盖率。 确保至少80%代码通过单元执行测试。

他的一些同事编写这种在注释的规划。这些测试代码。 其他记住其计划。 针对发现编写自己的列表步骤在任务工作项的说明字段。 如果用户在应暂时必须切换到一更加急需的任务,他知道查找列出,则就可以返回到它。

创建第一个单元测试

针对通过创建单元测试开始。 他从该单元开始测试,因为他要编写使用自己新选件类代码的示例。

这是第一个单元测试来测试,因此,他创建新的单元测试项目的选件类库。 他打开 *** 新项目 *** 对话框并选择 *** visual C# ***测试然后 *** 单元测试项目 ***

“新建项目”对话框中选择的单元测试

该单元测试项目提供就可以编写自己的示例的C#文件。 在此阶段,他若要声明他的新方式调用:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Fabrikam.Math.UnitTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        // Demonstrates how to call the method.
        public void SignatureTest()
        {
            // Create an instance:
            var math = new Fabrikam.Math.LocalMath();

            // Get a value to calculate:
            double input = 0.0;

            // Call the method:
            double actualResult = math.SquareRoot(input);

            // Use the result:
            Assert.AreEqual(0.0, actualResult);
        }
    }
}

他编写在测试方法的示例,因为,那么,当他编写自己的代码后,会希望该示例工作。

Hh543900.collapse_all(zh-cn,VS.110).gif创建单元测试项目和方法

通常您将创建一个新测试的每个项目的项。 如果测试项目中已经存在,您可以添加新测试方法和选件类。

此过程使用Visual Studio单元测试框架,但是,您也可以使用其他提供程序的结构。 假定您安装相应的适配器,同样正常测试资源管理器使用其他结构。

  • 如果它已不存在,创建测试项目。

    • *** 新项目 *** 对话框中,选择一种语言(如 *** Visual Basic ****** Visual C++ ****** visual C# ***。 选择 测试 然后 *** 单元测试项目 ***
  • 添加您向测试提供的选件类。 每个单元测试是一个方法。

    每个单元测试必须由 TestMethod 属性作为前缀,而且单元测试方法不应有参数。 您可以使用用于单元希望测试方法的名称:

            [TestMethod]
            public void SignatureTest()
            {...}
    
        <TestMethod()>
        Public Sub SignatureTest()
        ...
        End Sub
    
  • 每个测试方法都应调用 Assert 选件类的方法,指示是否已通过或失败。 通常,确认操作的预期和实际结果相等:

    Assert.AreEqual(expectedResult, actualResult);
    
    Assert.AreEqual(expectedResult, actualResult)
    
  • 测试方法可以调用没有 TestMethod 属性的其他普通方法。

  • 您可以组织测试到多个选件类。 必须由 TestClass 属性前缀每选件类。

    [TestClass]
    public class UnitTest1
    { ... }
    
    <TestClass()>
    Public Class UnitTest1
    ...
    End Class
    

有关编写单元方式的更多信息在C++测试,请参见 用 Microsoft 适用于 C++ 的单元测试框架编写 C/C++ 单元测试

创建新的代码存根

接下来,针对创建自己新的编码选件类库项目。 开发中现在有代码的项目,而且单元的项目测试。 他将项从测试项目开发中对代码。

具有测试和类项目的解决方案资源管理器

在新项目,他将新选件类和将至少允许测试成功编译的方法的最小的版本。 是生成从调用的选件类和方法存根在测试中最快的方法执行。

        public double SquareRoot(double p)
        {
            throw new NotImplementedException();
        }

Hh543900.collapse_all(zh-cn,VS.110).gif若要生成选件类和方法从测试

首先,创建要添加新选件类的项目,除非它已经存在。

生成选件类

  1. 将光标放在要生成选件类,例如,LocalMath的示例。 在快捷菜单上,选择 *** 生成代码 ****** 新类型 ***

  2. *** 新类型 *** 对话框中,设置 项目 到选件类库项目。 在此示例中,它是 Fabrikam.Math。

生成方法

  • 将光标放置在调用方法时,例如,SquareRoot。 在快捷菜单上,选择 *** 生成代码 ****** 方法存根 ***

运行第一个测试

针对生成并测试按CTRL+R运行,T。 测试结果显示红色失败的指示器和测试将出现在 ***** 未通过的测试 *****下列出。

显示 1 个失败测试的单元测试资源管理器

他对代码的简单更改:

       public double SquareRoot(double p)
        {
            return 0.0;
        }

他再次运行测试,并通过:

具有 1 个已通过测试的单元测试资源管理器

Hh543900.collapse_all(zh-cn,VS.110).gif要运行单元测试

显示“全部运行”按钮的测试资源管理器

  • 测试 菜单中,选择 运行*** 所有测试 ***

    - 或 -

  • 如果测试管理器是打开的,选择 *** 运行任何 ***

    - 或 -

  • 在测试代码文件并按 ***** CTRL+R,T *****中将光标置于

  • 如果测试将出现在 ***** 未通过的测试 *****下:

    通过双击该名称,例如,打开测试。

    测试失败的点显示。

若要查看完整列表,测试 选择 *** 显示任何 ***。 若要返回到摘要,请选择 主页 视图。

查看测试结果的详细信息, 选择测试管理器。

导航到测试的代码, 双击测试Explorer或在快捷菜单上选择 *** 打开"测试 ***

调试测试, 打开一个或多个快捷菜单的测试,然后选择 *** 调试选择测试 ***

若要在后台运行且测试,只要生成解决方案, 触发器 *** 运行在编译之后测试 ***。 测试失败以前首先运行。

授予接口

针对调用他的Lync的同事茱莉亚,并共享他的屏幕。 她使用自己的元素。 他显示他初始示例。

茱莉亚会将示例是可以的,但是,注释,“测试的许多功能将通过”。

针对答案,“第一个测试是,以确保函数的名称和参数是正确的。 现在我们可以编写获取此功能的主要要求的测试”。

共同以下测试编写:

  
      [TestMethod]
        public void QuickNonZero()
        {
            // Create an instance to test:
            LocalMath math = new LocalMath();

            // Create a test input and expected value:
            var expectedResult = 4.0;
            var inputValue = expectedResult * expectedResult;

            // Run the method:
            var actualResult = math.SquareRoot(inputValue);

            // Validate the result:
            var allowableError = expectedResult/1e6;
            Assert.AreEqual(expectedResult, actualResult, allowableError,
                "{0} is not within {1} of {2}", actualResult, allowableError, expectedResult);
        }

提示

此功能,针对使用测试先行的开发,会为其编写单元首先测试满足测试。函数,然后编写代码在某些情况下,会发现此做法不是真实的,因此,他的编写测试,在其编写代码之后。代码,因为它们保持稳定,代码,但是他测试是否将非常重要编写单元在之前或之后。

红色,绿色,重构…

针对遵循重复他编写测试并确认的循环它失败,将编写代码使测试通过,然后考虑重构是,改进代码,而不更改测试。

Hh543900.collapse_all(zh-cn,VS.110).gifRed

针对按ctrl+r,然后按T运行新测试他使用茱莉亚创建的。 在他编写任何测试后,会始终运行它,以确保它失败,将在其编写使其通过的代码。 这是他了解的约定,在他在某些忘记将断言测试他编写之后。 看到失败结果为他的confidence,会将其提交通过时,测试结果正确地表示满足的要求。

另一个有用的做法是设置 *** 运行在编译之后测试 ***。 此选项在后台运行测试,在生成解决方案时,因此,您的代码的测试条件的一个连续的报表。 针对处于可能使Visual Studio慢响应的第一,查找,但是他查看这很少发生。

具有 1 个失败测试的单元测试资源管理器

Hh543900.collapse_all(zh-cn,VS.110).gif绿色

针对编写自己的在他开发方法的代码的第一次尝试:

    public class LocalMath
    {
        public double SquareRoot(double x)
        {
            double estimate = x;
            double previousEstimate = -x;
            while (System.Math.Abs(estimate - previousEstimate) > estimate / 1000)
            {
                previousEstimate = estimate;
                estimate = (estimate * estimate - x) / (2 * estimate);
            }
            return estimate;
        }
        

针对再次运行测试,所有测试通过:

具有 2 个已通过测试的单元测试资源管理器

Hh543900.collapse_all(zh-cn,VS.110).gif重构

现在代码执行其主函数中,针对查看代码查找办法使其更佳,或者便于在以后更改。 他意识到他可以减少在循环执行的计算次数:

public class LocalMath
    {
        public double SquareRoot(double x)
        {
            double estimate = x;
            double previousEstimate = -x;
            while (System.Math.Abs(estimate - previousEstimate) > estimate / 1000)
            {
                previousEstimate = estimate; 
                estimate = (estimate + x / estimate) / 2;
                //was: estimate = (estimate * estimate - x) / (2 * estimate);
            }
            return estimate;
        }

他验证仍通过测试:

具有 2 个已通过测试的单元测试资源管理器

提示

所做的每项更改,当您开发代码应该是重构或扩展时:

  • 重构意味着不更改测试,因为不添加新功能。

  • 扩展方法添加测试,并使需要通过现有和新代码更改测试。

如果您要更新现有代码更改的要求,还将删除旧测试该不再表示当前要求。

避免更改测试已通过时。相反,请添加新测试。仅编写测试表示物理要求。

运行在每项更改后测试。

Hh543900.collapse_all(zh-cn,VS.110).gif…结构和重复

针对继续举办扩展他的系列,并且重构步骤,使用自己的列表小的步骤作为大致的准则。 他不在每个扩展后总是执行一个重构步骤,因此,他一个接一个地在某些情况下执行多个重构步骤。 但是他始终运行单元在对代码的每项更改后测试。

有时他将不需要对代码的更改,但是,添加到他的confidence的测试他的代码正常工作。 例如,他若要确保,该功能是在多种输入。 他编写更测试,例如这一操作:

        [TestMethod]
        public void SqRtValueRange()
        {
            LocalMath math = new LocalMath();
            for (double expectedResult = 1e-8;
                expectedResult < 1e+8;
                expectedResult = expectedResult * 3.2)
            {
                VerifyOneRootValue(math, expectedResult);
            }
        }
        private void VerifyOneRootValue(LocalMath math, double expectedResult)
        {
            double input = expectedResult * expectedResult;
            double actualResult = math.SquareRoot(input);
            Assert.AreEqual(expectedResult, actualResult, expectedResult / 1e6);
        }

首次运行,则通过测试:

具有 3 个已通过测试的单元测试资源管理器

确定此结果不是错误,他临时引入了一个小错误到他的测试将失败。 在中看到该失败后,会再次修复它。

提示

在进行它通过之前,请始终使测试失败。

Hh543900.collapse_all(zh-cn,VS.110).gif异常

针对现在移到编写测试异常类型:

[TestMethod]
        public void RootTestNegativeInput()
        {
            LocalMath math = new LocalMath();
            try
            {
                math.SquareRoot(-10.0);
            }
            catch (ArgumentOutOfRangeException)
            {
                return;
            }
            catch
            {
                Assert.Fail("Wrong exception on negative input");
                return;
            }
            Assert.Fail("No exception on negative input");
        }

此测试将代码添加到循环。 他必须使用 *** 取消 *** 按钮测试管理器。 这将在10秒内终止代码。

针对若要确保,无限循环在生成服务器不会发生。 虽然服务器施加超时对完整运行,这是很长的超时并导致大量延迟。 因此,他将显式超时到此测试:

        [TestMethod, Timeout(1000)]
        public void RootTestNegativeInput()
        {...

显式超时从而使测试失败。

针对然后更新代码处理此异常情况:

       public double SquareRoot(double x)
        {
            if (x <= 0.0) 
            {
                throw new ArgumentOutOfRangeException();
            }

Hh543900.collapse_all(zh-cn,VS.110).gif回归测试

新测试通过,但是,有回归。 使用现在通过的测试失败:

之前通过的失败单元测试

针对找到并修复错误:

      public double SquareRoot(double x)
        {
            if (x < 0.0)  // not <=
            {
                throw new ArgumentOutOfRangeException();
            }

在修复该bug后,所有测试都通过:

具有 4 个已通过测试的单元测试资源管理器

提示

确定每在对代码所做的每项更改后测试通过。

代码复盖率

在他的过程中的时间间隔,最后,在他入代码之前,针对获取一个代码复盖率"报表。 这将显示多少代码由其执行该测试。

针对peter的团队为复盖率至少80%争取。 因为实现此类代码中,一个高效复盖率可能很难将放宽生成的代码的此要求。

好复盖率不是确保元素的完全测试的功能,因此,它不保证代码为输入值的每个范围仍有效。 但是,代码行元素的性能上的空间复盖率和复盖率之间的大小接近的依赖项。 因此,首选复盖率生成这些测试大部分行为它们应团队的confidence。

获取一个代码复盖率"报表,有关 *** 测试 *** 菜单上,选择 运行*** 分析所有测试的代码复盖率 ***。 然后运行所有重新测试。

代码覆盖率结果和“显示颜色”按钮

针对获取一个总复盖率86%。 会将其展开报表时总计,它表示,他开发的代码具有复盖率100%。 重要,因为将用于测试代码,这非常满意的。 找到部分以实际进行测试。 通过切换 *** 显示代码复盖率着色 *** 按钮,针对可以看到测试代码的哪些部分尚未执行。 但是,他决定这些节为复盖率并不重要,因为它们在测试代码,并且仅使用,如果检测到错误。

若要验证特定测试达到到代码中的特定分支,可以设置 *** 显示代码复盖率着色 *** 通过在其快捷菜单,运行 的命令然后运行单个测试。

我们在执行?

针对继续更新在小步骤的代码,直到他不足:

  • 所有可用的单元测试通过。

    在与一个非常大的一个项目设置单元测试,则可以不适合开发人员可以等待其所有运行。 相反,该项目运行一个封闭签入服务,在其中自动化的所有测试配置的注册的搁置集运行,则合并到源树之前。 运行时,如果的失败,签入被拒绝。 这允许开发人员运行的最低设置单元独立测试计算机,然后继续执行其他工作,而不会面临的风险中断生成。 有关更多信息,请参见 定义封闭签入生成过程以验证更改

  • 代码复盖率以满足团队的条件。 75%是典型的项目要求。

  • 他的单元测试模拟需要行为的各个方面,包括典型和异常输入。

  • 他的代码易于理解和扩展。

当所有条件都满足时,针对就绪检查他的代码添加到源代码管理。

Hh543900.collapse_all(zh-cn,VS.110).gif代码开发的原则的单元测试

针对应用以下原则,在开发代码时:

  • 在开发过程中,开发单元与代码一起测试,并且经常运行它们。 单元测试将表示组件的规范。

  • 不要更改单元测试,除非要求已更改或测试是错误的。 添加新逐渐测试,则扩展代码的功能。

  • 要包括的至少75%的目标您的代码。 查看代码复盖率结果间隔,并且,则在签入源代码。

  • 检查您的单元测试与代码一起测试,因此,它们由连续或普通服务器生成运行。

  • 如有可能,为功能每个部分,单元测试首先编写。 执行此操作,在开发满足它的代码。

签入更改

在检查在他的更改之前,针对再次使用Lync用他的同事共享茱莉亚他的屏幕,因此她可以非正式并以交互方式检查利用自上创建的。 测试将在其讨论焦点,因为茱莉亚主要是为任何感兴趣代码执行,而不是其工作方式。 茱莉亚授予什么针对编写满足其需求。

针对注册他做的所有更改,包括测试和代码,并将自身与直到完成的任务。 签入对团队的自动化团队生成系统来验证他的更改团队使用的CI编译过程。 此生成过程团队通过编译将其基本代码的错误的帮助,并且测试在独立于其开发的干净环境计算机每项更改团队进行。

在生成完成后,针对发出通知。 在生成结果窗口,会看到生成成功,并且所有测试通过。

Hh543900.collapse_all(zh-cn,VS.110).gif签入更改

签入挂起的更改

  1. 在菜单栏上,依次选择**“视图”“团队资源管理器”**

  2. *** 团队资源管理器 ***,选择 主页,然后选择 *** 我的工作 ***

  3. *** 我的工作 *** 页上,选择 *** 注册 ***

  4. 检查 *** 挂起的更改 *** 页的内容,以确保:

    • 所有相关更改列表中 ***** 包含的更改 *****上

    • 所有相关工作项。***** 相关工作项 *****列表。

  5. 当用户查看已更改的文件和文件夹时,的版本控制历史记录指定 *** 注释 *** 帮助您的团队了解这些更改的意图。

  6. 选择**“签入”**。

Hh543900.collapse_all(zh-cn,VS.110).gif持续集成代码

有关如何定义持续集成生成过程的更多信息,请参见 定义生成过程以支持持续集成。 在设置了此生成过程后,可以选择将通知团队生成的结果。

Peter 收到 CI 生成成功的通知

CI 生成结果

有关更多信息,请参见 运行、监视和管理生成

接下来("挂起工作,修复bug,并执行代码评审)