快乐学习
前程无忧、中华英才非你莫属!

Cucumber-java版真正的入门到精通(Day4)

关心心您的测试        
自动化功能的好处是,您可以长期信任它们作为生动的文档,因为您将根据生产代码检查每个场景,以确保它仍然有效。对于编写代码的程序员来说,还有另外一个好处:那就是当他们在系统上工作时,这些测试就像安全网一样,提醒他们所犯的任何错误都会破坏现有的行为。              
所以,你的特性作为整个团队对系统行为的反馈机制,以及程序员是否已经破坏了任何东西。对于这些反馈循环是有用的,测试需要快速,他们需要是可靠的。我们首先看看影响测试可靠性的问题。      
漏点情况                                        
黄瓜场景基本上是状态转换测试:将系统置于给定状态A,执行操作X(当),然后检查是否已经进入预期状态B.因此,每个场景都需要系统处于在开始之前有一个特定的状态,但是每个场景在完成时也会使系统处于一个新的肮脏的状态。                  
当系统的状态在测试之间没有被重置时,我们说它们允许状态在它们之间泄漏。这是脆性测试的主要原因。                  
当一个场景依赖于另一个先前场景留下的状态以便它通过时,您已经创建了这两个场景之间的依赖关系。当你有这样一个连锁的几个情景彼此依赖,这只是一个时间问题,你最终的火车残骸。                  
如果第一种情况(恰好使系统处于正确的状态以便下一个系统启动)发生改变,那么下一个场景会突然开始失败。即使您没有更改早期的场景,如果您只想自行运行第二个场景,会发生什么情况?如果没有国家早先的情况泄漏,它将失败。                  
与此相反,独立的方案确保将系统置于干净状态,然后在其上添加自己的数据。这使得他们能够自立,而不是与其他测试或共享夹具数据留下的数据耦合。在建立良好可靠的投资库的测试数据建设者使这更容易实现。        
测试数据建设者                        
您可能已经了解了测试数据生成器[28]模式(Builder模式的专门化 – 请参阅设计模式:可重用面向对象软件的元素  [GHJV95])。对于外行人员,下面简要介绍一下它的好处。                     
假设您正在测试工资核算系统,并且您需要创建PayCheck记录作为方案的一部分。您的域模型的结构方式是,PayCheck需要一个Employee,而Employee需要一个Address。他们每个人也有一些必填字段。不必在步骤定义代码中单独创建所有这些对象,或者拥有大量的夹具数据,您可以简单地说:
一旦你创建了一个PayCheckBuilder,你所要做的就是要求它有一个PayCheck,它不仅会创建PayCheck对象,还会创建所有的依赖对象,并设置具有合理默认值的必填字段。如果您关心具有特定值的字段,则可以提供一种方法来覆盖默认值:
当创建数据很容易时,您不再需要随身携带大型夹具数据集。当然,在创建这些构建器时,只有少量的前期投资,但是它在可靠,可读的场景和步骤定义代码中很快就会得到回报。                   
我们不能足够强调独立于基础的情景如何成功地进行自动化测试。除了独立设置自己的数据的情况下增加的可靠性,他们也更清晰的阅读和调试。当你只需要阅读一个场景就可以精确地看到数据的使用情况,而不必根植于一个夹具数据脚本中,或者更糟糕的是,在数据库本身中,你将能够更好地理解和诊断故障容易。
当创建数据很容易时,您不再需要随身携带大型夹具数据集。当然,在创建这些构建器时,只有少量的前期投资,但是它在可靠,可读的场景和步骤定义代码中很快就会得到回报。                    
我们不能足够强调独立于基础的情景如何成功地进行自动化测试。除了独立设置自己的数据的情况下增加的可靠性,他们也更清晰的阅读和调试。当你只需要阅读一个场景就可以精确地看到数据的使用情况,而不必根植于一个夹具数据脚本中,或者更糟糕的是,在数据库本身中,你将能够更好地理解和诊断故障容易。
共享环境                    
这是我们经常在从手动验收测试制度过渡到使用自动化验收测试的团队中发现的一个问题。传统上,团队中的手动测试人员会有一个特殊的环境,通常称为系统测试,最近部署的系统将被部署。他们会在这个环境下进行手动测试,并将错误报告给开发团队。如果不止一个团队成员需要在同一个环境中进行测试,他们会相互沟通,以确保他们没有踩在对方的脚趾上。                  
如果将系统安装在新的环境中甚至有些尴尬,可能的情况是,当团队开始自动化测试时,他们将遵循阻力最小的路径,并将测试脚本指向现有的系统测试环境。现在,环境不仅由团队的人员共享,而且也由测试脚本共享。假设一个开发者得到一个错误报告,并想为自己复制它。他登录到系统测试环境并单击几个按钮,但他没有意识到自动化测试正在同时运行。作为重现错误的步骤的一部分,开发人员不知不觉地删除了自动化测试所依赖的数据库记录,而自动化测试失败。这种情况是闪烁情景的典型原因。                  
单一环境的共享使用也可能导致不可靠的测试,造成像数据库这样的需求资源负载过重和不一致。当共享数据库负载过重时,通常可靠的测试会超时失败。                  
为了解决这个问题,需要在新的环境中简单地启动系统,以达到乐趣。你需要一键系统设置。
一键式系统设置                                   
为了避免使用共享环境导致的闪烁场景,团队需要一个设置脚本,只需单击一个按钮,即可从头创建一个新的系统实例。                      如果系统有一个数据库,脚本生成的数据库应该包含最新的模式,以及任何存储过程,视图,函数等等。它应该只包含系统能够运行所需的最基本的数据,例如配置数据。还有什么应该留给独立的场景来为自己创造。                      
如果有消息队列或memcache守护进程,那么安装脚本也应该启动它们,并在运行的系统上使用最少的配置。          
测试仪种族隔离          
在软件团队中,测试人员往往被不公平地视为二等公民。正如我们将在第8章解释,支持代码,开发的黄瓜功能健康的套件不仅需要测试的技能,但也编程技能。当测试人员独自建立自己的Cucumber测试时,他们可能缺乏软件工程技能来保持其步骤定义和支持代码组织良好。在你知道之前,测试是一个脆弱的混乱,人们害怕改变。                                      
通过鼓励程序员和测试人员在编写步骤定义和支持代码时一起工作来解决这个问题。程序员可以向测试人员展示如何保持代码的组织性,并将其他团队可以使用的可重用组件或库分解出来。通过与这样的测试人员配对,程序员还能更好地理解如何使代码可测试。                  
当黄瓜在团队中使用效果良好时,测试人员应该能够将基本检查的工作委托给黄瓜。这使得他们能够做更有趣,更有创意的探索性测试工作,如敏捷测试:测试人员和敏捷团队的实践指南  [CG08]所解释的。      
夹具数据                   
当手动测试一个系统时,用真实的数据填充它是很有用的,这样就可以像在实际应用程序中一样在系统中漫游。当您的团队从手动过渡到自动化测试时,您可能会经常试图移植一部分生产数据,以便自动化测试具有可正常工作的运行系统。                  
另外,每个测试都建立了自己的数据,可能看起来太难了。在一个遗留系统中 – 尤其是设计有机地演化的 – 在创建你正在进行的测试中实际需要的单个对象的情况下,意味着你需要创建一个巨大的其他依赖对象树,你会觉得是最简单的选择只是在夹具数据中创建一次这个树,然后与所有其他测试共享它。                                      
这种方法有几个重要的问题。一套夹具数据,即使开始相对较瘦,也只会随着时间的推移逐渐增大。随着越来越多的场景依赖于数据,每个需要自己特定的小调整,夹具数据的大小和复杂度也在不断增长和增长。当您对一个场景的数据进行更改时,您将开始感受到脆弱功能的痛苦,但是这种更改会导致其他场景失败。因为根据灯具数据,你有很多不同的场景,所以你会倾向于更多的数据,因为它比改变现有的数据更安全。当一个场景确实失败时,很难知道系统中的哪些数据可能与失败相关,从而使诊断变得更加困难。                                      
当你有大量的夹具数据时,在每次测试之间设置它可能会很慢。这会给你施加压力,写出不能在每个场景之间重置系统状态的泄漏场景,因为不这么做会更快。我们已经解释了这可能导致什么。                            
我们认为夹具数据是一个反模式。我们更喜欢使用测试数据建设者,其中测试本身内产生的相关数据,而不是在一个大的纠结一套夹具数据被埋没了。        
每晚生成                                        
当你有慢特点,造成方案的很多,这是值得考虑的两个分裂您的构建。使用标签来标注每个签到时应该运行的场景,然后将其余的签到夜间构建。                  
 这种模式的使用取决于你的团队对风险的偏好,以及他们犯错误的倾向。应该降级到夜间构建的场景是那些很少(如果有的话)失败的场景。他们是几个月来一直没有改变的功能方案,他们涵盖了稳定的代码没有被处理。如果你不得不这样做,你会准备好完全删除。                  
在保持正确情况下签入的标签的维护开销。随着时间的推移,这些情景中的一些将会稳定下来,并应该被降级到夜间建设,以被更新的情况所取代。                  
虽然每晚构建可以是一个很好的方式,让你出一个大洞,通常正确的长期解决方案就是要打破你的大泥球。        
很多方案                                        
这看起来似乎很明显,但是有很多场景是给自己一个缓慢的整体功能运行的最简单的方法。我们并不是建议你放弃BDD并回到牛仔编码,但是我们建议你把一个缓慢的功能当作红旗来对待。进行大量的测试,除了等待很长时间的反馈之外,还有其他的缺点。很难保持一大堆的功能组织,使他们尴尬的读者导航。基础步骤定义和支持代码的维护也比较困难。                  
我们发现拥有单一庞大构建的团队也倾向于拥有一个可以最好地描述为一个大泥潭的建筑。因为系统中的所有行为都是在一个地方执行的,所以所有的测试都必须在同一个地方,而且都必须作为一个整体来运行。这是一个经久不衰的应用程序,它们在其子系统之间没有明显的接口有机地增长。                  
我们将在下一节讨论更多关于如何处理大泥土的问题。一旦意识到这个问题,正视这个问题并解决这个问题是非常重要的,但这不是一个一夜之间就能解决的问题。                                                                    
在此期间,您可以继续使用的子文件夹和标签组织您的功能(见第5章,表现场景)。标记是特别有用的,因为你可以使用标签来分割你的测试。您可以选择以并行方式运行分区组测试,甚至降级他们有的在运行每日构建。                                      
还有一点值得考虑一下,你在黄瓜场景中指定的一些行为是否可以用快速单元测试来推低。积极拥抱黄瓜的团队有时候也会忘记编写单元测试,而过于依赖慢速集成测试来获得反馈。试着把你的黄瓜场景看作是广泛的笔触,将代码的一般行为传达给业务,但仍然试图从快速单元测试中得到一个好的覆盖范围。在实现Cucumber场景时,让测试人员和程序员成对工作,从而实现这一点。这对可以做出一个很好的决定,是否一个行为必然需要在一个缓慢的,完整的Cucumber场景中实现,并用快速单元测试取而代之。                                                                    
大泥球当没有人花大力气做任何软件设计的时候,“大泥球” [31]就是你所看到的软件设计类型的讽刺名字。换句话说,这是一个大混乱的混乱。                  
我们已经解释了一大块泥土会在你的黄瓜测试中出现的问题:慢速特征,夹具数据和共享环境都是它可能导致的麻烦的例子。注意这些信号,并勇于改变系统的设计,以便于测试。                                                                                        
我们建议Alistair Cockburn的端口和适配器体系结构[32]作为设计可测试系统的一种方式。Michael Feathers 与传统代码一起工作的效率  [Fea04]给出了很多分解大型系统的实际例子,这些系统不是被设计用来测试的。                    
与您的团队定期举行会议,讨论您的架构:您喜欢什么,不喜欢什么,以及您想在何处采取。在您回到办公桌后,很快就会被一些雄心勃勃的想法挥洒在空气中,很容易,所以请务必以实际可行的步骤离开这些会议,以便您朝着正确的方向前进。                这涵盖了当你将Cucumber引入你的团队时可能遇到的最常见的问题。然而,理解这些问题是一回事,但是花时间去处理这些问题是另一回事。接下来我们将讨论一下这个时间的重要技巧。

停止线路和缺陷预防                  
在你们团队所做的所有活动中,你认为哪一个最重要?编写新功能的代码?修复测试中发现的错误?修复生产中发现的错误?加快你的功能?          
可悲的是,测试维护并没有靠近大多数软件团队的优先级列表。如果你的办公楼里的电梯坏了,你可以确定有人会马上打电话给设施小组。当你的测试变得缓慢或脆弱时,除了程序员和测试者依赖它们之外,每个人都看不到这个问题。如果你真的做了维护测试,那么当事情变得糟糕,再也无法忍受的时候,你通常会这样做,否则你根本就无法获得释放,因为测试是如此的破裂。似乎总是有一些更重要的事情要做。          
那些以这种方式思考他们的测试的团队成员是错误的。自动化测试是依靠他们的团队的心跳,他们需要细心的照顾和关注,以保持健康。   
在丰田停止生产线        
在丰田的制造工厂中,每当出现问题时,每个车间工人都有权力和责任停止整条生产线。然后由有经验的工作人员立即集中注意问题,只有在问题解决后才重新启动。一旦线路重新启动,一个团队的任务是对问题进行根本原因分析,以了解为什么会发生问题,从而解决问题的根源。              
当Taiichi Ohno [33]首次提出这个想法时,他的经理们认为他疯了。当时,在制造业中理所当然,最重要的事情就是保持组装线的运转,必要的时候昼夜不停。              
当大野第一次告诉他的管理者实施这个新系统时,他们中的一些人听了,其中一些没有。起初,执行政策的管理者看到他们的生产力下降。立即停止处理每一个问题正在放慢他们的速度,当他们把他们的产出数字与忽视老板的管理者进行比较时,看起来老板错了。              
然而,渐渐地,那些让自己的线路停下来处理每一个问题的经理开始看到他们的线路不再频繁停下来。因为每一个问题都是用缺陷预防来处理的,所以这些生产线一直在投资,不断提高生产线的机器和工艺的质量。这笔投资开始得到回报,他们的线路开始变得越来越快。不久,他们的产出远远超过了那些忽视了他们显然疯狂的老板的经理们的控制力。他们的生产线仍旧以同样的旧的速度徘徊,遭受着同样的老问题。      
缺陷预防                
丰田公司违反直觉但是非常成功的停止生产线的政策是有效的,因为它是更广泛的过程的一部分,被称为缺陷预防,着重于不断改进制造系统。如果没有这个更广泛的过程,停止线路本身就没有什么效果。这个过程有四个步骤:                  
检测异常。                      
停止你在做什么                      
修复或更正眼前的问题。                      
调查根本原因,并安装对策。                  
这第四步是至关重要的,因为它抓住了手头问题提供的机会,以了解您的过程更基本的东西。这也意味着修理东西就成了一种习惯,而不是一天之后你不急于做的东西。              
例如,假设构建打破了一个失败的测试。事实证明,推动失败测试的人在推动之前没有运行所有的测试。为什么不?事实证明,他认为这些测试需要很长时间才能运行,所以他跑出了他所认为的那些涵盖了他所做出的改变的东西,然后横渡他的手指并推动他的提交。所以,根本原因是功能很慢。现在我们明白了根本原因,我们可以努力解决它。              
一些团队保持构建失败的日志,每次记录根本原因。当他们有足够的证据证明一个特定的根源是值得处理的时候,他们可以集中精力来妥善处理。             
将您的团队想象成一条生产线,为您的用户打造有价值的功能。如果您发现问题会放慢生产线,请停止生产线并解决问题。实施停止生产线意味着您已经决定做出一个快速,高质量,可靠的测试来运行整个团队的首要任务,仅次于解决影响客户的生产问题。当测试出现问题时,无论是像是失败测试这样的紧急问题,还是像一个闪烁的场景那样的恼人的烦恼,都要把最好的人放在上面,并且永远修复它。
我们刚刚学到的东西      
黄瓜功能是贵公司的宝贵财富。我们已经看到团队已经彻底改写了系统的大部分内容,因为他们知道他们有一套准确的可执行规范,以确保新的解决方案能够像原始的那样工作。对于这些团队来说,这些功能比生产代码本身更有价值。如果您要投资编写黄瓜功能,您需要通过照顾他们来保护投资,以使其对整个团队尽可能有用。不要满足于那些速度缓慢,间歇性失败,或者只有一半人阅读的功能:在问题发生的时候解决问题,并将每个问题作为使测试比以前更好的一个理由。          
黄瓜可能只是一个测试工具,但其核心是一个真正的协作工具。如果你真的努力编写作为团队中非技术利益相关者的文档的功能,你会发现你不得不和他们讨论你可能从来没有时间谈论的细节。这些对话揭示了他们对这个问题的理解的见解,这些见解将帮助你建立一个比你更好的解决方案。这是黄瓜的大秘密:测试和文档只是一个快乐的副作用; 真正的价值在于你在这些谈话中发现的知识。    尝试这个这里有一些练习可供你自己尝试。预防你的团队缺陷          
想想有三件事正在放慢你的团队的生产线。他们每个人的根本原因是什么?你能做些什么来改变他们呢?        
附带的细节实践          
这里有一个情节,用一个可怕的命令写成,充满了偶然的细节:
开始只是试图弄清楚发生了什么事情:你认为这个系统有什么作用?这个场景的目的是什么?它试图测试什么样的行为?注意附带的细节是如何杂草丛生,妨碍你找出测试实际上正在做的事情。                  
现在你明白了情节的本质,用你自己的话来重写。您应该需要更少的步骤,但是您可能需要考虑使用多个方案。                  
现在,你已经重写场景更声明的风格,你能发现的关键然后是从原始场景中缺少的步骤?
打赏

未经允许不得转载:同乐学堂 » Cucumber-java版真正的入门到精通(Day4)

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

特别的技术,给特别的你!

联系QQ:1071235258QQ群:226134712
error: Sorry,暂时内容不可复制!