跳过主要内容

保存的帖子

你应该选择的用户界面和API测试哪些工具?

Dave Nicolette |领导敏捷
戴夫尼科尔特
阅读: 你应该选择的用户界面和API测试哪些工具?
测试自动化金字塔流程图

现在,大家已经看到了“测试自动化金字塔”一万次以上。你可以找到无数插图它在线。

所述基座包括大量自动检查小范围。当我们提升时,我们检查逐步大块的代码,我们需要相对较少的情况下比在下面的层。

我们的核心理念是用最少的时间、金钱和精力从每一张支票中获得尽可能多的价值。金字塔上更高的检查比金字塔上更低的检查需要更多的资源和更多的接口,所以它们本质上更昂亚傅体育app贵。我们通过更便宜、更低水平的检查学到的东西越多,我们的生活就越好。

当与现在才开始填补测试自动化空白的组织一起工作时,总是有很多关于工具的讨论。人们倾向于避免将大量不同的工具混在一起,因为这会让环境更难理解和维护,并增加事情一与事情二无法正常工作的可能性。

这是一个合理的想法,但它可以超越收益递减点。在自动化检查的背景下,不同的工具可能提供最好的结果,这取决于我们在金字塔上的位置。

微观镜头

到目前为止我见过的金字塔的所有插图都显示了基地的“单位测试”。随着当代的开发实践,基地真的比这更小;这是微量

Microtests的书面和程序员维护。他们是测试驱动开发(TDD)的基础。一个单一的例子将通过的代码只是一个小规模非常单元行使只是一个逻辑路径。为了做到这一点,例子有相同的语言测试的代码编写。(这是可能有人创造了一个低级别的测试工具,违背这一声明,但作为一般规则,它是在地面上的现实。)

如果你有这样的c#代码:

使用系统;命名空间Prime.Services {公共类PrimeService {公共BOOL IsPrime(INT候选){如果(候选<2 ||候选%2 == 0){返回FALSE;} INT边界=(int)的Math.Floor(Math.Sqrt(候选));对(INT I = 3;我<=边界; I + = 2){如果(候选%I == 0){返回FALSE;}}返回true;}}}

然后,您希望通过方法,isPrime拥有每个逻辑路径的Microtest。也许这样的东西:

使用Microsoft.VisualStudio.TestTools.UnitTesting;使用Prime.Services;public class primeservice_isprimeshshould{private readonly PrimeService _primeService;public PrimeService_IsPrimeShould() {_primeService = new PrimeService();} [DataTestMethod] [DataRow(-1)] [DataRow(0)] [DataRow(1)] public void ValuesLessThan_2_AreNotPrime(int value) {var result = _primeService.IsPrime(value);断言。IsFalse(result, $"{value}不是素数");} [DataTestMethod] [DataRow(4)] [DataRow(80)] [DataRow(2000)] public void ValuesDivisbleBy_2_AreNotPrime(int value) {var result = _primeService.IsPrime(value);断言。IsFalse(result, $"{value}不是素数"); } [TestMethod] public void Value_81_IsNotPrime() { Assert.IsFalse(_primeService.IsPrime(81), "81 is not prime"); } [TestMethod] public void Value_13_IsPrime() { Assert.IsTrue(_primeService.IsPrime(13), "13 is prime"); } } }

类似地,如果您有一些COBOL代码来确定下一个发票日期,如下所示:

2000 -下-发票日期。当二月执行2100-处理-二月,当30天-月移动30到ws-current-day,当其他移动31到ws-current-day结束时,评估为真,将ws-current-date移动到ws - next -发票- date。

然后,您希望通过段落,2000-下一发票日期为每个逻辑路径想要一个Microtest。也许这样的东西:

TESTCASE“它决定下一个发票日期30天月”“20150405”WS-CURRENT-DATE执行2000 -下-发票日期预计WS-NEXT-INVOICE-DATE“20150430”TESTCASE“它决定下一个发票日期在一个月31天”“20150705”WS-CURRENT-DATE执行2000 -下-发票日期预计WS-NEXT-INVOICE-DATE"20150731" testcase " it determines the next invoice date in feb, non leap " move " "20150205" to ws-current-date perform 2000-next-invoice-date expect ws-next-invoice-date to be "20150228" testcase " it determines the next invoice date in feb,将“20160205”移动到ws-current-date执行2000-next-invoice-date期望ws-next-invoice-date为“20160229”

从这些例子中采取的点是,当我们需要隔离一组代码单位时,只练习该部分,并使断言有关部分展示的行为与代码的其余部分展示,那么我们必须将我们的自动检查与与正在测试的代码相同的语言写入。Python或Ruby程序无法直接查看C#方法或COBOL段落的结果。Python或Ruby中的测试工具必须间接检查方法或段落的有效性,作为较大范围检查的一部分。那种方式谎言疯狂

这是测试用例应该用与被测代码相同的语言编写的推理基础。问题是:同样的推理适用于更高层次的测试自动化金字塔吗?

UI和API的性质检查

对于人们来说,这是一个常见的看法,“我们是一个Java商店,所以我们也需要使用基于Java的测试工具,即使是对API和UI的高级检查。”在Java中编写Java中的Microtests是有意义的。但是,对网页,移动设备,CICS屏幕,命令行界面,SOAP API或RESTFUL API进行写入自动检查的正确选择?

如果应用程序是用一种以上的语言编写的呢?在这些案例中,我们经常看到技术人员分成“阵营”,并无休止地争论工具的选择。“我们的团队用Java编写微服务,所以我们需要使用[例如]RestAssured来进行API检查”,而不是“我们的团队用c#编写微服务,所以我们需要使用[例如]SpecFlow来进行API检查”。现在您必须维护两个自动检查的代码库。

事情是,API检查与MICRESTS不同。他们不会在申请中断言单个方法的结果。它们断言服务调用的结果,通常在HTTP上。当您在HTTP上调用服务时,就像您执行谷歌搜索时,您是否需要知道服务写入的语言?

同样,针对移动应用程序,网页,CICS屏幕和命令行接口检查或关心API后面应用程序中使用的编程语言。没有技术原因,这种支票必须以与正在测试的代码相同的语言编写。

事实上,强制要求所有测试工具使用与应用程序相同的语言,很容易造成弊大于利。

知识缺口(和它们的恐惧)

人们希望在所有自动化检查中坚持使用一种语言的第二个最常见的原因是,技术人员可能不熟悉其他语言。“我们的开发人员非常了解Java,但他们不了解Ruby。因此,他们必须使用[例如]黄瓜,JVM而不是黄瓜“。

谁提出这个顾虑的人通常是在两个组中的一种:(一)非技术经理谁(显然)假设人的大脑有确切的知道一个程序设计语言的能力,和(b)的程序员谁是(不幸)关闭在钟形曲线错误的结束(虽然惊人的.)

这种担忧背后有两个基本的逻辑错误。

首先,技术人员已经知道并使用多种编程语言和相关工具,例如脚本语言,标记语言,作业控制语言和用于配置,集成,构建,运行,打包和部署其代码的工具。即使应用程序的应用程序只是一种语言,技术人员也必须使用一系列不同的工具来使用代码库。

第二,有能力的程序员享受学习新语言。他们进入这个领域首先是因为他们喜欢解决问题和创造软件。程序员将会是快乐的有机会学习(一)技能测试和(b)新的语言和工具。

适合的目的

理想情况下,我们希望使用任何自动检查工具意义的检查,我们需要执行的各个类别,并为测试自动化金字塔的每一层。我们已经看到有必要写microtests在相同的语言测试中的代码。

对于UI和API检查,我们希望选择能够提供良好功能和灵活性的工具来检查UI和API;不必断言单个Java或c#方法的结果等等。这是一个不同的用例。

测试工具可以增加价值,但不是魔法

在HTTP上访问服务方面没有魔法。要示意,让我们使用常用的* nix命令行程序访问服务。我们不想暗示这是创建大量维护的大型可执行检查的好方法。目的只是展示没有必要在用于编写正在测试的系统的相同编程语言中写入API检查。

截至出版日期,Heroku上有一个Sample MicroService我们可以用于此演示。它被称为RPN服务,它是反向波兰符号(RPN)计算器。使用CURL来调用服务和JQ以查看它返回的内容,我们得到以下内容:

卷曲-s 'http://rpn-service.herokuapp.com' |JQ'。

而结果是:

{"usage": [{"path": "/calc/*", "description": "以后缀顺序传递值,如:/calc/6/4/5/+/*。为了避免与URL字符串冲突,使用\"d\"而不是\"/\\ "进行除法。}]}

所以,当我们不带任何参数调用该服务将返回使用帮助。我们可以看到JSON响应文件中包含的关键“用途”有项目的一个项的数组。让我们来看看,以确保“说明”条目包含文本,“传递顺序后缀值”:

perl -wnE'say /pass values in postfix order/g'

让我们:

按后缀顺序传递值

包装在Bash脚本中,我们可以检查regex查找匹配并调用'pass'。

#!/ bin / bash如果[$(curl -s'http://rpn-service.herokuapp.com'| jq'.usage [0] .description'| perl -wne'say / pass值以postfix命令/ g')]];然后回声'通过'否则回声'失败'fi

您可以看到我们不需要任何特殊的测试工具来检查API调用的结果,并且我们不需要在与正在测试的系统中以与系统相同的编程语言编写我们的可执行检查。

当然,好的测试工具还会增加价值。它们帮助我们组织测试用例,隐藏丑陋的细节,并基于我们定义的标准运行测试套件的子集,例如长/短运行用例或与特定应用程序特性相关的用例。它们通常也比命令行程序和shell脚本更容易使用。

问题的关键是想法,测试和应用程序代码必须在相同的编程语言编写是一个神话,或者,也许仅仅是

选择API测试工具的注意事项

不同的组织有不同的需求,通常有独特的技术环境。在较大的企业IT组织中,以下考虑通常是相关的:

  1. 服务可以驻留在内部或云中,也可以驻留在一系列不同的平台上。这些通常包括一些的Linux(通常是红帽企业或者Suse),一些味道的Unix(通常是IBM AIX或HP - ux,有时Solaris虽然被淘汰),企业平台,公开类Unix shell(惠普不间断/串联,IBM环球),和/或Microsoft Windows的一些味道。
  2. 大多数软件开发人员在大型企业IT部门的工作使用Microsoft Windows开发系统。一些使用苹果OSX或Linux的一番风味。这些谁做手机开发以及API开发最有可能使用苹果OSX。
  3. API测试套件可能非常大,通常包含数千个案例。在开发周期的不同阶段,必须执行这些用例的子集,而不是整个套件。可能会应用分组和选择测试用例的不同标准。
  4. API的检查必须是在交互模式运行以及作为编写脚本包含在一个CI构建。
  5. 最常使用基于RUSF或SOAP的标准调用服务。在较旧的IT商店中,基于可能是非标准的旧界面,可能会在内部公开使用类似的服务界面。
  6. 自动化测试套件的一个功能是提供正在测试的系统的文档。与传统文档相比,与生产代码同步的可执行文档永远不会过期或不准确。
  7. 不同类型的测试提供了不同类型的价值。通常建议基于示例性和基于物业的测试。

考虑因素1和2建议我们希望具有平台无话可标的工具。在纯粹的Microsoft商店,VST和Specflow和朋友可能很好。大多数企业环境在技术上是异质的。基于Java(例如,RepaceSured,Jbehave,Cucumber-JVM),Ruby(例如,黄瓜),JavaScript(例如,Cucumber-JS)或Python(例如,表现)等工具可能更加合适。作为单独应用程序运行的工具可能是良好的选择,也可能是良好的选择,(例如,Soapui,Fitnesse)。开发人员可以在其Windows开发框中使用它们,并且相同的工具可以在各种目标平台上运行。

注意事项3和4建议我们希望为组织和重新组织测试用例的直接方式提供直接方式的工具,并根据我们想要定义的任何标准,选择测试套件的子集。

考虑5建议我们希望可以在没有太多麻烦的情况下处理肥皂,休息和自定义API的工具。

考虑6建议我们希望以技术和非技术利益相关者可以理解的形式支持测试案例定义的工具。

考虑7建议我们需要支持基于示例和基于属性的测试的工具。

表达与给定的,当-THEN模式的例子

任何行为检查都会指定先决条件,一个行动针对正在测试的系统和预期后置条件.Given-When-Then模式被广泛用于为行为示例声明前置条件(Given)、动作(When)和后置条件(Then)。

小黄瓜用于表示基于给定-时-然后图案示例的流行的语言。这里是我们上面用于检查的RPN计算服务的使用帮助,同样的例子:

特点:逆波兰式计算器服务方案:作为一个人,我想知道我可以用RPN服务做。鉴于我想知道如何调用该服务RPN当我调用RPN服务然后我收到使用文档

下面是运行这些示例的黄瓜- jvm代码片段(省略了样板Java代码):

给定("^我想知道如何调用RPN服务$",()-> {valuesToPush = EMPTY_STRING;});当("^I调用RPN服务$",()-> {jsonResponse = get(RPN_SERVICE_BASE_URI + valuesToPush);});然后("^我接收使用文档$",()-> {assertTrue(jsonResponse .getBody() .getObject() .getJSONArray("usage") .getJSONObject(0) .getString("description") .startsWith("传入的值在后缀顺序"));});

大多数的工具上面提到的可以解析小黄瓜的例子,并执行这些代码大致与此类似Java的例子。

选择UI测试工具的注意事项

如果我们再次表明,我们需要支持大型企业的IT环境假设,再上面API检查工具列出的注意事项也适用于UI检查工具。UI检查可以大大超过API检查复杂。其他考虑因素包括:

  1. 定时问题 - 可以异步地提供网页的不同元素。网络延迟可以是可变的和不可预测的。
  2. 浏览器实现差异 - 不同的浏览器,不同版本的相同浏览器的不同版本以及不同平台上的浏览器的行为会在定义稳定和可靠的自动检查中创建并发症。
  3. 响应式设计问题-响应式设计,网页上的元素改变位置,形状或大小,并可能完全消失,当用户重新设置窗口的大小或取决于用户与应用程序的交互状态。
  4. 辅助功能 - 特殊功能,支持的人有不同类型的残疾人必须处理的需求。
  5. 国际化和本地化 - UI支票必须处理国际化功能(涵盖)和/或本地化内容。
  6. 移动设备 - 自动检查工具必须能够访问各种移动设备和设备模拟器。
  7. 遗留ui——自动检查工具必须能够访问命令行应用程序、WinForms、Java Swing、Tandem/HP Pathway和其他遗留ui,以及模拟IBM 3270和5250终端(以一种平台无关的方式)。

基于示例的测试提供了用于检查确定性结果的具体行为示例。它还可以检查非确定的(统计)结果。

为了系统文档的目的,当示例被写成Given-When-Then场景或表格形式时,所有涉众都可以阅读。支持两种格式的工具比只支持一种格式的工具更好。

最好的品种?

为了最大限度地减少环境中的不同工具的数量,最好找到一种处理API和UI同样良好检查的工具。在作者的经验中,提供最广泛的选项和最简单的定制路径的工具是黄瓜的Ruby实现。

下面是一组简单的“Hello, World!”的应用程序,说明表格形式的小黄瓜:

特点:作为一个友善的人我想打招呼说“你好”对世界所以大家都快乐场景概述:打招呼给我遇到的人说<语言>当我说你好,问候是<祝福>例子:| |语言问候| | |英语“hello, world !”| |西班牙语| " Hola, mundo!"日本| | |”こんにちは世界”| |俄罗斯|“Здравствуйте,мир!”|

在Ruby代码,使这个可执行文件看起来像这样(忽略样板代码和辅助方法):

/^I meet someone who speaks (.*?)$/) do |language| visit_page HelloworldPage @language = language_key language end当(/^I say hello$/) do @current_page。然后(/^the greeting is "(.*?)"$/) do |greeting| expect(@current_page.greeting)。包括问候语

Ruby是一种跨平台的语言。Cucumber本身是一个用于运行示例的轻量级框架。Ruby库被称为宝石提供附加功能。Gems支持广泛的API标准、标记语言、终端仿真、断言和模拟,以及辅助功能,如格式化测试用例输出、日志记录、处理web计时问题和截图。此外,基于属性的测试的实际支持已经可用。Ruby是一种易于学习的语言,配置Cucumber以使用各种gems非常简单。

通过在测试项目中包含适当的宝石,对iOS应用程序,Android应用程序或IBM CICS应用程序运行的示例并不难以锻炼基于网络的“Hello,World!”。应用程序。

对于支持提供多种调用方法的服务的组织来说,这是一个合乎逻辑的选择,因为可以重用用于设置前置条件和指定预期后置条件的代码。

下一个>给分布式团队的scrummaster的提示

自1977年以来,Dave Nicolette一直是IT专业人士。他在各种技术和管理角色方面服役。自1984年以来,他主要担任顾问,在管理营中保持一英尺。

评论(7)

    • 戴夫尼科尔特
      回复

      谢谢彼得,我去看看空手道。我在Github repo上读了README,乍一看,它与任何人喜欢的解析器(Cucumber或其他)解释的小黄瓜(Gherkin)没有什么特别的不同。所以我还不确定它的优势是什么。我打算玩一玩,找出答案。

      如果你使用BDD进行API测试,我读了你在SO上的说明,我可以理解它。在我看来,这样做BDD和使用恰好用于BDD的工具是有区别的。在为企业环境选择工具时,需要考虑的问题之一是尽量减少人们每天必须处理的不同工具的数量。当我写这篇文章时,我想到的问题是,人们经常把这种担忧带到了极端,并假设他们需要使用用相同语言编写的工具来做任何事情。不幸的是,人们通常会在难以使用的工具和测试套件上进行投资,因为他们把错误的工具硬塞进了这些工具中。我理解您对使用Cucumber进行API测试的担忧,我也很欣赏这种观点。我们在划界的问题上可能会有分歧。

      就我个人而言,在使用相同的工具进行API测试和UI测试时,我没有任何哲学或实际问题。这样就少了一件工具。我们正在进行的测试的具体情况会有所不同,但这本身并不需要第二个工具。这是我们在做什么,而不是我们使用的工具的问题。对于那些不了解各种自动化测试的不同之处的输入法(IME)来说,再给他们提供另一种工具也无济于事。

      Gherkin非常少的“规则”,并且以适合手头任务的方式构建示例很容易。在一个语境中,示例可以反映业务级域语言。亚博vip9通道在另一个上下文中,他们可以使用适合使用API​​的技术受众的语言。任何Gherkin解析器都可用于写两个情况的步骤。两种工具无需支持这两项活动。

      Regarding your warning to expect endless arguments, I will suggest it’s possible to worry too much about hearing arguments about the way the Gherkin is written from people who may not deeply understand the buzzwords they’re arguing about, and who have rigid notions of which tools support which practices. Those people will continue to learn as they progress in their careers. We can give them time and space to do so without getting pulled into useless debates. I tend not to worry about that too much.

      我想建议API是否是机器面向或人为的定义的另一个视角。显然,他们面向机器,人们可以编写与他们交互的代码。与此同时,他们是如何写入客户端代码的人为的描述。我并不肯定问题是表达Gherkin中API交互的例子。空手道确实如此,与许多其他工具一样,通常看起来几乎相互相同。作为一种人,我发现很容易涉及在粗眼的API交互的例子。底层步骤定义非常容易写入和读取,因为API交互本质上比UI交互更简单。几乎所有这些都能设置REST或SOAP请求,然后在JSON或XML中拔出几个值。每个编程语言都有库来处理我们的这些细节。所以我不得不想知道空手道是否是寻找问题的解决方案。

      我将检查空手道,看看它为无数现有工具增加了什么价值。如果这真的是一个突破,我会很高兴地这么说,并可能在我自己的作品中采用它。如果这似乎是又一个小黄瓜口译员添加到已经很长的清单上,我希望你能理解,我也会很高兴地说,没有不敬的意思。

      谢谢你的反馈!

      回复
      • 彼得托马斯
        回复

        感谢(哇)详细的回复。我们肯定不同意几点,但我真的很感激你打算仔细看空手道和开放的心态。

        >几乎所有这些方法都相当于设置一个REST或SOAP请求,然后从响应中提取两个JSON或XML值

        我想在这里你过度简化事情,因为恕我直言,你缺少的,你做的回应声明的部分。下面是空手道语法的例子:https://gist.github.com/ptrthomas/2a1e30bcb4d782279019b3d5c10b3ed1

        如果你准备好迎接挑战,我想看看黄瓜和Ruby一步DEFS相当于:P

        回复
        • 戴夫尼科尔特
          回复

          实际上,使用更适合编写DSL的语言而不是Java来实现DSL更有趣。但我们不会在博客上做到这一点。

          回复
  1. Bobman
    回复

    我同意你的意见,使用gherkin /黄瓜(或者我不会在这里),但不同意你对涉及什么语言的论据。

    在我的例子中,我们学习新语言的时间受到了限制。我同意你的观点,工程师们足够聪明(而且可能有足够的兴趣)去学习新的语言,但是当你有一个不考虑学习的截止日期时,你就坚持你知道的东西,因为那是你更有效率的地方。

    最后,我们为希望我们高效的公司工作。希望他们对我们(工程师)的个人发展感兴趣,因为从长远来看,这对我们所有人都有好处,但在短期内并非总是如此。

    回复
    • 大卫王匡
      回复

      我可能会建议,如果你有一个没有把学习考虑在内的截止日期,你就有一个管理问题。

      回复
      • 马克·舍尔
        回复

        嗨大卫,

        我同意对管理问题的评论,

        我非常欣赏你这篇价值连城的文章。

        谢谢,

        马克·舍尔

        回复

留下你的评论

您的电子邮件地址将不会被公布。必填字段已标记