当前位置: 首页 > news >正文

做网站项目所需资源小程序推广的十种方式

做网站项目所需资源,小程序推广的十种方式,电信宽带做网站服务器吗,深圳保障性住房在哪里申请持续交付#xff1a;发布可靠软件的系统方法#xff08;五#xff09; 第二部分——部署流水线第 5 章 部署流水线解析5.1 引言5.2 什么是部署流水线5.3 部署流水线的相关实践5.3.1 只生成一次二进制包5.3.2 对不同环境采用同一部署方式5.3.3 对部署进行冒烟测试5.3.4 向生产… 持续交付发布可靠软件的系统方法五 第二部分——部署流水线第 5 章 部署流水线解析5.1 引言5.2 什么是部署流水线5.3 部署流水线的相关实践5.3.1 只生成一次二进制包5.3.2 对不同环境采用同一部署方式5.3.3 对部署进行冒烟测试5.3.4 向生产环境的副本中部署5.3.5 每次变更都要立即在流水线中传递5.3.6 只要有环节失败就停止整个流水线 5.4 提交阶段5.5 自动化验收测试之门5.6 后续的测试阶段5.6.1 手工测试5.6.2 非功能测试 5.7 发布准备5.7.1 自动部署与发布5.7.2 变更的撤销5.7.3 在成功的基础上构建 5.8 实现一个部署流水线5.8.1 对价值流进行建模并创建简单的可工作框架5.8.2 构建和部署过程的自动化5.8.3 自动化单元测试和代码分析5.8.4 自动化验收测试5.8.5 部署流水线的演进 5.9 度量5.10 小结 第二部分——部署流水线 第 5 章 部署流水线解析 5.1 引言 对于大多数项目来说采纳持续集成实践是向高效率和高质量迈进的一大步。它保证那些创建大型复杂系统的团队具有高度的自信心和控制力。一旦代码提交引入了问题持续集成就能为我们提供快速的反馈从而确保我们作为一个团队所开发的软件是可以正常工作的。它主要关注于代码是否可以编译成功以及是否可通过单元测试和验收测试。但持续集成并不足以满足我们的需要。 持续集成的主要关注对象是开发团队。持续集成系统的输出通常作为手工测试流程和后续发布流程的输入。在软件的发布过程中很多浪费来自于测试和运维环节。例如我们常常看到 构建和运维团队的人员一直在等待说明文档或缺陷修复测试人员等待“好的”版本构建出来在新功能开发完成几周之后开发团队才能收到缺陷报告开发快完成时才发现当前的软件架构无法满足该系统的一些非功能需求。 当然我们能找到很多种能很快得到收益的方法来渐进改善软件交付过程比如教开发人员如何才能写出可以随时在生产环境上运行的软件在类生产环境中进行持续集成以及组建跨功能团队等。然而尽管这种实践肯定会让情况得到改善但它们无法帮助你洞悉哪里是交付流程的瓶颈以及如何进行优化。 解决方案就是采取一种更完整的端到端的方法来交付软件。在前面几章中我们已经解决了配置管理以及自动化大量构建、部署、测试和发布流程的很多问题。现在我们通常能通过一键式方式把软件的某个版本部署好甚至可以将其一键式部署到生产环境中这样就建立了一个非常有效的反馈环——由于很容易将应用程序部署到测试环境中所以团队可以同时得到软件功能和部署流程两个方面的快速反馈。因为部署流程无论是在开发机器上部署还是为最后发布而进行的部署是自动化的所以可以频繁且有规律地运行并被测试从而降低发布风险也降低了向开发团队传递有关部署流程的知识时的风险。 从精益的角度来看我们实现了一个“拉式系统”pull system即测试团队只要自己单击按钮就能将某个特定的软件版本部署到测试环境中。运维人员也可以通过单击一下按钮就把软件部署到试运行环境和生产环境中。在整个发布流程中开发人员能看到每个目标环境上部署了哪个版本发现了哪些问题。管理人员也很容易就能看到一些关键的度量指标比如周期时间cycle time吞吐量throughput以及代码质量等。整个交付过程中的所有人都因此具有两种能力即他能使用任何他想使用的东西也能看到整个发布流程从而可以改善反馈循环识别、优化并解决瓶颈。这样就形成了一个更加快速且更加安全的交付流程。 实现端到端的自动化构建、部署、测试和发布流程会带来一些连锁反应还会带来一些意料之外的收益。通过在很多项目里使用这种技术我们找到了这些项目中各种部署流水线系统之间的共同点。而且通过这种抽象总结出来的一些通用模式在我们尝试过的项目中都获得了成功。这种抽象使我们在项目开始就能很快建立一个相当成熟且能快速运行的构建、测试和部署系统。在交付项目里这种端到端的部署流水线系统使我们获得了一定程度的自由和灵活性而这在几年前是根本无法想象的。我们确信这种方法能让我们以更高的质量和相当低的成本与风险来创建、测试、部署复杂系统。 这正是部署流水线的功用。 5.2 什么是部署流水线 从某种抽象层次上讲部署流水线是指软件从版本控制库到用户手中这一过程的自动化表现形式。对软件的每次变更都会经历一个复杂流程才能发布。这一流程包括构建软件以及后续一系列不同阶段的测试与部署而这些活动通常都需要多人或者多个团队之间的协作。部署流水线是对这一流程的建模在持续集成和发布管理工具上它体现为支持查看并控制整个流程包括每次变更从被提交到版本控制库开始直到通过各类测试和部署再到发布给用户的过程。 因此这个由部署流水线建模而成的流程从代码提交到软件发布的这个流程实际上就是“将客户或用户脑中的一个想法变成其手中真实可用的特性”这一过程的一部分而整个流程从概念到概念兑现可以用一个价值流图来描述。关于创建新产品的一个抽象价值流图如图5-1所示。 这个价值流图讲述了一个故事。整个过程一共需要大约三个半月的时间其中真正的工作时间只有大约两个半月其余时间都是从概念到概念兑现整个流程中各阶段之间的等待时间。例如在开发完成首次要发布的版本与测试开始之间有五天的等待时间。这个时间有可能是将应用部署到某个类生产环境上所需的时间。顺便说一句图中故意没有表明该产品是否为迭代开发。如果是迭代开发流程开发阶段本身就会包含几个迭代而每个迭代都包括测试和演示。而且从发现到发布这个过程也会被重复很多次。 本书中我们仅讨论从开发到发布的价值流也就是图5-1中的阴影部分。这部分价值流的一个关键不同点在于会有很多次构建通过这一流程走向最后的发布。要理解部署流水线以及代码变更在其上流动的方法是把它看成一个序列图如图5-2所示。 请注意流水线的输入是版本控制中的某个具体版本。每次变更都会生成一次构建这个构建像神话中的英雄一样闯过一系列的测试希望成为一个能到达生成环境中的发布版本。在这一系列的测试阶段中每个阶段都从不同的角度评估这个构建版本且和持续集成一样它的起点是向版本控制库的每一次提交。 随着某个构建逐步通过每个测试阶段我们对它的信心也在不断提高。当然我们在每个阶段上花在环境方面的资源也在不断增加即越往后的阶段其环境与生产环境越相似其目的就是在这个过程中尽早发现那些不满足发布条件的构建版本并尽快将失败根源反馈给团队。一般来说只要某个构建使无论是这一流程中的哪个阶段失败了它都不会进入下一个阶段。这在图5-3中有所反映。 使用这种模式的话有些非常重要的积极影响。 首先它可以有效地阻止那些没有经过充分测试或不满足功能需求的版本进入生产环境也能避免回归缺陷尤其是对于那些需要紧急修复并部署到生产环境的情况因为和其他变更一样这种紧急修复版本也需要走同样的流程。根据我们的经验最新发布的软件由于系统组件和其环境之间的未预期交互导致出现故障的事情是很常见的比如使用了新的网络拓扑结构或者生产环境的服务器在配置方面有些许不同。部署流水线的纪律会缓解这种现象。其次当部署和产品发布都被自动化之后这些活动就变成快速、可重复且可靠的了。一旦被自动化发布工作会变得非常容易以至于会变成一件“平常”事即只要你愿意就可以做频繁发布。另外如果支持自动安全回滚发布风险也会大大降低那么频繁发布就更不成问题了。一旦具有这种能力发布就根本不会有什么风险了。最不济也就是引入一个严重缺陷可这时只要回滚到之前没有缺陷的那个版本然后在线下修复这个缺陷就可以了没什么大不了的详见第10章。 为了达到这种令人羡慕的状态我们必须把那些用于证明某些版本满足业务要求的测试集合进行自动化。而且我们还要把测试环境、试运行环境和生产环境上的部署过程自动化这样可以避免那些手工密集型的易出错的步骤。对于很多系统来说可能还需要其他形式的测试或者阶段但对所有项目有一些阶段是共同具有的。 提交阶段是从技术角度上断言整个系统是可以工作的。这个阶段会进行编译运行一套自动化测试 (主要是单元级别的测试)并进行代码分析。自动化验收测试阶段是从功能和非功能角度上断言整个系统是可以工作的即从系统行为上看它满足用户的需要并且符合客户的需求规范。手工测试阶段用于断言系统是可用的满足了它的系统要求试图发现那些自动化测试未能捕获的缺陷并验证系统是否为用户提供了价值。这一阶段通常包括探索性测试、集成环境上的测试以及UATUser Acceptance Testing用户验收测试。发布阶段旨在将软件交付给用户既可能是以套装软件的形式也可能是直接将其部署到生产环境或试运行环境这里的试运行环境是指和生产环境相同的测试环境。 部署流水线就是由上述这些阶段以及为软件交付流程建模所需的其他阶段组成有时候也称为持续集成流水线、构建流水线、部署生产线或现行构建living build。无论把它叫做什么从根本上讲它就是一个自动化的软件交付流程。这并不是说该发布过程不需要人的参与而是说在执行过程中那些易出错且复杂的步骤被变成可靠且可重复的自动化步骤。事实上人工参与的活动反而有增加的趋势因为在开发流程中所有阶段均可进行一键式部署这一事实会促使测试人员、分析人员、开发人员以及最重要的用户更频繁地执行它。 最基本的部署流水线 图5-4中显示了一个典型的部署流水线体现了这种方法的本质。当然一个真正的流水线应该反映真实的软件交付流程。 这个流程的起点是开发人员向版本控制库提交代码。此时持续集成管理系统对这次提交作出响应触发该流水线的一个实例。 第一个提交阶段会编译代码运行单元测试执行代码分析创建软件二进制包。如果所有的单元测试都通过了并且代码符合编码标准就将可执行代码打包成可执行文件并放到一个制品库artifact repository中。时新的持续集成服务器都提供保存这种过程产物的功能并让用户和流水线的后续阶段能以某种非常简便的方式获取并使用。另外还有很多像Nexus和Artifactory这样的工具可帮助管理这类过程产物。在提交阶段你也许还会执行另外一些任务比如为验收测试准备测试数据库。时新的持续集成服务器都支持通过构建网格并行执行这些任务。第二个阶段通常由运行时间较长的自动化验收测试组成。因此持续集成服务器最好支持将测试分成多组的做法以便在构建网络中并行执行任务这样会提高执行效率使你更快地得到反馈通常要在一两个小时之内返回结果。这个阶段应该是流水线中第一个阶段成功完成以后自动触发的。 在此之后部署流水线可能会有分支出现这样就可以将该构建版本独立部署到多个不同的环境中比如部署到用户验收测试环境、容量测试环境和生产环境。通常情况下我们并不需要在验收测试阶段成功之后直接自动触发这些阶段。相反我们希望让测试人员或运维人员可以做到自服务即自己手工选择需要的某个版本并将其部署到相应的环境中。 要将同样的原则应用于后续阶段仅仅有一点不同即不同阶段的使用者拥有各自的环境权限所以只有那些具有相应权限的人才能通过自服务方式部署该应用到各自的环境中。比如运维团队可能希望自身是唯一有权在对生产环境进行部署的部署工单上签字的一方。 最后一定要记住我们所做的这一切都是为了尽快得到反馈。为了加速这个反馈循环就必须能够看到每个环境中都部署了哪个版本每个构建版本在流水线中处于哪个阶段。图5-5产品Go的截屏展示了这个实践是什么样子的。 你可能已经注意到每次提交都列在了页面的一侧并显示出了每次提交分别走到了流水线中的哪个阶段以及相应的每个阶段是否成功了。要能够将某次代码提交、构建版本与其在部署流水线上通过了哪些阶段关联在一起这一点是非常必要的。因为这样你就能立刻发现是哪次代码提交造成了本次验收测试的失败。 5.3 部署流水线的相关实践 接下来我们将讨论部署流水线中每个阶段的细节。在开始之前为了能够获得该方法带来的好处你需要遵循一些实践。 5.3.1 只生成一次二进制包 方便起见我们将所有可执行代码的集合称作二进制包例如Jar文件、.NET 程序集和.so文件。有时候代码根本不需要编译那么这种情况下二进制包就是指所有源文件的集合。 很多构建系统将版本控制库中的源代码作为多个步骤中最权威的源不同上下文中会重复编译这个源比如在提交时、做验收测试时或做容量测试时。而且在每个不同的环境上部署时都要重新编译一次。但是对于同一份源代码每次都重新编译的话会引入“编译结果不一致”的风险。在后续阶段里其编译器的版本可能与提交阶段所用版本不一致。对于第三方库你可能会不小心使用了本未打算使用的版本。甚至编译器的配置都会对应用程序的行为产生影响。我们曾遇到过由于上述原因导致在生产环境中出现问题的情景。 一种相关的反模式就是一直使用源代码而不是二进制包。 这种反模式违反了两个重要原则。 第一个原则就是“保证部署流水线的高效性使团队尽早得到反馈”。重复编译违反了这一原则因为编译需要花时间在大型软件系统中进行的编译尤其如此。第二原则就是“始终在已知可靠的基础上进行构建”。被部署到生产环境中的二进制包应该与通过前面验收测试流程的二进制包是完全一样的。在很多实际使用的流水线里每次生成二进制包时都会存储其散列并在后续每个阶段中利用这个散列对二进制包进行验证。 假如重新创建二进制包就会存在这样的风险即从第一次创建二进制包到最后发布这两个时间点之间会引入某种变化比如在不同阶段里编译时所用的软件工具链有差异此时这个即将发布的二进制包就不是我们曾经测试过的那个二进制包了。出于审计的目的确保从二进制包的创建到发布之间不会因失误或恶意攻击而引入任何变化是非常关键的。如果是解释性语言的话有些组织甚至要求只有资深人员才有权在某个特定的环境里进行编译、组装或打包其他人不得插手。所以一旦创建了二进制包在需要时最好是重用而不是重新创建它们。 5.3.2 对不同环境采用同一部署方式 为了确保构建和部署流程被有效测试在各种环境中使用相同流程对软件进行部署是非常必要的这些环境即包括开发人员或分析人员的工作站也包括测试环境和生产环境。显然部署风险与部署频率成反比。部署频率最低的环境生产环境却是最重要的。因此只有在很多环境中对部署过程测试过数百次以后我们才能消除那些由于部署脚本错误而导致的问题。 只要把那些与特定环境相关的特定配置分开放置就行了。一种方法是使用属性文件保存配置信息比如分别为每个环境保存一个属性文件并将其放在版本控制库中。在部署时通过本地服务器的主机名来查找正确的配置而如果是在有多台服务器的环境中可以将环境变量提供给部署脚本使用。当然还有一些其他方法提供部署时的配置信息比如将其放在一个目录服务中LDAP或ActiveDirectory也可以将其放在数据库中通过像ESCAPE这样的工具来访问它。 在同一个源一个版本控制库、一个目录服务或一个数据库中找到所有环境中运行的所有应用程序的配置信息是完全可行的。 如果你所在的公司里管理生产环境的团队与负责开发和测试的团队不是同一个团队那么这两个团队就要在一起工作确保自动化部署过程在所有环境中都是有效的包括开发环境在内。能够使用相同的脚本向开发环境和生产环境部署是避免“它在我的机器上可以工作”病症的法宝 如果对于不同的环境其部署脚本也不相同的话你就无法知道某个测试过的脚本是否在上线部署时还能正常工作。相反如果使用同一个脚本在所有的环境上进行部署那么当在某个环境上部署失败时就可以确定其原因一定来自以下三个方面 与该环境相关的配置文件中某项配置有问题基础设施或应用程序所依赖的某个服务有问题环境本身的配置有问题。 那么到底是哪个原因呢这是接下来的两个实践需要解决的问题。 5.3.3 对部署进行冒烟测试 当做应用程序部署时你应该用一个自动化脚本做一下冒烟测试用来确保应用程序已经正常启动并运行了。这个测试应该非常简单比如只要启动应用程序检查一下能看到主页面并在主页面上能看到正确的内容就行了。这个冒烟测试还应该检查一下应用程序所依赖的服务是否都已经启动并且正常运行了比如数据库、消息总线或外部服务等。 一旦有了单元测试之后这种冒烟测试部署测试可能就是你要马上着手做的最重要测试了甚至可以说是最最重要的测试。因为它可以让你对“应用程序可以运行起来”建立信心。如果应用程序不能运行这个冒烟测试应该能够告诉你一些最基本的诊断提示比如应用程序无法运行是否是因为其依赖的外部服务无法正常工作。 5.3.4 向生产环境的副本中部署 很多团队实际部署应用上线时可能遇到的另一个主要问题是生产环境与他们的开发环境或测试环境有非常大的差异。为了对系统上线充满信心你要尽可能在与生产环境相似的环境中进行测试和持续集成。 理想情况下如果生产环境非常简单或者有足够多的预算我们完全可以建立与生产环境一模一样的环境用于运行手工测试或自动化测试。另外要想确保所有的环境都一样需要有很多纪律保障良好的配置管理实践。你要确保 基础设施是相同的比如网络拓扑和防火墙的配置等操作系统的配置包括补丁版本都是相同的应用程序所用的软件栈是相同的应用程序的数据处于一个已知且有效的状态。系统升级过程中需要进行的数据迁移是部署活动的一个痛点我们将在第12章讲这个问题。 你可以使用像磁盘镜像或虚拟化技术这类实践以及Puppet、InstallShield这类工具和某个版本控制系统共同管理环境配置。我们将在第11章详细讨论这个问题。 5.3.5 每次变更都要立即在流水线中传递 在持续集成出现之前很多项目都有一个各阶段的执行时间表比如每小时构建一次每天晚上运行一次验收测试每个周末运行一次容量测试。部署流水线则使用了不同的方式每次提交都要触发第一个阶段的执行后续阶段在第一个阶段成功结束后立即被触发。当然假如某些阶段需要花较长的时间而开发人员尤其是在大型团队中的提交又非常频繁就很难做到这一点了。图5-6中就显示了这样做的问题。 在本例中某人将代码提交到版本控制库生成了版本1并且触发了流水线的第一个阶段构建及单元测试。这一阶段通过之后紧接着触发了第二个阶段——自动化验收测试。此时另一个人提交了另一个修改在版本库中生成了版本2流水线中的第一个阶段构建及单元测试被再次触发。然而即便这次构建也通过了它仍无法触发下一个自动化验收测试因为有一个自动化验收测试正在运行。与此同时又有两个新的版本被提交。可是持续集成系统不能同时构建它们两个如果遵循这个原则而开发人员继续以同样的速率提交代码的话构建就会越来越落后于开发人员的开发速度。 另一种构建策略是一旦代码构建和单元测试结束持续集成系统就去检查版本库中是否有新的提交。如果有的话就将最近还没有构建过的所有变更全部拿来进行构建即对版本4进行构建。假设这次构建和单元测试失败了那么构建系统是无法知道究竟是哪个版本版本3还是版本4引起的但开发人员自己可以很容易发现问题在哪儿。有些持续集成系统可以让你执行某个特定版本的构建而无需按顺序执行。假如持续集成服务器有这种功能的话开发人员就可以运行一次对版本3的构建和单元测试看版本3是否能够通过测试这样就可以弄清楚到底是哪个版本引入了问题。无论哪种方法开发人员会提交版本5来修复这个构建。这样当验收测试结束以后持续集成系统的调度程序发现版本5已经通过了第一阶段的测试就会直接触发针对版本5的验收测试。 这种聪明的调度方法对于实现部署流水线来说是非常关键的。一定要确保持续集成服务器支持这种调度方式事实上很多持续集成服务器都支持这种调度方式而且要确保每次变更都能立即在流水线中传递这样就不用按固定的时间表来执行不同的阶段了。 目前这些策略只能用于那些完全自动化的阶段比如包含自动化测试的阶段而流水线中后续的那些为手工测试环境执行部署的阶段就要按需激活 5.3.6 只要有环节失败就停止整个流水线 就像我们在3.2节中所说的为了达到本书所描述的目标迅速、可重复且可靠的发布对于团队来说最重要的是要接受这样的思想每次提交代码到版本控制系统中后都能够构建成功并通过所有的测试。对于整个部署流水线来说都适用这一要求。假如在某个环境上的某次部署失败了整个团队就要对这次失败负责应该停下手头的工作把它修复后再做其他事情。 5.4 提交阶段 每次提交都生成部署流水线的一个新实例。如果提交阶段的测试通过了这个版本就被视为一个候选发布版本。部署流水线中第一个阶段的目标就是消除那些不适合生产环境的构建并尽早给团队一个信号——“应用程序出错了”。我们不想在那些明显有问题的版本上花时间和精力所以当开发人员提交变更到版本控制系统后我们希望尽快地评估一下这个最新版本。提交者要一直等到构建结果然后才能做下一项工作。 在提交阶段我们需要做以下几件事。这些任务通常作为一个工作集合运行在构建网格上大多数持续集成服务器都提供类似功能这样提交阶段就能够在一个可接受的时间之内完成最好在五分钟之内完成最多不能超过十分钟。一般来说提交阶段包含以下步骤 编译代码如果所用开发语言需要的话运行一套提交测试为后续阶段创建二进制包执行代码分析来检查代码的健康状况为后续阶段做准备工作比如准备一下后续测试所用的数据库。 测试非功能特性比如容量可能比较困难但仍旧可以通过一些分析工具收集一些关于当前代码库的测试覆盖率、可维护性以及安全漏洞方面的信息。为这些度量项设定一个阈值并像对待测试一样一旦不满足阈值条件就让提交阶段失败。比较有用的度量项包括 测试覆盖率如果提交测试只覆盖了代码库的5%那么这些测试发挥不了太大的作用重复代码的数量圈复杂度cyclomatic complexity输入耦合度afferent coupling和输出耦合度efferent coupling编译警告的数量代码风格。 如果前面这些任务都成功了提交阶段的最后一步就是生成二进制包用于后续阶段的部署。当然只有这步也成功了提交阶段才能算成功。把生成可执行代码作为成功的验收条件是确保构建流程本身也能够被持续集成系统不断评估和检查的简单方法。 提交阶段最佳实践 在第3章中所描述的实践大多数都适用于提交阶段。开发人员需要一直等到部署流水线的提交阶段成功完成。如果它失败了开发人员要么快速修复问题要么将刚提交的代码回滚。在理想情况下无限的处理能力和无限的网络带宽我们希望开发人员能够一直等到所有测试甚至是手工测试全部通过这样一旦出现问题就可以马上修复。然而这并不现实因为部署流水线的后续阶段自动化验收测试、容量测试和手工验收测试都需要相对较长的时间。这也是规范测试流程的一个理由因为当缺陷还比较容易修复时尽快得到反馈是非常重要的而不应花更大的代价得到全面的反馈。 5.5 自动化验收测试之门 全面的提交测试套件对于发现许多种错误来说是非常优秀的试金石。然而有很多类型的错误是它无法捕获的。在提交测试集合中大部分是单元测试而单元测试与底层的API是紧耦合的以至于开发人员难免落入一个陷阱即“用某种特殊方式来证明解决方案是正确的”而不是断言它解决了某个具体问题。 每次提交后就立即运行提交测试的意义在于它能为最新的一次构建或程序中可能存在的一些较小的代码问题提供及时反馈。然而如果没有在类生产环境上执行验收测试我们就根本不知道该应用程序是否符合了客户规范也不知道它在现实世界中是否能够部署并运行。如果想在这些方面得到及时反馈的话就必须在持续集成流程中引入更多测试并不断对系统各个方面进行演练。 这个自动化验收测试关卡是识别候选发布版本过程中第二个重要的里程碑。部署流水线只允许后续阶段比如需要手工干预的手工部署阶段获取那些已通过自动化验收测试的构建版本。我们当然可以不遵循这样的机制但可能会导致大量时间和精力的消耗。如果能把这些时间和精力花在修复那些已被部署流水线发现的问题上花在以受控的可重复方式进行的部署工作上不是更好吗在部署流水线的帮助下我们更容易做正确的事情。 因此如果一个候选版本不能满足所有的验收条件就根本不会被交给用户 自动化验收测试最佳实践 实际上就像整个团队负责流水线的每一个阶段一样整个团队都是验收测试的所有者。如果验收测试失败了整个团队都要停下来马上修复它。 这一实践的一个重要推论是开发人员必须能在自己的开发环境中运行自动化验收测试。这样开发人员在发现验收测试失败后就很容易在自己的机器上修复它然后在本地再次运行验收测试来验证修复。对于这个实践来说最常遇到的障碍是没有足够多的测试软件授权应用程序的架构不允许将其部署到开发环境中以至于无法运行验收测试。如果你的自动化验收测试策略是为长远打算的话就应该尽早清除这类障碍。 5.6 后续的测试阶段 验收测试阶段是整个遴选候选发布版本过程中的一个重要里程碑。一旦这个阶段结束了这个候选版本就会受到开发人员之外更多人的广泛关注。 对于最简单的部署流水线来说至少就系统的自动化测试而言一个构建版本通过了验收测试就能够发布给用户了。如果某版本在验收测试阶段失败了根据定义它是不能发布的。 5.6.1 手工测试 在迭代开发过程中验收测试之后一定会有一些手工的探索性测试、易用性测试和演示。在此之前开发人员可能已经向分析师和测试人员演示了应用程序的功能但一定是在自动化测试通过之后。在这个过程中测试人员所扮演的角色并不是回归测试该系统而是首先通过手工证明验收条件已被满足从而确保这些验收测试的确是验证了系统行为。 之后测试人员会做一些机器不太擅长而人比较擅长的测试。他们做探索性测试、易用性测试在不同平台上测试程序的界面是否正确并着眼于一些不可控制的最坏情况进行测试。自动化验收测试使测试人员节省出更多的时间做那些高价值的活动而不是测试脚本的人力执行器。 5.6.2 非功能测试 每个系统都有很多非功能需求。比如几乎每个系统都有容量和安全性方面的要求或者必须遵守服务水平协议等。通常应该用某些自动化测试衡量应用程序是否满足这些需求。如何能够做到这一点呢请参见第9章。对于某些系统并不需要连续不断地做非功能需求测试。根据我们的经验如果需要的话完全可以在部署流水线中创建一个阶段用于运行这些自动化的非功能测试。 在定义部署流水线结构时必须回答一个问题即容量测试阶段的结果是可以作为一个门槛还是需要由人来决定对于高性能应用来说可以在验收测试阶段通过之后就运行容量测试作为该版本整个自动化测试的输出结果。如果这个版本不能通过容量测试就不能把它看成是可部署的版本。 然而对于很多应用程序来说判定“什么是可接受的”更加具有主观性。通常根据实际容量测试阶段的结果由人来判定该版本是否可以作为候选版本来部署会更有意义 5.7 发布准备 每次向生产环境发布时都有业务风险。一旦在发布时发生严重问题可能最好的结果就是推迟部署有价值的新功能而最糟糕的结果就是出了问题却没有合适的撤销计划这可能导致关键业务无法运行因为新版本中已经替换了原有版本的关键功能。 缓解这类风险非常简单只要把这个发布环节视为部署流水线的一个自然结果就行。实际上我们只需要 让参与项目交付过程的人共同创建并维护一个发布计划包括开发人员和测试人员以及运维人员基础设施和支持人员通过尽可能多的自动化过程最小化人为错误发生的可能性并从最容易出错的环节开始实现自动化在类生产环境中经常做发布流程演练这样就可以对这个流程及其所使用的技术进行调试如果事情并没有按计划执行要有撤销某次发布的能力作为升级和撤销过程的一部分制定配置迁移和数据迁移的策略。 我们的目标是实现一个完全自动化的发布过程。发布就应该简单到这种程度即只要选择一个需要发布的版本单击一下按钮就万事大吉了。撤销也应该同样简单。 5.7.1 自动部署与发布 对生产环境的控制权越小遇到意外情况的可能性就越大。因此无论何时发布软件系统我们都希望有完全的控制权。然而这里至少有两方面的约束。 首先对于很多应用程序来说你根本不能完全控制应用程序所在的运行环境。对于由用户自行安装的软件比如游戏或者办公软件来说这一点是必然的。通常解决这个问题的办法就是选择一些具有代表性的目标环境并分别在这些样本环境上执行自动化验收测试套件。这样就能通过收集结果数据发现哪些测试在哪些平台上无法正常运行了。第二个约束就是人们通常认为为了达到完全控制环境所付出的成本会高于因此得到的收益。然而事实常常恰好相反。生产环境中的大多数问题往往是由不充分的控制导致的。正如我们在第11章中所讲的生产环境应该是完全受控的即对生产环境的任何修改都应该通过自动化过程来完成。这不仅包括应用程序的部署还包括对配置、软件栈、网络拓扑以及状态的所有修改。只有在这种方式下我们才可能对它们进行可靠地审计和问题诊断并在可预计的时间内修复它们。随着系统复杂性的增加不同类型服务器的增多以及不断提高的性能需求我们就更需要这种程度的控制力。 管理生产环境的流程也应该用于测试环境比如试运行环境、集成环境等。通过这种方式就可以利用自动化变更管理系统来为手工测试环境创建一个完全一致的配置信息。根据容量测试的结果对配置进行不断的评估和调整就会得到一个非常完美的配置。当满意后就能在这种可预测且可靠的方式下把这份配置放在每个需要这种配置的服务器上也包括生产环境上的服务器。环境的所有方面都应该以这种方式来管理包括中间件如数据库、Web服务器、消息代理和应用服务器等。每个配置都能够被调整并把可选设置加到配置基线中。 通过自动化的环境准备和管理、最佳的配置管理实践以及虚拟化技术如果适用的话环境准备和维护的成本会显著降低。一旦环境配置被正确地管理起来了就可以部署应用程序了。尽管很多实现细节更多地依赖于系统所使用的技术但步骤基本上是相似的。这种方法与我们用来创建构建脚本和部署脚本以及监控流程的方法相似。创建构建脚本与部署脚本的方法将在第6章中加以讨论。 5.7.2 变更的撤销 传统上人们对新版本的发布常常存在着恐惧心理原因有两个。一是害怕引入问题因为手工的软件发布过程很可能引入难以发现的人为错误或者部署手册本身就隐藏着某个错误。二是担心由于发布过程中的一个问题或新版本的某个缺陷使你原来承诺的发布失败。无论是哪种情况你的唯一希望就是足够聪明且非常迅速地解决这个问题。 我们可以通过每天练习发布多次来证明自动化部署系统是可以工作的这样就可以缓解第一种问题。对于第二个问题可以准备一个撤销策略。最糟的情况也就是回滚到发布之前的状态这样你就有足够的时间评估刚发现的问题并找到一个合理的解决方案。 对于很简单的应用程序来说这是可以做到的忽略数据和配置信息的迁移只要把每个版本都放在一个单独的目标中再使用符号链接指向当前版本就行了。最复杂的情况就是在部署和撤销中涉及生产数据的迁移。 **撤销流程绝不应该与部署流程、增量部署流程或回滚流程有什么不同。然而这些流程可能很少被测试所以也就不可靠。**而且这些流程也很少基于某个已知良好的版本基线所以也就比较脆弱。因此一定要让旧版本保持同步运行一段时间或者在必要时完全重新部署某个已知良好的旧版本。 5.7.3 在成功的基础上构建 当一个候选发布版本能够部署到生产环境时我们就确信 代码可以编译代码能够按开发人员的预期运行因为它通过了单元测试系统能够满足分析人员或用户预期因为它通过了所有的验收测试基础设施的配置和基线环境被恰当地管理了因为应用程序在模拟的生产环境上通过了测试系统所有的正确组件都就绪了因为它是可以部署的部署脚本也是可以工作的因为在该版本到这一阶段之前部署脚本至少在开发环境中用过一次在验收测试阶段用过一次在测试环境中用过一次我们需要部署的所有内容都在版本控制库中而且不需要手工干预因为我们已经部署这个系统好几次了。 这种“在成功的基础上构建”的方法, 完全符合我们常挂在嘴边的口头禅“尽快让这个流程或其任何环节失败”这在任何层次都是有用的。 5.8 实现一个部署流水线 无论是从零创建新项目还是想为已有的系统创建一个自动化的流水线通常都应该使用增量方法来实现部署流水线。接下来我们将描述如何从无到有建立一个完整流水线的策略。一般来说步骤是这样的 对价值流建模并创建一个可工作的简单框架将构建和部署流程自动化将单元测试和代码分析自动化将验收测试自动化将发布自动化。 5.8.1 对价值流进行建模并创建简单的可工作框架 正如本章开始所描述的第一步就是画出从提交到发布整个过程的价值流图。如果项目已经建好并开始运行你在半个小时内就能画完。然后和参与其中的每个人聊一下记录下流程中的每个步骤包括对经历时间elapsed time和增值时间value-added time的最佳估计值。如果是还没有启动的新项目就要先设计一个合适的价值流可以在同一组织中找个与你的项目相似的项目思考它的价值流也可以从最简单的价值流开始即第一个阶段是提交阶段用来构建应用程序并运行基本的度量和单元测试第二个阶段用来运行验收测试第三个阶段用来向类生产环境部署应用以便用它来做演示。 一旦有了价值流图就可以用持续集成和发布管理工具对流程建模了。如果所用工具不支持直接对价值流建模的话可以使用“项目间依赖”来模拟它。首先这些项目应该什么也不做而只是作为可以被依次触发的占位符。如果是使用“最简单模型”每当有人提交代码到版本控制系统时就应该触发提交阶段。当提交阶段通过以后验收测试阶段就应该被自动触发并使用提交阶段刚刚创建的二进制包。为手工 测试或发布应用而向类生产环境部署二进制包的阶段都应该会要求你具有通过单击按钮来选择到底部署哪个版本的能力而这种能力通常都需要授权。 接下来就让这些占位符真正做些事情。假如项目已经全面展开那么把已有的构建、测试和部署脚本放进去就可以了。如果还没有的话就先创建一个“从头到尾的轮廓”即用最少的工作量将所有的关键元素准备就绪。首先是提交阶段。如果还没有开始写代码和单元测试的话就写一个最简单的“Hello world”示例如果是 Web 应用写个 HTML 页 面 就 行 再写个单元测试而这个测试只是“assert(true)”。其次完成部署比如在IIS上建立一个虚拟目标将你的网页放进去。最后进行验收测试。注意要在完成部署阶段后再做验收测试。因为只有部署应用后才能做验收测试。对于Web应用验收测试可以使用WebDriver或Sahi来验证网页中是否包括文字“Hello world”。 对于一个新项目上述内容都应在开发工作正式开始之前完成如果是迭代开发的话这是迭代0iteration zero中的工作内容。另外系统管理员或运维人员也应该参与到建立演示用的类生产环境和开发部署脚本的活动中。在下面的几节中我们会更详细地讲述如何创建简单的可工作框架并随着项目的进行而不断开发。 5.8.2 构建和部署过程的自动化 实现部署流水线的第一步是将构建和部署流程自动化。构建过程的输入是源代码输出结果是二进制包。“二进制包”是我们故意含糊使用的一个词因为由于所用开发技术的不同构建过程的输出也不相同。在这里二进制包的关键特征是“你能将它复制到一台新机器上上面没有IDE等开发工具集只要环境配置正确且又有应用在该环境中所需的正确配置信息它就可以启动并运行了而不必依赖于在这台机器上安装的开发工具链的任何部分。 每当有人提交后持续集成服务器就应执行构建——使用3.2节所列出的某个工具。持续集成服务器应该监视版本控制系统每当发现有新提交的代码时就签出或更新源代码运行自动化构建流程并将生成的二进制包放在文件系统的某个地方使整个团队都能通过持续集成服务器的用户界面获取。 一旦持续构建流程建立并运行起来了接下来就要做自动化部署了。首先要找到能够部署应用程序的机器。对于刚启动的新项目用持续集成服务器所在的机器也行。如果项目已比较成熟可能就需要找几台专用机器了。这些环境可以称作试运行环境或者用户验收测试UAT环境这在各组织中的叫法不同。无论怎样这个环境应该与生产环境相似——如第10章所述而且它的准备和维护工作都要用全部自动化的流程完成——如第11章所述。 部署自动化的几种常见方法在第6章有详细描述。部署活动可能包含(1) 为应用程序打包而如果应用程序的不同组件需要部署在不同的机器上就要分别打包(2) 安装和配置过程应该实现自动化(3) 写自动化部署测试脚本来验证部署是否成功了。部署流程的可靠性是非常重要的因为它是自动化验收测试的前提条件。 一旦将部署流程自动化后接下来就要向UAT环境做一键式部署了。配置一下持续集成服务器使你能自由挑选应用版本并做到通过单击按钮来触发一个流程即获取作为构建输出的二进制包运行部署脚本再运行部署测试。在开发构建和部署系统的过程中一定要确保遵循前面说过的那些原则如只生成一次二进制包将配置信息与二进制包分离以便在不同环境的部署中可以使用相同的二进制包。这能确保配置管理有一个健全的基础。除非软件需要用户自行安装否则发布流程应该与向测试环境部署的流程相同。即使有不同之处也只能是环境配置信息不同而已。 5.8.3 自动化单元测试和代码分析 开发部署流水线的下一步就是实现全面的提交阶段也就是运行单元测试、进行代码分析并对每次提交都运行那些挑选出来的验收测试和集成测试。运行单元测试应该不需要太复杂的步骤因为根据单元测试的定义它并不需要运行整个应用程序只需要运行在一个xUnit风格的单元测试框架上。 因为单元测试并不需要访问文件系统或数据库与之对应的是组件测试所以运行速度应该很快。这也是构建应用程序之后就直接运行单元测试的原因。与此同时还可以运行一些静态分析工具得到一些有用的分析数据比如代码风格、代码覆盖率、圈复杂度、耦合度等。 随着应用软件不断变得复杂你就需要写更多的单元测试和组件测试了。这些测试也应该出现在提交阶段。一旦提交阶段运行超过五分钟就应把它们分成几份以便并行执行。为了做到这一点就需要多台测试机器或者一台更强大的机器它要有足够大的内存和更多的CPU以及一个支持多任务并行管理的持续集成服务器。 5.8.4 自动化验收测试 流水线的验收测试阶段可以重用向测试环境部署的脚本。唯一的不同之处就是在冒烟测试之后就要启动验收测试框架并在结束之后为进行分析收集所有的测试结果报告。另外最好也保存一下应用程序的运行日志文件。如果应用程序有图形用户界面的话也可以在验收测试运行时使用一个像Vnc2swf这样的软件来进行屏幕录像这对于诊断问题比较有用。 验收测试可分为两种类型功能测试和非功能测试。在项目初期就开始非功能需求测试比如测试容量和可扩展性等是非常关键的这样你就能得到一些数据用来分析当前的应用程序是否满足这些非功能需求。关于安装和部署我们可以使用与功能验收测试同样的方法。但是测试内容有所不同关于如何创建这些测试请参见第9章。刚开始时你完全可以把验收测试和性能测试放在同一个阶段里接连运行。之后为了能很容易知道哪类测试失败了你可以再将它们分开。一套好的自动化验收测试会帮助你追查随机问题和难以重现的问题如竞争条件、死锁以及资源争夺。这些问题在应用发布之后就很难再被发现。 当然在部署流水线中提交测试阶段和验收阶段需要运行哪些测试取决于你的测试策略参见第4章。在项目初期应该至少有每种测试的一到两个测试可以自动化运行并把它们放到部署流水线中。这样初步框架就建好了今后随着项目的进展就比较容易增加测试了。 5.8.5 部署流水线的演进 我们发现每个价值流图和流水线中几乎都有上面描述的步骤。通常这些是自动化的第一个目标。随着项目越来越复杂价值流图也会演进。另外对于流水线来说还有两个常见的外延组件和分支。大型应用程序最好由多个组件拼装而成。在这样的项目中每个组件都应该有一个对应的“迷你流水线”然后再用一个流水线把所有组件拼装在一起并运行整个验收测试集包括自动化的非功能测试然后再部署到测试环境、试运行环境和生产环境中。第13章会详细讨论这部分内容而分支管理会在第14章讨论。 当实现了部署流水线后你会发现与相关人士的谈话以及效率的提高反过来又会对你的流程有影响。所以一定要记住三件事。 首先并不需要一次实现整个流水线而应该是增量式实现。其次部署流水线是构建、部署、测试和发布应用程序整个流程中有效的也是最重要的统计数据来源。最后部署流水线是一个有生命的系统。随着不断改进交付流程部署流水线也应该不断变化加以改善和重构就像改善和重构要交付的应用一样。 5.9 度量 反馈是所有软件交付流程的核心。改善反馈的最佳方法是缩短反馈周期并让结果可视化。你应该持续度量并把度量结果以一种让人无法回避的方式传播出去比如使用张贴在墙上的海报或者用一个专门的计算机显示器以大号粗体字显示结果这些设备就是信息辐射器。 根据精益思想应该做整体优化而不是局部优化。如果你花很多时间去解决某个瓶颈而这个瓶颈在整个交付流程中并不是一个真正约束的话整个交付流程并不会有什么根本性的变化。因此应该对整个流程进行度量从而判定这个交付流程作为一个整体是否存在问题 对于软件交付过程来说最重要的全局度量指标就是周期时间cycle time。它指的是从决定要做某个特性开始直到把这个特性交付给用户的这段时间。正如Mary Poppendieck所问的那样“你所在的组织中如果仅仅修改一行代码需要多长时间才能把它部署到生产环境中你们是否以一种可重复且可靠的方式做这类事情”这个指标很难度量因为它涉及软件交付过程中的很多环节从分析到开发直至发布。然而这个指标比其他任何度量项都更能反映软件交付过程的真实情况。 一旦知道了应用程序的周期时间就能找到最佳办法来缩短它。你可以利用约束理论按照下面的流程来做优化。 (1) 识别系统中的约束也就是构建、测试、部署和发布这个流程中的瓶颈。随便举个例子比如手工测试部分。(2) 确保供应即确保最大限度地提高流程中这部分的产出。在我们的例子中手工测试就是保证总是有用户故事在等待手工测试并确保手工测试所需的资源不会被其他工作占用。(3) 根据这一约束调整其他环节的产出即其他资源都不会100%满负荷工作。比如开发人员全力开发用户故事时等待测试的用户故事会越积越多。因此只要开发人员开发用户故事的速度能及时供应手工测试就可以了其他时间他们可以写些自动化测试来捕获缺陷这样测试人员就不需要在手工测试上花太长时间了。(4) 为约束环节扩容。如果周期时间还是太长换句话说第(2)步和第(3)步都没有什么太多的帮助就要向该瓶颈环节增加资源了比如聘用更多的测试人员或者在自动化测试方面投入更多的精力。(5) 理顺约束环节并重复上述步骤即在系统中找到下一个约束并重复第(1)步。 尽管周期时间是软件交付中最重要的度量项但还有一些其他度量项可以对问题起到警报作用。这些度量项如下所示。 自动化测试覆盖率。代码库的某些特征比如重复代码量、圈复杂度、输入耦合度、输出耦合度、代码风格问题等。缺陷的数量。交付速度即团队交付可工作、已测试过并可以使用的代码的速率。每天提交到版本控制库的次数。每天构建的次数。每天构建失败的次数。每次构建所花的时间包括自动化测试的时间。 如何呈献这些度量项是值得斟酌的。上面这些报告会产生很多数据而如何解析这些数据就是一门艺术。比如程序经理可能想在一个项目健康报告中以非常简单的红黄绿交通信号灯方式看到已分析的聚合数据而不是看到一页又一页的报告。相比之下一个团队中资深的软件工程师会希望看到更详细的情况但也不会乐意查看多页的报告。 每个团队的持续集成服务器在每次提交后都应该能够产生这样的报告和可视化效果并将报告保存起来以便今后对照某一数据库中的这些数据对每个团队进行追踪分析。这些结果数据应该发布到一个内部网站上用不同页面分别显示一个特定项目的数据信息。最后把它们聚合在一起这样就可以在整个开发过程甚至整个组织的所有项目中追踪监控这些数据。 5.10 小结 部署流水线的目的是让软件交付过程中的每个人都能够看到每个构建版本从提交到发布的整个过程。大家应该能够看到哪次修改破坏了应用程序哪次修改可以作为候选发布版本进入到手工测试环节或发布环节。它应该能够支持人们执行到手工测试环境的一键式部署并使大家能了解当前每个环境中运行的应用程序究竟是哪个版本还能够支持一键式发布选定的某个版本并清楚地标识出这一候选发布版本已成功通过整个流水线并在类生产环境中经历了一连串的自动化测试和手工测试。 一旦有了部署流水线发布流程中的低效环节就会显而易见。所有需要的信息都可从这个部署流水线上获取比如一个候选发布版本需要多长时间能够通过各种手工测试阶段从提交到发布的平均时间是多长流程中每个阶段发现了多少缺陷。一旦掌握了这些信息就可以优化软件的构建和发布流程了。 对于实现部署流水线这个复杂问题来说没有万能钥匙一样的解决方案。关键还是在于创建一个记录系统用来管理从提交到发布的任何变更为你提供在流程中尽早发现问题所需要的信息。部署流水线可以帮助消除流程中的低效环节这样可让反馈周期更短并更有效。这样做的途径有多种比如添加更多的自动化验收测试并行执行它们或让测试环境与生产环境更相似或者实现更好的配置管理流程等。 当然部署流水线也依赖于一些基础设施包括良好的配置管理自动化的软件构建脚本和部署脚本还要有自动化验收测试来验证软件会向用户交付价值。它还需要纪律性比如确保只有通过了自动化构建、测试和部署的那些修改才能发布。我们会在第15章讨论这些前提条件和必要的纪律其中有一个成熟度模型用来评估持续集成、测试、数据管理等。
http://www.zqtcl.cn/news/565347/

相关文章:

  • 公司网站建设工作重点网站建设吉金手指专业11
  • vue做前台网站怎么做钓鱼网站吗
  • 个人建设网站如何定位烟台h5网站开发
  • 广州网站定制多少钱html5游戏开发
  • 使用angularjs的网站域名怎么解析到服务器
  • 地方门户网站盈利模式宝塔 wordpress
  • 西安网站备案软件开发基础教程
  • 有服务器做网站软件系统开发怎样容易
  • 网站建设的公司有发展吗织梦婚纱网站模板
  • 淘宝销售书网站建设方案wordpress调用评论数据
  • 搭建网站需要什么软件苏州吴中区建设局工程网站
  • 长沙市网站推广公司wordpress 弹窗登录插件
  • 网站策划怎么做内容朔州网站建设公司
  • 宁波拾谷网站建设蚌埠网站建设中心
  • 青岛专业设计网站公司加拿大广播公司
  • 盘锦市建设局网站地址八桂职教网技能大赛
  • 投资建设一个网站多少钱和淘宝同时做电商的网站
  • 做动物网站的素材icp备案 网站备案
  • 找人建网站唐山网络运营推广
  • 福建省住房建设厅网站6网站简历模板
  • 医疗网站模版杭州工商注册
  • 正保建设工程网站logo创意
  • 简洁个人博客网站模板下载用自己电脑做网站服务器-phpstudy+花生壳
  • 网页模板下载哪个网站好多个域名指定同一个网站好处
  • 北京网站建设有哪些公司微网站的案例
  • 常德经开区网站官网域名备案关闭网站吗
  • 做宠物网站的工作室做网站租服务器
  • 2017做那个网站致富网站换源码如何保留以前的文章
  • php网站开发实例教程书wordpress博客页面显示文章在哪
  • 地方o2o同城网站源码微信app开发价格表