<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>服务世界 开发未来 : 译文</title><link>http://blogs.msdn.com/stbcblog/archive/tags/_D18B8765_/default.aspx</link><description>Tags: 译文</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>系统压力测试</title><link>http://blogs.msdn.com/stbcblog/archive/2009/04/12/Stress-testing-your-system.aspx</link><pubDate>Sun, 12 Apr 2009 11:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9546282</guid><dc:creator>STB China Blog</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/stbcblog/comments/9546282.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stbcblog/commentrss.aspx?PostID=9546282</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对我们的系统和组件进行压力测试是非常重要的。压力测试可以发现很多在正常情况下不会被暴露的问题，也就是说可以发现更多其他测试无法发现的系统缺陷。虽然压力测试和负载测试在某些方面有共同点，但是两者并不相同。负载测试是通过在系统上运行已经定义好的工作负载从而确保系统能够在一定的负载系正常工作。而压力测试是测试系统过载的情况，并帮助回答这样一个问题“什么原因导致了系统错误？”&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以下是我曾经参与过的一些压力测试:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;Windows 客户端的压力测试&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在这个系统测试中，我们同时运行许多应用程序，伪应用程序以及测试程序。如果你没有看到过这种情形，你应该去尝试一下。此时，很多子系统会被同时频繁地调用。由于现实中，一个人很难同时做很多事，所以一般Windows用户是很难出现这样的负载。&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;Xbox 压力测试&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在这个系统测试中，许多测试程序和一个游戏引擎同时在Xbox的进程空间中以多线程的方式运行。在Xbox中的所有测试都被设计成与系统内核同时运行在同一个进程空间中。而这也正是Xbox系统的模型。每个测试都是一个线程，每个线程都知道自己不能独享整台机器。我们同时运行所有的测试，于是就出现了图形测试，I/O测试,声音测试，网络测试和控制器测试同时运行的情形。&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;HPC 压力测试&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在这个系统测试中，我们在管理控制台运行的时候提交许多简单的MPI作业，从而模拟了一个很大的工作负载。事实上，它模拟了一个实际中不可能出现的工作负载，因为真正的用户不会喜欢一个集群同时有成百上千的作业在队列中等待处理 。成千上万的MPI作业同时运行，就会有几百万个状态更新信息被发送到管理控制台。此时管理控制台就需要同时处理几百万条消息。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这些测试都如下共同点：&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;没有用户会这样使用系统!&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;负载是完全不合理的&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;系统最终可能会崩溃&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=宋体 size=2&gt;我们可能不会修复这样的&lt;B&gt;BUG&lt;/B&gt;，因为用户不会碰到它。&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这是一种设计出来的不合理的负载。实际中用户不会给系统带来如此强度的工作负载。而这种负载强度应该会导致系统崩溃。但是我们并不会修复每一个这样的BUG。其实这些都并不是重点。重点是我们可以通过这样的测试很快发现系统的弱点，并决定这些弱点是否应该被修复或者处理并由此调整测试。一个在正常使用情况下可能需要一个月才暴露的BUG,在压力测试中可能几分钟就会暴露出来。这是一种很有效并高效的寻找BUG的方法。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 压力测试的关键是：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;一个通过了压力测试的系统在正常的工作负载下将很难出错。这样的系统才是好系统！&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;John Daly&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;高性能计算(HPC)美国团队测试经理&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;翻译：周毅， 高性能计算中国团队测试开发工程师&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9546282" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_6F8FF64E4B6DD58B_/default.aspx">软件测试</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_D18B8765_/default.aspx">译文</category></item><item><title>Visual Studio Team Architect团队的敏捷开发 （第二部分）</title><link>http://blogs.msdn.com/stbcblog/archive/2009/03/09/How-we-do-agile-in-Visual-Studio-Team-Architect-2.aspx</link><pubDate>Mon, 09 Mar 2009 05:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9467438</guid><dc:creator>STB China Blog</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stbcblog/comments/9467438.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stbcblog/commentrss.aspx?PostID=9467438</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我希望大家都度过了一个快乐的春节。我也享受了一段轻松的假期——大部分时间宅在家里接待朋友和他们的家人，同时去杭州做了短暂的旅行。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 十分感谢你们通过博客或者私下里给我的反馈。我希望在这篇博文中回答一些你们提出的问题。同时，为了延续整个系列的行文思路，我也会涉及一些我们团队计划sprint的方法以及sprint过程中发生的事情，并穿插着回答你们提出的那些问题。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 首先，我想说的是，不存在敏捷无需计划的神话。可是，敏捷开发中的计划的确和传统软件开发中的计划有着很大区别。正如我在上一篇博文中所说，我们针对利益攸关方(stakeholders)给出的上层需求创建了带有优先级的产品待开发事项(product backlog)。这一带有优先级的任务列表形成了最基本的sprint计划。在这一过程中，我们一般遵循三阶段的步骤：在主管间进行的预计划阶段，所有团队成员都参加的计划阶段以及包含利益相关者的计划提交阶段。这里的关键是：计划是在所有成员的通力合作中进行，最重要的是由组员自发来制定标准、而不是依赖于某个项目经理。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 预计划阶段在上一个sprint的最后一周进行，在这一阶段中，团队中分别带领项目经理，开发和测试的几位主管会聚集到一起讨论出在即将进行的下一个sprint中，需要开发的故事(story)列表。这个过程取决于很多因素，其中最重要的是：上一个sprint的进展情况，从利益相关者那里得到的反馈，需求或故事优先级发生的变化以及预计的团队速度。项目经理(有时甚至是开发人员或者测试人员)在阐述故事的时候会尽量简短到只描述出目标、故事的简单介绍以及故事的具体流程。我们发现OneNote很好的满足了我们这一需求(稍后会给出一个故事的截图)。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 产品待开发事项总是列出对客户有价值的条目，同时它也可以增加这个团队要求的条目。但是，只有那些最终会给客户带去价值的条目才可以出现在待开发事项中。举例来说，创建并维护一个持续集成服务器以持续保证最终产品的质量，这样的条目被允许出现在待开发事项中的。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 计划阶段通常在sprint的第一天进行。在开会前，项目经理会把OneNote页面的链接发送给组员，以便大家评估，并且为计划会议做好准备。通常，组员会在OneNote页面中交换意见，从而在会议之前澄清那些不明了的地方。在计划会议当天，团队组员会聚集到一起，过一下所有的故事，解决之前发现的任何问题，把故事进一步细分成一些任务，并描述每个故事的验收测试。组员同时也会对完成这些故事所需要的时间做一个大致的估计，然后根据这些估计决定在这个sprint中，团队可以完成哪些故事。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 计划提交阶段在之后的一天进行，主管会再度聚集在一起并且向利益相关者介绍团队承诺完成的任务。此时，利益相关者可以提出建议对优先级进行调整。比如，如果团队成员可以完成故事A，B以及C，但是不能完成D和E，利益相关者可以建议团队在这一个sprint中完成A,B,D以及E(假设D和E消耗的总时间和C相同)。然后，项目经理会把这些故事输入用来管理我们项目的Visual Studio Team Foundation Server。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 注：我们花了好几个sprint来学习并总结出以上这个计划流程。这就是sprint回顾(我会在以后的博文中提及)发挥的重要作用。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 现在，让我来回顾一些针对我上一篇博文提出的问题：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;FONT face=宋体 size=2&gt;在sprint中的变化以及干扰&lt;/FONT&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有一位朋友提了这样一个问题，变化是敏捷方法的核心，那么团队应该如何应对sprint过程中发生的变化呢？诚然，快速有效的应对变化是所有敏捷方法的核心部分，然而，在sprint过程中的干扰始终对生产力有着不良影响。在我们的团队中，我们总是尽量避免sprint过程中的干扰，把变化延缓到下一个sprint中。因为我们把sprint的长度控制在4个星期，所以对于那些变化，意味着他们平均需要等待2个星期。:) 最起码，我们希望团队在应对变化之前，先完成那些计划了的故事。这一策略当然需要利益相关者的支持，并且在之前就达成一致。干扰对团队的影响很容易观察到，方法之一就是留意团队速度的下降。(比如在燃尽图上看到曲线的变化)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&lt;U&gt;代码重构：&lt;/U&gt;&lt;U&gt;&lt;/U&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 另一个问题是该怎样应对因需求改变导致的重构现有代码。当研究一个新的设计时，重构是有效的方法；当代码量不大时，重构也不是一个大问题。然而，一旦你的代码量开始变大，重构的代价就会变得很昂贵。由于利益相关者的反馈和需求的变化，我们也曾有相当一部分代码需要重构。 在考量代码重构问题时，最重要的依据是重构对于产品和团队的影响。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 举一个例子，我们曾不得不改变当一个图形被拖动到另一个图形内部时的产品行为。因为在最初设计这一行为的时候，我们的信息不够充分。在初期的实现之后，我们注意到有一些人已经对这一行为记录了bug，因为他们认为产品的表现和他们的预期不同。我们针对这一情况采取了下列的方法：1）收集更多的反馈以明确预期的行为；2)提供了一个穿刺(spike)方案（译者注：Spike指在产品线的外部开发的试探性的原型系统），调整了产品的行为；3)对穿刺方案进行代码复查和“伙伴测试”确保解决问题。（译者注：伙伴测试指找产品组成员帮忙适用产品的新功能，以查找问题）4)对已发生的变化撰写单元测试。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 另外，我需要指出的是，在任何的重构过程中，自动化测试的好处都不会被过分夸大。它能够确保正在进行的代码改变不会给产品的其他部分带来计划外的破坏。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&lt;U&gt;架构与设计&lt;/U&gt;&lt;U&gt;&lt;/U&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 尽管我们应该预期到设计和实施中会有变化发生，然而，就如我之前提及的，当代码量增大时，对代码的改变和重构的代价呈非线性的增长。面对这个问题，预先进行一定程度的架构与设计就带来了好处。这里的架构与设计并不需要非常具体化，其目的是能够刚好鉴定出在之后的实施中可能面对的主要问题。当然，说起来容易做起来难J。在项目的初期，当上层的需求齐备了，也有一个初步的产品待开发事项列表时，就可以开始进行上层架构了。尽管这可以通过纸笔或者任何建模工具来完成(我们希望在Dev10发布之后，你们会用Visual Studio Team Architect完成这项任务)，你将会需要开发一个原型来支持你的设计与架构。我们发现这一步骤对项目的成功非常有帮助。对有一定复杂度的项目，你可以通过这个方法来确定应使用的技术，明确依赖关系等等。对团队来说，这也是对其各自的自动化框架加强建设的好时机。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OK，我已经讲了很多形而上学的东西。下面让我展示一些截图，把我们团队在sprint计划阶段进行的工作映对到我在前文中所讲述的方法原则。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面的这些截图展示了我们团队在sprint计划以后讨论出的故事列表。 同时，你也会注意到一些不同的团队成员留下的评论。其中的交付编号是在TFS中对应的标识号码。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_4.png"&gt;&lt;FONT face=宋体 color=#000000 size=2&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_4.png"&gt;&lt;IMG title="list of stories" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=380 alt="list of stories" src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_1.png" width=508 border=0 mce_src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_1.png"&gt;&lt;/A&gt;&lt;/A&gt;&lt;/A&gt;&lt;FONT face=宋体 size=2&gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一个用户故事从用户角度描述了一个需求功能点。一个好的用户故事包括需求功能的描述，谁需要它，怎么使用它，为什么需要它。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Spint计划中的重要一环是让团队对“完成”的定义达成共识。在我们对“完成”的定义中，编写并且运行通过验收测试是重要内容之一。验收测试是在软件交付之前进行的黑盒测试。在我们的语境中，它意味着用户故事的核心内容实现得如同预期的那样。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一个验收测试应该满足两个条件：1)产品的拥有者应该能够根据它鉴定用户故事已经被实现。2)开发人员应该能够根据它检验他们是否已经开发出了预期的功能。&lt;U&gt;我们不开发那些不能被检验的功能。&lt;/U&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面是我们所创建一个典型用户故事的具体组成部分：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_8.png" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_8.png"&gt;&lt;FONT face=宋体 color=#000000 size=2&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_8.png" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_8.png"&gt;&lt;IMG title="various parts of a typical user story" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=56 alt="various parts of a typical user story" src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_3.png" width=512 border=0 mce_src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_3.png"&gt;&lt;/A&gt;&lt;/A&gt;&lt;/A&gt;&lt;FONT face=宋体 size=2&gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 接下来，你会看到一个示例故事以及基于这个故事展开的讨论。&amp;lt;作者注：为了节省空间，以及展示团队成员间的合作，在复核阶段对问题展开的讨论，我做了手工编辑并把他们合并在了一起。〉最重要的是对故事的讨论是团队在动手实施之前的协作，团队在那一时刻已经达成了一致。在这里，我们把对质量的要求往上流推进到很早期的阶段，甚至在团队动手开始写任何一行代码之前，我们已经开始为产品质量作了努力。事实证明，这一办法在之后节省了我们很多的时间精力。如下图所示，团队讨论并解决了关于可用性，可实施性以及可测试性的问题。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_12.png" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_12.png"&gt;&lt;IMG title="story example" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=414 alt="story example" src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_5.png" width=519 border=0 mce_src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_5.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_14.png" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_14.png"&gt;&lt;IMG title="story discussion" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=350 alt="story discussion" src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_6.png" width=522 border=0 mce_src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_C420/image_thumb_6.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;这篇博文中，我已闲庭信步于sprint计划阶段，不多言了。下一篇中，我会就sprint的实施阶段展开进一步的讨论。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;Ramesh Rajagopal&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;Visual Studio Team Architect 中国团队经理&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;翻译：朱永泰&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;校译: 林裕科&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9467438" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_E2561F9645658B4E_/default.aspx">团队故事</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_A74EC1540E4E80622F67_/default.aspx">产品与技术</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_4F657763005FD153_/default.aspx">敏捷开发</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_D18B8765_/default.aspx">译文</category></item><item><title>资源分配测试—失败及恢复</title><link>http://blogs.msdn.com/stbcblog/archive/2009/02/04/Test-to-failure-and-recover.aspx</link><pubDate>Wed, 04 Feb 2009 01:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9394174</guid><dc:creator>STB China Blog</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stbcblog/comments/9394174.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stbcblog/commentrss.aspx?PostID=9394174</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们知道所有程序都会和各种资源打交道，硬件资源类型如硬盘，系统资源如句柄，因此如何做好资源相关的测试很重要。大家熟知的是测试资源的泄漏，但这里我想更多的从资源分配失败及恢复角度去谈资源分配测试。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于资源通常有如下操作：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;1．分配资源&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp; 我们熟知的一个典型例子就是 C语言中'malloc()' 系列函数。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;2．释放资源&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp; 同样的一个例子就是C语言中'free()'系列函数。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;3．资源计数&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp; 比较常见的例子就是性能计数器，比如文件句柄计数器，它能够提供“有多少文件句柄被打开”的信息&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们编写软件的时候，我们一般都会经常使用这些资源管理类函数来帮助我们，从而得以申请和释放多种类型的资源。当然我们也会编写一些自己的代码来申请和释放资源。一般情况下，这些代码会处于我们的软件架构的相对底层上。我们可能有一个系统，在这个系统里，我们分配资源，使用资源，还可能管理并监控资源，最后当处理完后释放掉这些资源。同时还存在着当代码运行时替我们分配资源的情况。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 由于各种原因，资源的申请和分配并不总是能够成功的。其中一个原因可能是某种特殊的资源被消耗殆尽了。比如在磁盘空间不够时，我们申请使用更多磁盘资源的话就会失败；还比如内存总是是有限的；句柄空间总是那么多。总之软件有可能因为各种原因而出错，但一个主要的原因就是资源的消耗。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于服务型软件而言，提供长期稳定的服务是重要的设计目标之一。从而，相对于客户端程序，它需要运行得更加可靠、健壮。为了确保软件的可靠性和健壮性，我们必须确保它在资源可用率发生异常变动的情况下，它还是可以正常运行。如果某一个程序消耗了所有的内存，那么我们可以假定它肯定会出错了；但如果由于系统内存的不足导致内存分配的偶尔失败，那么我们的软件应不应该完全&lt;I&gt;崩溃&lt;/I&gt;？还是应该仅仅让当前操作出错并让软件其他部分能够继续正常运行？同样的问题也适用于其他类型的动态分配并被共享的资源，比如磁盘空间，内存，文件，网络连接等。&lt;B&gt;&lt;I&gt;&lt;/I&gt;&lt;/B&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 致错测试是一个重要的测试场景，可以帮助我们了解当资源使用达到极限的时候会发生什么。简单地说， 这种测试可以用以下伪代码描述：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Segoe UI" size=2&gt;&lt;EM&gt;Pallocatedthing[&amp;lt;use more than enough space here&amp;gt;]&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Segoe UI" size=2&gt;&lt;EM&gt;counter n&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Segoe UI" size=2&gt;&lt;EM&gt;While(Pallocatedthing[n++]=allocate(&amp;lt;whatever size you like&amp;gt;))&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Segoe UI" size=2&gt;&lt;EM&gt;While(n)&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Segoe UI" size=2&gt;&lt;EM&gt;free(Pallocatedthing[n--])&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这种测试很简单，就是申请分配资源直到失败，然后释放掉所有分配的资源。这只是一种最简单的测试，如果你确保它可以工作了，那么还有几件事情等着你去做。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 首先，将它放到一个循环里面，然后执行很多次。它是否依然可以正常工作？&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其次，在它运行的时候观察整个系统，看被测试进程是否有内存，句柄或者其他资源的泄漏。这种场景下的一个典型的BUG就是资源分配函数发生错误时没有被正确处理。即使它不会立即导致崩溃，但仍可能会导致内存泄漏或者错误。这种事情我以前也遇到过。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果要更深入此类测试场景，则需要理解资源的依赖关系，以及在软件依次消耗掉所有的这些资源情况下其是否正确处理了所有的资源错误。这方面的一个例子就是处理消息的软件。它将在等待处理的消息在磁盘上保存为一个队列。那么磁盘如果满了的话会发生什么？这种场景可能会比较难设置，它看起来类似于：&lt;B&gt;&lt;I&gt;&lt;/I&gt;&lt;/B&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;1. 限制硬盘空间&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;2. 将消息注入到队列中&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;3. 停止从队列中取消息&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;4. 磁盘满了，会发生什么？相应的工作行为是正确的吗？&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;5. 重新开始从队列中取消息。是否一切工作正常？&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 接下来的几个步骤类似于我们上面已经做的，那就是在更多的情况下去重复测试它，并观察结果：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 尝试取出所有的消息，直到队列为空。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建立一个稳定的消息输入流，但时而暂停并再恢复取出消息，反复执行磁盘空间测试用例，看是否在这样的情况下仍然工作正常？ 如果出错的话，是否该出错被正确处理？是否有副作用，比如内存泄漏，句柄泄漏或者数据出错？是否队列的生产者和消费者都正确处理了错误用例？&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在你的软件中还会有很多关于这个主题的情况等待你去挖掘，我不准备将所有可能的情况都列在这里。我想你能够自己考虑这些事情。&lt;/FONT&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;John Daly&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;高性能计算美国团队测试经理&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;翻译：周毅， 高性能计算(HPC)中国团队测试开发工程师&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9394174" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_6F8FF64E4B6DD58B_/default.aspx">软件测试</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_D18B8765_/default.aspx">译文</category></item><item><title>Visual Studio Team Architect 团队的敏捷软件开发（第一部分）</title><link>http://blogs.msdn.com/stbcblog/archive/2009/01/21/How-we-do-agile-in-Visual-Studio-Team-Architect.aspx</link><pubDate>Wed, 21 Jan 2009 02:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9345138</guid><dc:creator>STB China Blog</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/stbcblog/comments/9345138.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stbcblog/commentrss.aspx?PostID=9345138</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在最近几次与客户面对面的交流中，我有幸分享了我们团队如何在日常工作中进行敏捷软件开发。毫无疑问，这在中国开发人员中是个热门话题，我也想利用博客这个平台与更多的读者进行书面的交流。当然关于敏捷开发利弊得失的争论有不少，而相关的开发模式也分成了TDD (Test Driven Development), Scrum, XP(eXtreme Programming)等流派。就我个人而言，一个团队是否严格遵循某种既定的敏捷方法并不重要，但一定得选择并采用一种（或几种）最适合自己开发团队和开发项目的。我认为重要的是团队能否遵循《&lt;/FONT&gt;&lt;A href="http://agilemanifesto.org/" mce_href="http://agilemanifesto.org/"&gt;&lt;FONT face=宋体 size=2&gt;敏捷软件开发宣言&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=宋体 size=2&gt;》所涉及的12条原则。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在我深入这一议题前，请允许我介绍一下团队：我们属于微软开发工具部（Developer Division,以下简称DevDiv），这个部门拥有几千名软件工程师，核心产品Visual Studio系列的用户从软件开发爱好者一直到大型企业里的专业开发人员及架构师。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;大量而且复杂的依赖关系、代码改动、紧迫的开发周期等因素使管理软件开发生命周期并按时发布高质量的Visual Studio产品极具挑战性。为了降低风险和复杂度，DevDiv在开发Visual Studio 2008过程中采用了功能分支架构(Feature Branch Structure)和功能小组模型(Feature Crew Model)。其实这一方式之前已在Office开发团队的实践中取得不错的效果。它的最大好处之一就是使负责某个功能的团队在独立开发过程中有更大自由。由于篇幅所限，在这篇博文中我将侧重介绍我们团队是如何进行敏捷软件开发的。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们团队负责Visual Studio系列中的Visual Studio Team System Architecture Edition，帮助架构师、运营经理及开发人员以可视化方式构造面向服务的解决方案、降低（软件产品开发的）复杂度。目前我们已开发了基于UML和DSL几个建模工具。这基本上是一个全新项目。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;从产品开发来看，我们属于全球分布式开发，团队分布在三大洲的四个城市，包括亚洲的上海，北美洲的雷德蒙和夏威夷，以及欧洲的剑桥。为了尽可能减少分布式研发对团队间交流所造成的障碍，我们尽量使功能小组的成员集中于一地。基本上，每个功能小组的核心部分都在某一个城市完成，在其他城市可能会有个别工程师参与相关开发。例如，我们在上海就有一个功能小组，其他一些工程师在雷德蒙的公司总部工作。但有时，基于客户场景的特殊要求，我们也会将一个功能小组拆分成若干个，由多个城市的团队同时开发。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;在本文后半部分和之后的系列文章中，我所谈及得敏捷软件开发流程都是同一个功能小组所遵循的，即是我们中国团队所遵循的。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;我们中国团队主要负责开发基于UML的核心图形设计工具，包括即将发布的Logical Class Designer, Use Case Designer。此外，我们还负责在项目中提供建模元素视图功能的Model Explorer。我们所采用的敏捷开发方法是Scrum的修改版。就如我之前提到的，我们认为敏捷开发方法和技术没有哪一种是万灵丹，适合自己才是最好的。我们的团队中已有两位工程师参与过Scrum实践，也因此促成我们最终选择了它。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面是一个我们敏捷软件开发流程的概要视图：&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;FONT face=宋体 size=2&gt;&lt;A href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_FD2A/SprintLifeCycle_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_FD2A/SprintLifeCycle_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=287 alt=SprintLifeCycle src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_FD2A/SprintLifeCycle_thumb.jpg" width=524 border=0 mce_src="http://blogs.msdn.com/blogfiles/stbcblog/WindowsLiveWriter/VisualStudioTeamArchitect_FD2A/SprintLifeCycle_thumb.jpg"&gt;&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;产品待开发事项（Product Backlog，视图的左上角）可以被视作一份这个团队以优先级排列的、需要完成的功能需求单：来自相关产品利益相关者（Stakeholders）对产品提出一系列高端要求。例如，我们最初的要求是为客户增加逻辑级（更抽象的）和物理级（更靠近代码）建模提供支持，由此衍生出了高端功能需求，诸如开发在逻辑级方便客户生成逻辑模型、兼容UML的关系图和开发帮助创建无力模型的DSL关系等。然后我们会对将要支持的UML关系图种类按优先级进一步分解（UML共有13种不同的关系图）。产品利益相关者的意见会驱动整个优先级选择过程，最终我们得出五个最重要的关系图：Logical Class Diagrams, Use Case Diagrams, Sequence Diagrams, Activity Diagrams 和Component Diagrams。于是，团队依据当时对产品和市场的了解，以故事标题的形式完成一份产品待开发事项。无疑，整个开发工程中一旦要求发生变化，也会导致需求排列优先级的变更。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;在与客户的交流中，我被问得最多的问题之一是是否需要在敏捷开发过程中创建架构模型设计。和咨询公司一样，我的答复也是：视情况而定:)。围绕Big Design Upfront (BDUF), You Are Not Going to Need It (YAGNI)以及让团队在开始实施新功能时“重构”现有的代码/设计等所存在陷阱的争论也不少，其中有不少值得借鉴。尽管如此，我坚信设计初期存在这么一个阶段可以尽责地做架构设计以生成高端架构。例如，你打算建一个网上贷款流程的应用程序，你可能需要决定在这个架构里有几层。当然，能有这样一个基于最初要求的，并可能随着项目进展有所变更的架构是很重要的。在我看来，重构在敏捷开发中有其重要地位，但是如果是变更基础架构的“大重构”代价就太大了。如果大家感兴趣，我将在之后的文章中与大家探讨架构在敏捷软件开发过程中所扮演的角色。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;在我们团队所遵循的敏捷软件开发实践过程中，我们的项目被分解成类似Scrum的若干个四周sprints或迭代开发周期。尽管没有测试驱动开发(Test Driven Development)或结对编程(Pair Programming)，但我们的开发人员会编写单元或签入测试（Unit/Check-in Test）来检查功能，开发和测试工程师也会在一起调试、调查或评审某个特定问题和变更等。我们还会使用极限编程（eXtreme Programming）中的使用者故事（User Story）模式。事实上，我们的产品待开发事项和每个迭代周期中的待开发事项（Sprint Backlog）都会以故事的形式被追溯。这些使用者故事就是描述一个系统的最终用户会如何使用某个特定功能。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;通常，我们都会在一个Sprint阶段的最后一周计划下一个Sprint阶段：通常负责某个功能的团队（主要是主管们）会依据团队需要侧重的故事来进行由下至上的计划；然后再与产品利益相关者对项目中故事优先级的规划相协调；协调后的需求优先级清单一般会在Sprint的第一天完成。团队于是评估这些使用者故事，并完成设计初稿、实施成本，确认故事完成的标志。依据这个设计和成本，团队将承诺这个Sprint将完成的内容。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;今天先谈到这里，下一篇博客我将谈谈我们团队在Sprint阶段的运作。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;祝各位读者新年平安、喜乐！&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;Ramesh Rajagopal&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;Visual Studio Team Architect 中国团队经理&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;翻译：郑洁&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体&gt;校译:钱量&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9345138" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_E2561F9645658B4E_/default.aspx">团队故事</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_A74EC1540E4E80622F67_/default.aspx">产品与技术</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_4F657763005FD153_/default.aspx">敏捷开发</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_D18B8765_/default.aspx">译文</category></item><item><title>在微软开发软件的几个重要专业</title><link>http://blogs.msdn.com/stbcblog/archive/2008/02/22/product-development-disciplines-at-microsoft.aspx</link><pubDate>Fri, 22 Feb 2008 00:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7814475</guid><dc:creator>STB China Blog</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/stbcblog/comments/7814475.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stbcblog/commentrss.aspx?PostID=7814475</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=宋体 size=2&gt;[原文发表地址] &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/prakas/archive/2008/01/27/product-development-disciplines-at-microsoft.aspx" mce_href="http://blogs.msdn.com/prakas/archive/2008/01/27/product-development-disciplines-at-microsoft.aspx"&gt;&lt;FONT face=宋体 size=2&gt;Product Development Disciplines at Microsoft&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;[原文发表时间] &lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;Sunday, January 27, 2008 8:01 AM&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;过去几个月，我先后在中国数家知名大学举行了讲座，并会见了多位致力于数据平台研究的学术领头人和学生。我还在一些业界会议上发言，与用户、合作伙伴、分析师和其他同行会面。这些会议涉及了多个议题，例如，日新月异的科技发展趋势，异地分布式软件开发，以及亚洲的&lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;蓬勃发展&lt;/FONT&gt;&lt;FONT face=宋体 size=2&gt;。但有一个议题似乎得到了最大的关注——微软是如何组织和进行产品开发的？我想这很自然，微软是全球最成功的软件公司之一，而亚洲软件行业正经历其自身的飞速发展，因此业内人士迫切地希望了解我们过去20多年的经验也就在情理之中了。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;“微软是如何组织和进行产品开发”其实是一个很大的题目。在微软内部我们有一个卓越软件工程团队，主要为员工提供为期数日的课程，内容涉及微软软件开发方法概述、工程系统、组织架构、最佳实施办法，以及用以保证产品质量、可靠性及安全性的内部工具和技术等等。这并不意味着我们的体系已经十全十美，但我们的确积累了很多知识和经验可以与大家分享。实际上，我们也在以适当的方式与全球（包括亚洲）同行分享这些成功。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;因为这是一个大题目，我想在这篇文章里着重介绍我们工程系统中的一个方面，即我们研发团队的核心专业和每个专业在产品开发中所扮演的角色。因为我相信微软在这一方面的做法不同于我们的同行（即使在美国也是如此），尤其在中国，目前业界还没有充分理解这些核心专业及其所扮演的角色。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;微软的工程体系一直由三个核心专业组成：“开发（Development）＂，＂测试（Test）＂和＂项目管理（Program Management）＂，英文简称分别为＂Dev＂，＂Test＂和＂PM＂。在此，我将以另一个顺序作简单介绍：&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;&lt;U&gt;PM&lt;/U&gt;&lt;/STRONG&gt;：提及软件专业时，大多数人都马上想到"Dev" 。但是对我来说，一切则从项目管理开始。在微软，“PM” 意味着很多事情，对我而言，这个角色主要意味两件事：&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;１．了解用户的需求，并将其转换为用于开发的&lt;I&gt;功能说明（&lt;/I&gt;&lt;I&gt;functional specification&lt;/I&gt;&lt;I&gt;）&lt;/I&gt;。这是一切的开始，如果我们无法理解用户，我们就不能开发出合适的产品。 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2 ．协调Dev 和Test，将最初的功能说明转变成真正的产品。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;我发现很多人，特别是在中国，一听到”PM”就认为这是“Project Management”。事实上，这仅是PM工作的一部分（上述第２点）。PM真正的技能在于倾听用户并从他们的角度理解问题，然后设计出解决问题的方案。这并不意味着简单地为用户提供他们所需要的，而是在真正理解需求后设计最好的解决方案，即使这是连用户自己都从未想到的解决方案。常言道，如果我们一味地遵循用户的要求而只是去找寻一匹更快的马匹，那么汽车永远也不会诞生。 &lt;BR&gt;&lt;/FONT&gt;&lt;B&gt;&lt;U&gt;&lt;/U&gt;&lt;/B&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;U&gt;&lt;STRONG&gt;Dev&lt;/STRONG&gt;&lt;/U&gt;：三个专业中，Dev可能总是人们知道得最多的。他们负责实际设计和开发软件产品。Dev 的主要工作是实现PM制定的&lt;I&gt;功能说明&lt;/I&gt;。在系统级的、关键任务级的软件世界里，这个实现应该极为可靠、 安全、 便于管理、 可以扩展和高性能。Dev的设计和功能实现应经得起时间的考验，并在未来版本中得到重用。&lt;B&gt;&lt;U&gt;&lt;/U&gt;&lt;/B&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;B&gt;&lt;U&gt;&lt;FONT face=宋体 size=2&gt;&lt;/FONT&gt;&lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;&lt;U&gt;Test&lt;/U&gt;&lt;/STRONG&gt;：外界对微软测试工程师存在许多误解，内部有时也存在这个问题。多年前我刚进入微软时，我（愉快而）惊奇地发现在微软Tester的人数几乎和Developer同样多。在我之前服务的公司，测试人员要少很多（当然产品的质量会相对薄弱），因此在微软工作了一段时间后，我才真正了解测试专业的本质。在微软，我们何时可以发布产品并不取决于我们何时完成产品的设计和实现，而是取决于我们何时能完成产品测试。因为我们所发布的每个产品，尤其是系统类型的软件，必须通过一个极高的质量标准。测试专业的确是一个非常复杂的领域，一个Test必须花好几年时间才能掌握悟我们所应用的测试种类—— 单元测试、功能测试、集成测试、压力和远距测试、性能测试、安全性测试，以及本地化测试等。我们在测试中运且用的一整套工具和技术的复杂性令人印象深刻——自动测试套件，自动测试生成工具，自动检测故障分析工具，自动安全模糊测试和基于状态机的测试。&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;以上三个核心工程专业就像一张3条腿的凳子——一个也不能少，并且需要一个合适的工程组织保持其平衡。没有一方可以凌驾于其他任何一方，否则这个组织就无法与客户需求保持一致，或者无法在产品质量上下足功夫。这 3个专业类似政府部门间的制衡机制，这套机制确保了我们能理解客户需要，设计高品质产品，同时每个发布的产品都在各方面满足顾客的期望。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;这里需要强调的是，我们一直在招募这三个领域最优秀的人才，他们的招聘条件同样严格，只是每个领域的技能和关注方面有所差异。PM通常热衷与客户一起构思应该设计什么样的产品，然后与Dev和Test同事协作完成所需要的产品。Dev对设计高品质软件更富有激情 —— 产品应是革新的、简单的、可靠的、安全的、可扩展的、高性能的并能经受起时间考验。Test则爱好，&lt;I&gt;在我们向客户发布产品前&lt;/I&gt;，竭尽所能找寻出软件中所存在的所有问题和漏洞。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=宋体&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;我们的面试官有一项非常重要任务，就是找出应聘人员的才能和激情所在，然后引导他们向那个方向发展。当然，在个人职业生涯中激情和才华可能发生改变，员工个人也可能因为从事的工作领域不同而有所改变——我本人就曾是从Dev转为PM。这是很自然的，我们实际上也鼓励这种做法以构建更好的队伍。 &lt;BR&gt;&lt;/FONT&gt;&lt;B&gt;&lt;/B&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;B&gt;&lt;FONT face=宋体 size=2&gt;其他领域&lt;/FONT&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;除了以上三个历来被视为微软“核心”的专业，另外几个专业也变得日益重要。例如，使产品使用更自然、直观的用户体验专家（User Experience，简称UX）。良好的用户使用体验能让人爱上一件产品，反之则甚至可以让用户不愿去触碰它。用户体验无疑对为终端用户设计的产品至关重要，同时对我们的开发人员、 I T专业人士以及信息工作者而言也是如此。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;当我们进入“软件+服务“的时代，各种与构架、开发和运行极大型基础设施的领域变得越来越重要。需要重申的是，这些曾经只存在MSN和Live 等网络产品开发过程的专业，现在对&lt;EM&gt;所有产品组&lt;/EM&gt;都变得日益关键，因为他们正逐步将产品融入这个 “软件+服务”的新模式。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;很多应聘人员问我在微软什么样的角色更适合他们，以及如何发展他们的职业。我能想到的最好建议是在他们真正热衷的一个技术或角色上下功夫。正如我刚才说过，我们对所有专业同等对待，一个均衡的组织需要在各个领域上都有突出人才。尽管不同专业需要不同专业技能和爱好的人才，但&lt;U&gt;所有专业&lt;/U&gt;都存在创新和有所作为的机会。所有领域都提供了技术晋升和管理晋升的阶梯。事实上，如果你留意微软高层管理人员会发现他们中有从各种领域脱颖而出的 —— 他们的共同点是热爱他们所从事的工作。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;我希望本次讨论对那些对此感兴趣的人有帮助，如果你有问题请随时在这篇文章之后留言。&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=left&gt;&lt;FONT face=宋体 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;下次再聊 -- 再见！&lt;/FONT&gt;&lt;/P&gt;
&lt;P align=right&gt;&lt;FONT face=宋体 size=2&gt;Prakash (孙博凯)&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7814475" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_E2561F9645658B4E_/default.aspx">团队故事</category><category domain="http://blogs.msdn.com/stbcblog/archive/tags/_D18B8765_/default.aspx">译文</category></item></channel></rss>