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

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

小黄瓜基础   
 现在你已经对黄瓜如何工作有了一些信心,值得稍微回顾一下,稍微研究一下。我们将看看小黄瓜,这是我们用来写黄瓜功能的语言。      在本章的最后,您将了解如何编写可供您的利益相关方阅读并由Cucumber测试的软件规范。您将了解每个Gherkin关键字的作用,以及它们如何组合在一起,以生成可读的,可执行的Cucumber规范。
什么是小黄瓜?                  
当我们为人们构建软件(让我们称之为利益相关者)时,要想清楚他们希望我们构建什么是非常困难的。
弗雷德·布鲁克斯(Fred Brooks)在他的着名散文“ 无子弹”  (Bro95)中说: 建立一个软件系统的最难的部分正在决定要建立什么。”                           
 我们都参与了一些项目,因为一些误解,我们努力工作了好几天甚至更多的代码都被扔掉了。
开发者和利益相关者之间更好的沟通对于避免这种浪费的时间至关重要
一种真正有助于促进这种交流的技术是使用具体的例子来说明我们想要软件做什么。         
具体的例子        
                
通过使用真实世界的例子来描述我们想要建立的系统的期望行为,我们基于语言和术语,这对我们的利益相关者是有意义的:我们正在说他们的语言。
当我们谈到这些例子的时候,他们可以真正想象自己使用这个系统,这意味着他们可以开始在写一行代码之前给我们有用的反馈和想法。             
为了说明这一点,让我们想象你正在建立一个信用卡支付系统。其中一个要求是确保用户不能输入错误的数据。
这里有一种表达方式:应防止客户输入无效的信用卡信息。                         
这就是敏捷团队经常称之为验收标准或满意条件的一个例子。
[12]我们使用接受这个词是因为他们告诉我们系统必须能够做什么才能使我们的利益相关者能够接受。              
以前的要求声明是有用的,但是它为歧义和误解留下了太多的空间。它缺乏精确度。究竟是什么使一组细节无效?
用户如何防止进入他们?
我们已经看到太多的项目被这些有价值但模糊的陈述拖进了焦油坑[13]。
让我们试着用一个具体的例子来说明这个要求: 如果客户输入的信用卡号码长度不是十六位数字,当他们尝试提交表格时,应重新显示一个错误消息,通知他们正确的位数。                 
 你能看到第二个陈述有多特别吗?作为开发者实现这个功能,我们知道几乎所有我们需要能够坐下来开始代码的工作。作为一个利益相关者,我们对开发者将要建立的东西有一个更清晰的概念。             
事实上,一个利益相关者阅读这个可能会指出,有一些卡的有效数字少于16位,给我们另一个例子。
这是实例的真正力量:它们刺激我们的想象力,使我们能够探索和发现我们以前可能找不到的边缘案例。              
通过举例说明我们的要求,我们将验收标准转化为验收测试。现在我们有一些明确的东西可以用来测试系统的行为,无论是手动还是使用自动测试脚本。                                              
尝试这个  考虑一下你现在正在使用的功能或者最近的工作。
你能否写下三个具体的例子来说明这个功能所需要的行为是否可以接受?        
可执行的规格                       
使用具体示例的另一个优点是,比运行系统更容易验证而不是模糊的需求语句。事实上,如果我们对表达他们的方式很整齐,我们可以让电脑为我们检查。我们称之为自动验收测试。[14]                                     
编写好的自动化验收测试所面临的挑战是,要使它们真正有效,不仅需要计算机,而且需要我们的利益相关者阅读。正是这种可读性使我们能够获得关于我们正在构建的内容的反馈。这是小黄瓜进来的地方。                     
 小黄瓜为我们提供了一个轻量级的结构,用于记录我们的利益相关者想要的行为的例子,以一种可以被利益相关者和Cucumber轻松理解的方式。尽管我们可以称其为一种编程语言[15],但它的主要设计目标是人的可读性,这意味着您可以编写像文档一样的自动化测试。这是一个例子:
Gherkin语法的一个有趣特征是它不受限于一种特定的口语。每一个小黄瓜的关键词已被翻译成四十多种不同的语言,使用它们中的任何一个来编写你的小黄瓜特征是完全有效的。无论您的用户是使用挪威语还是西班牙语,只要您的用户使用挪威语或西班牙语,即可使用该语言。(小黄瓜让你用他们能理解的语言写出你的特征。)Tocino grueso!(矮胖培根!)稍后再说。

格式和语法           
小黄瓜文件使用功能文件扩展名。他们保存为纯文本,这意味着他们可以阅读和编辑简单的工具。在这方面,小黄瓜与Markdown,Textile和YAML等文件格式非常相似。    
关键词    
使用一组特殊关键字给小黄瓜文件的结构和含义。在每种支持的口语语言中都有一组相同的关键字,但现在让我们来看一下英语的关键字:
我们将在本章的其余部分中探索如何使用这些关键字中最常见的关键字,这足以让您开始编写自己的Cucumber功能。我们再回过头来看看其余关键字后面的第5章,表现场景。
干运转       
本章中的所有例子都是有效的小黄瓜,可以被黄瓜解析。如果你想在阅读本章的时候使用它们,只需要创建一个features / test.feature工作文件。然后运行以下内容:
该--dry运行开关告诉黄瓜来解析该文件,而不执行它。它会告诉你,如果你的小黄瓜是无效的。

特征    
              
每个黄瓜文件都以Feature关键字开头。这个关键字并不真的影响你的黄瓜测试的行为; 它只是给你一个方便的地方,把一些关于下面的测试总结文档。    
这是一个例子:
与Feature关键字紧随其后的文本是该功能的名称,其余的行是其描述。您可以在描述中包含任何您喜欢的文字,但以“ Scenario”,“ Background ”或“ Scenario Outline”之一字开头的行除外。描述可以跨越多行。这是一个伟大的地方蜡烛抒情与谁将使用该功能的细节,为什么,或把链接支持文档,如线框或用户调查调查。          通过将特征名称转换为小写字符并用下划线替换空格来命名特征文件是常规的。因此,例如,名为用户登录的功能将存储在user_logs_in.feature中。         
在有效的小黄瓜中,特征必须遵循以下之一:
尽管Background是一个方便的关键字,只要您已经编写了一些场景,我们就不用担心了。它在第5章,后来覆盖表现场景。现在我们所需要的只是场景。
描述特征的模板        
尽管功能描述通常是有用的文档,但它们不是强制性的。如果你正在努力想要说什么,下面的模板可以是一个很好的开始:
通过从功能提供的目标或价值开始,您可以明确地告诉每个曾经在这个功能上工作过的人,他们为什么要放弃他们的宝贵时间。你也为人们提供了一个机会来思考可以实现目标的其他方式。也许你根本不需要建立这个功能,或者你可以用一个更简单的方法来提供相同的值。                        
这个模板被称为Feature Injection模板,我们感谢Chris Matts和Liz Keogh与我们分享。

脚本           
为了实际表达我们想要的行为,每个功能都包含几个场景。每个场景都是系统在特定情况下应该如何运行的一个具体示例。如果将所有场景定义的行为相加,那就是该功能本身的预期行为。         
 当Cucumber运行场景时,如果系统按照场景中的描述运行,则场景将会通过; 如果不是的话,将会失败。每当你添加一个新的场景到你的Cucumber测试套件并使其通过时,你已经为系统添加了一些新的功能,现在是时候进入前五名。          
每个功能通常具有五到二十个场景之间的地方,每个场景都描述了不同情况下该功能应该如何运行的不同示例。我们使用场景来探索边缘案例和通过特征的不同路径。         
情景都遵循相同的模式:    
1、让系统进入一个特定的状态。
2、戳它(或痒它,或...)。
3、检查新的状态。                              
所以,我们从一个上下文开始,继续描述一个行为,然后最后检查结果是我们所期望的。每个场景都讲述了一个描述系统应该能够做的事情的小故事。    
鉴于,何时,那么                                
在Gherkin中,我们使用关键字Given,When和Then来确定场景的三个不同部分:
因此,我们使用Given来设置场景发生的上下文,何时以某种方式与系统交互,然后检查交互的结果是我们所期望的。      但是        场景中的每条线都称为一个步骤。我们可以添加更多的步骤给每个给定,当时,或然后使用关键字And和But方案:
但是,这不是很好,是吗?      
用项目符号替换给定/何时/之后                        
有些人觉得考虑,当,然后,而且,和但有点冗长。有一个额外的关键字可以用来开始一个步骤:*(星号)。我们可以这样写下以前的场景:
黄瓜,这是完全一样的情况。你觉得这个版本更容易阅读?也许。一些意思是否迷失了?也许。这取决于你和你的团队如何去处理事情。唯一重要的是每个人都明白所传达的信息。              
无状态                
在编写场景时,需要掌握一个非常重要的概念:            
每个场景都必须有意义,并且能够独立于任何其他场景来执行。              
这意味着您不能在一种情况下将一些资金投入到账户中,然后期望在下一种情况下资金到位。黄瓜不会阻止你这样做,但这是一个非常糟糕的做法:最终会出现意想不到的情况,而且很难理解。                            
 这可能看起来有点教条,但相信我们,它确实有助于保持简单的工作方式。它避免了在场景之间建立脆弱的依赖关系,还可以让您灵活地运行在工作于系统某个特定部分时所需的场景,而无需担心如何设置正确的测试数据。我们在第6章深入解释这些问题,使你的黄瓜甜。              
编写场景时,始终假设它将以默认的空白状态在系统上运行。从一开始就讲述故事,使用“ 给定步骤”设置所需的所有状态。      名称和说明                                
就像一个功能,场景关键字后面可以跟一个名字和描述。通常情况下,你可能只是使用这个名字,但是用一个多行描述来跟随这个名字是有效的,这个名字一直到第一个Given,When或者Then都会被写入场景的描述。             
陈旧的方案名称可能会导致混淆。在修改现有场景(或复制和粘贴场景)时,请注意检查名称是否有意义。由于场景名称只是文档,所以即使其名称不再与步骤中实际发生的事情有关,Cucumber也不会使场景失败。对于以后阅读场景的人来说,这可能会让人感到困惑。
马特说:注意你的命名方案                             
即使他们不能使你的测试通过或失败,场景名称是非常重要的正确的。以下是为什么关注它们的好主意:                      
当你的测试中断时,这是失败的场景的名字,会给你关于破坏的头条新闻。这里一个简洁而富有表现力的名字可以为大家节省很多时间。                          
一旦在功能文件中有几个场景,除非真的需要,否则不需要阅读这些步骤的细节。如果你是一个程序员,想想它有点像方法命名。如果你把这个方法命名的很好,你将不需要阅读它里面的代码来找出它的作用。                         
随着系统的发展,您的利益相关者会经常要求您改变现有方案中的预期行为。一个精心组合的场景名称将仍然有意义,即使你添加一个额外然后两步。                      
一个好的提示是避免将场景的结果(后面的部分)的任何内容放入名称中,并集中于总结场景的上下文和事件(给定和何时)。        尝试这个           
现在你已经明白如何编写小黄瓜场景了,试着将你之前写下的一些具体例子转换成小黄瓜。          
把他们展示给对你的项目一无所知的人,并问他们对你的应用程序的看法。         
练习描述你正在做什么与给定 / 何时 / 那么当你做每天的事情,如开车,煮早餐,或在电视上切换频道。你会惊讶它适合。

注释                        
除了Feature和Scenario关键字后面的描述字段外,Cucumber还允许您在这些关键字之前添加注释。                     
注释以#字符开始,必须是第一个也是唯一一行(除了空格)。               
这是一个例子:
您也可以在场景中添加注释。最常见的用法是注释掉一个步骤,正如我们在前面的例子中所展示的那样。         
就像在任何编程语言中一样,注释可能会很快变得陈旧,变得毫无意义或者完全混乱。发生这种情况时,评论会造成更多的伤害。我们建议您尽可能少地使用它们,并将重要的东西放到可以测试的场景中。                                                   
以下是我们如何看待这个问题:在每个关键字之后可以放置的描述是结构化的Gherkin文档的一部分,并且是为您的利益相关者提供文档的正确位置。              
另一方面,评论可以更多地用于为正在使用这些特性的测试人员和程序员留下笔记。把评论想象成更临时的东西,有点像一个粘滞便笺。             
不要忘记,程序员和测试人员也需要文档。如果技术细节需要记录在该功能中,那么您也可以随意将它们放入说明中,只要您的团队中面向业务的成员对他们感到满意即可。

口语                              
记得早些时候我们说过,你可以用你的利益相关者的口头语言来写你的小黄瓜功能吗?就是这样。                      
把一个#语言:一个特征文件的第一行注释告诉Cucumber写这个特征的口语。如果你省略了这个头,Cucumber将默认为英文,就像你已经看到的那样。 
 这里有一个以挪威语写的功能的例子:
如果您想知道Cucumber是否知道如何说您的语言,您可以使用以下命令询问所有有效语言的列表:
在使用特定语言时,可以通过将语言代码(如前面的命令列出)传递给--i18n开关来发现关键字。例如,以日语为例:
该--i18n选项仅在黄瓜JVM 1.2.0面世。在此之前,找出支持哪种语言的最简单方法是在lib / i18n.json中查找Gherkin项
乔问:那么,我可以在我的功能中混合使用语言吗?       
 一个项目可以混合使用不同口语的功能,是的。但是,请记住,该设置是针对某项功能的,因此功能中的所有场景都必须使用相同的口语。          
使用像Cucumber这样的工具的最大好处之一就是在编写场景时与利益相关者进行的对话。这些对话可以帮助你找到差距和误解,否则这些差距和误解只有在你花了几天甚至几周的时间来处理代码之后才会出现。所以,即使你从不运行测试,只要写它们可以帮助你加快速度。
我们刚刚学到的东西      
让我们回顾一下我们在本章中讨论的内容:             
 
我们看到了核心的Gherkin关键字Feature(特征),Scenario(脚本),Given(特定),When(什么时候)和Then(然后)如何被用来描述您的利益相关者想要的行为作为具体的例子。                  
有一个基本模式,每个黄瓜的情况下,与一个上下文(给定),一个事件(时),和一个结果(然后)。                
 每个场景必须能够独立运行,不应该依赖于其他场景设置的数据。这意味着每个场景都必须包含足够的给定步骤来设置所需的所有数据。                  
你可以添加描述和注释到你的.feature文件,把它们变成你的系统的有用文档。                 
使用#language:标题,您可以使用不同的口语编写功能。              
在这一点上,你有所有的知识,你需要开始编写自己的小黄瓜功能。尽管我们还没有涉及到一些关键字,但是您已经知道了大量的价值。只要假装你有一台机器可以把你的黄瓜情况变成完美的工作代码,并玩与你的团队一起工作的游戏,以创建你想要的软件做的最好的描述。

步骤定义
现在你已经知道如何使用小黄瓜来描述你想做什么测试,接下来的任务是告诉他们如何去做。无论您选择从Cucumber场景还是简单的JUnit测试来推动您的验收测试,都不会逃避您最终需要编写一些代码的事实。现在是那个时候         
步骤定义位于业务域和程序员域之间的边界上。你可以用许多JVM语言编写它们(现在我们将用Java来展示示例),它们的责任是将你的Gherkin场景中的每个简单语言步骤翻译成代码中的具体操作。作为一个例子,从上一章的ATM场景中采取这一步骤:
这个步骤定义需要做以下事情:  
*在场景中为主角创建一个帐户(如果没有的话)。
*将该帐户的余额设置为$ 100。
如何实现这两个目标取决于您的具体应用。自动验收测试通常会尝试模拟用户与系统的交互,而步骤定义则是告诉黄瓜您希望如何与系统混淆的步骤。这可能包括点击用户界面上的按钮或到达封面下方,直接将数据插入数据库,写入文件,甚至调用Web服务。我们认为步骤定义本身与自动化代码截然不同,这些自动化代码会执行实际的抠图操作,以便将图层分离出来,如下图所示:
步骤定义有两个方面。在外部,它从简单的语言翻译成代码,并在内部告诉你的系统使用自动化代码做什么。JVM有一套令人难以置信的丰富的库,用于自动执行从JavaScript到Web应用程序到REST Web服务的各种系统。在本章中,我们不会告诉你如何使用所有这些库。这将在后面的书。在这里,我们要专注于你的黄瓜测试这一层的主要责任,这个测试是解释一个简单的小黄瓜步骤,并决定要做什么。      
我们将从解释步骤定义与简单语言步骤相匹配的一些机制开始,然后通过一个如何编写可处理许多不同步骤的单个步骤定义的示例进行工作。我们将通过解释Cucumber如何执行步骤定义并处理其结果来完成。当我们完成后,您应该足够了解,开始编写和运行您自己的步骤定义。

步骤和步骤定义               
   
首先澄清步骤和步骤定义之间的区别。          
每个小黄瓜场景由一系列用简单的语言编写的步骤组成。就其本身而言,一步就是文档; 它需要一个步骤的定义来实现它。步骤定义是对黄瓜说的一段代码,“如果你看到这样一个步骤...,那么这就是我想要你做的事情......”。          
当Cucumber尝试执行每一步时,它会查找匹配的步骤定义来执行。那么,黄瓜如何配合一步定义呢?    
匹配一个步骤                        
小黄瓜的步骤用纯文本表示。黄瓜扫描每个步骤的文本的模式,它识别,你用正则表达式定义。如果你之前没有使用过正则表达式,那么就把它们看成是你用来搜索文件的通配符稍微复杂的一个版本。虽然起初看起来很吓人,但你只需要少量的模式就可以获得很多的里程。所有这些模式将在本章中讨论; 如果你已经非常熟悉正则表达式,你可能想掠过接下来的几节,直到返回结果。              
我们来看上一章的ATM例子:
依赖管理 - 第1部分      
到目前为止,我们已经使用一个小的shell脚本运行黄瓜。
随着我们的继续,我们将看到这个脚本的复杂性随着我们的例子开始使用更多的组件而增长。
而不是手工管理这些依赖关系,现在是时候开始使用开发社区提供的依赖管理工具之一了。
我们将使用Apache基金会的Maven [17]。                                 
Maven非常强大,但是我们只是用一个小子集来帮助管理我们例子中的依赖关系。
Maven的核心是一个配置文件,默认名为pom.xml。我们的POM文件的主要内容只是用XML格式表示在我们的黄瓜脚本中描述的依赖关系:
由于Cucumber执行这个功能,它将会进入这个场景的第一步,因为我的帐户有100美元,并且对自己说,现在,我有没有与我帐户中有100美元的短语相匹配的任何步骤定义?              
一个简单的正则表达式将会匹配这个步骤,如下所示:
请注意,我们不得不用双反斜杠来摆脱美元符号。这是因为美元符号在正则表达式中可以有特殊含义,但在这种情况下,我们希望从字面上理解它。为了使生活更加复杂,反斜杠在Java字符串中有特殊的含义,所以我们需要使用双反斜杠。稍后我们将回到这些特殊字符。                              
如果Cucumber看到这个正则表达式的一个步骤定义,它会在我们的场景的第一步执行它。那么,我们如何创建一个步骤定义?      
创建一个步骤定义        
步骤定义存在于普通文件中。要在Java中创建一个步骤定义,可以使用一个特殊的Cucumber注释,如@Given,如下所示:
您通常会将这样的几个步骤定义放在同一个源文件中。既然你必须告诉黄瓜在哪里找到你的步骤定义,这真的取决于你想要如何组织他们。我们建议为每个域实体保留一个单独的文件,以便与系统的类似部分一起工作的步骤定义保持在一起。(有关如何黄瓜知道在哪里可以找到你的步骤定义的详细信息,请参阅黄瓜如何寻找我们的步骤定义。)                                              
我们来详细的检查一下这个步骤的定义。这是一个Java文件,我们使用特殊的Cucumber注释@Given,它告诉Cucumber我们要注册一个步骤定义。我们将@Given注释传递给一个正则表达式来匹配一个或多个步骤(双引号之间的位),我们定义一个Java方法,当它匹配时,它将被执行。黄瓜存储正则表达式和方法之间的映射,所以如果遇到匹配步骤,它可以稍后调用该方法。              
您也可以使用批注@When或@Then以相同的方式创建步骤定义。
依赖管理 - 第二部分           
 需要添加一个额外的部分来包含Surefire插件[18],其中包含允许Maven找到并运行我们的JUnit测试所需的代码:
从现在开始,当我们要构建项目并运行测试时,我们将使用Maven:mvn clean test           
第一次运行此命令时,可能需要很长时间才能从Internet上下载依赖项到本地存储库。下一次使用Maven构建项目时,它将使用存储库中的副本。
鉴于,什么时候,那么是一样的                               
实际上,用于注册步骤定义的三种方法中哪一种方法无关紧要,因为在匹配某个步骤时,Cucumber将忽略关键字。在引擎盖下,所有的注释都是StepDefAnnotation的别名。注释实际上只是为了提供额外的文档,以帮助您表达每个步骤或步骤定义的意图。              
这意味着,无论是使用方法@Given,@When还是@Then创建,只要正则表达式与步骤的主要文本匹配,步骤定义将与任何黄瓜步骤匹配。这个数字突出显示了Cucumber在扫描匹配步骤定义的场景时看到的内容。
这种灵活性可以非常方便,稍后我们会向您展示,但有一个值得注意的地方。我们来看一个例子。             
想象一下,你已经实现了你的ATM取款方案,包括为我在账户中有100美元的情况下编写一个步骤定义。所以,你有一个步骤的定义,匹配我的账户中有100美元的文本,并创建一个100美元的账户。几个星期后,这种情况是一个模糊和遥远的记忆,你得到一个新的要求,给所有新的账户一美元的礼物。你和你的领域专家坐下来,写下下面的脚本:
这看起来很合理,不是吗?我们建立新帐户,存入一些钱,然后检查新的余额是我们所期望的。但是,如果我们运行这个新的场景以及原来的ATM取款场景,你能看到会发生什么吗?              
让我们再看看我们的原始步骤定义:
现在我们已经知道Cucumber 在匹配一个步骤时会忽略@Given / @When / @Then注解,我们可以看到这个原始的步骤定义也将匹配我们新场景的最后一步,然后我有$ 100我的帐户。惊喜!我们预计该步骤检查账户余额,而是它打算把$ 100 到帐户!              
在这种情况下,我们显然需要小心,因为我们很容易产生一个给我们带来误判的情况:在本应该失败的时候通过。看起来似乎不是这样,但Cucumber的灵活性实际上已经帮助我们在这里揭露了在每个步骤中使用的语言中的一些非常微妙的含糊不清。我们发现避免这种问题的最好方法是仔细注意您的步骤中的确切措辞。你可以改变这两个步骤,以减少歧义
通过对这样的步骤进行重新说明,你可以更好地沟通他们在执行时会做什么。学会发现和消除这种模棱两可是需要实践的东西。注意这两个步骤之间的区别,也可以给你一些关于在你的代码中可能不表达的概念的暗示。这看起来可能很迂腐,但是我们发现那些对细节进行仔细关注的团队会写更好的软件,速度更快。              
用舌头说话                                                        
如果您的功能中使用的语言不是英语,则在注册步骤定义时仍然可以使用相同的语言。黄瓜为每种口语语言创建了每个注释的别名,例如,在西班牙工作的一个团队可以使用以下内容:

捕获参数                 
你会注意到,在我们一直用作的例子中,我们已经讨论了100美元的总和。如果我们有另一种情况需要将不同数额的资金存入账户,那该怎么办?我们需要另外一个步骤定义吗?
幸好,我们没有。这是正则表达式的灵活性发挥作用的地方。我们可以在这里使用两个正则表达式的最有用的功能来捕获任何美元数量作为步骤定义的参数。这些功能是捕获组和通配符。    
捕获组                       
当用圆括号包围正则表达式的一部分时,它就成为一个捕获组。捕捉组用于突出显示要从匹配的文本中提取并使用的模式的特定部分。在Cucumber步骤定义中,每个捕获组中匹配的文本作为参数传递给代码块:
这里,当这个步骤定义匹配时,方法参数数量将接收字符串值100。前面的例子有点愚蠢,因为这个正则表达式仍然只能匹配$ 100的数量。我们需要在捕获组中使用通配符来打开其他值。      
轮流                               
我们可以使用几种不同的方法在正则表达式中指定通配符。其中一个最简单的交替,我们表达通过管道字符分隔不同的选项| , 喜欢这个:
此步骤定义现在将匹配两个值100或250中的任意一个的步骤,并且该数字将被捕获并作为参数传递给该方法。如果您想在步骤定义中接受一组固定的值,那么交替可能很有用,但是通常情况下,您会希望稍微松一些。              
点                                                        
点是一个元字符,意味着它在正则表达式中具有魔力。从字面上来说,点意味着匹配任何单个字符。所以,我们可以试试这个:
现在将匹配任何三位数美元总和的步骤,并将匹配的数量发送到方法中。这绝对是朝着正确方向迈出的一步,但是我们所做的还有一些问题。首先,请记住点符合任何字符,所以我们可以结束在这里捕获字母,而不是数字。更重要的是,如果我们想要在账户中存入10美元,或者1000美元,那么该怎么办呢?此步骤定义将不匹配这些步骤,因为它总是在寻找三个字符。我们可以通过使用修饰符来解决这个问题。
乔问:如果我实际上要匹配一个点呢?                                                  
像点这样的任何元字符都可以通过在它们前面加一个反斜杠来转义。所以,如果你想特别匹配,比如3.14,你可以使用“3 \ 14”。                                      
您可能已经注意到,在我们使用的步骤定义中,美元金额前面有一个反斜杠。这是因为$本身就是一个元字符(这是一个锚点,我们稍后会解释),所以我们需要转义才能使其符合正常的美元符号。        
明星修改器                                        
在正则表达式中,重复修饰符需要一个字符(或元字符),并告诉我们它可以出现多少次。最灵活的修饰符是明星:
星形修饰符意味着任何次数。所以,用。*我们捕捉任何字符,任何次数。现在我们到了某个地方 - 这将允许我们捕捉所有这些不同的数量。但是还有一个问题。        
星形修饰符是一个钝器。
因为我们正在使用与任何字符相匹配的点,它会吞噬任何文本,直到我的帐户中的短语。这就是为什么在正则表达式中,星形修饰符被称为贪婪操作符。例如,它会高兴地匹配这一步:
在这种情况下我们的正则表达式捕获的数量将是1和一个黄瓜。我们需要更具体的关于我们想要匹配的角色,只是捕捉数字。我们可以使用别的东西来代替点。                                      
字符类                
字符类允许您告诉正则表达式引擎匹配其中一个字符范围。您只需将所有可接受的字符放在方括号内:
对于像我们一样的连续范围的字符,可以使用连字符:
现在我们已经限制了我们接受的数字字符。我们仍在修改角色以接受任意数量的角色,但是我们现在正在具体说明,我们只接受一串连续的数字。      
速记字符类       
对于像[0-9]这样的常见字符模式,可以使用一些简写字符类。你可能会发现这只是让你的正则表达式更加神秘,但只有少数人可以学习。对于数字,您可以使用 d作为[0-9]的简写:
这里是最有用的速记字符类:
您也可以通过大写字母来取消速记字符类,例如, D表示除数字之外的任何字符。       
到匹配我们的金额。看起来我们已经完成了,但还有最后一个问题需要解决。你能看到它是什么?              

Plus修饰符                              
星星是重复修饰词的一个例子,但也有其他的例子。这颗星星的一个微妙的问题是,任何次数都可能意味着零。              
所以,这一步将匹配:
这不好。为了解决这个问题,我们可以使用+修饰符,这意味着至少一次:
我们走了 我们走了一条漫无边际的路线来找到答案,但是在我们构建Cucumber步骤定义时,我们访问了几乎所有对我们有用的正则表达式的特征。我们只有几个要覆盖。     
尝试这个        
想象一下,你正在建立一个机场候机室屏幕系统。您需要能够从黄瓜场景中捕获航班代码的示例。你能写出一个单一的步骤定义,可以从所有这些步骤捕捉飞行代码?
首先编写一个适用于第一步的步骤定义,然后使其更加通用,以便与其他步骤一起工作。

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

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

联系QQ:1071235258QQ群:710045715

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

error: Sorry,暂时内容不可复制!