Heim  >  Artikel  >  Web-Frontend  >  利用F#库canopy进行UI测试_html/css_WEB-ITnose

利用F#库canopy进行UI测试_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-21 08:53:55902Durchsuche

虽然Selenium是一个流行的UI测试库,但基于它创建的测试却有着 脆弱与 不可靠等常见的问题。InfoQ与 canopy的作者Chris Holt进行了一次访谈,以便更深入地了解canopy这个在Selenium的基础上所创建的F#库。

InfoQ:你能否为我们介绍一下canopy?

Chris Holt:canopy是基于Selenium之上,以F#实现的一层功能,它的目标是使UI测试的行为符合使用者的预期。Selenium虽然表现很出色,但有时会显得过于刻板。在canopy中,所有行为不再会因为无法点击某个元素而立即报错,而是不断地尝试点击某个元素,直至一段合理的时间后仍无法点击才会报错。这将帮助你创建更可靠的测试,而不是往往只在第一次尝试时成功的测试。

InfoQ:canopy如何简化通过Selenium进行UI测试的过程?

CH:canopy内置了重试功能,包括元素的获取以及用户在屏幕上的行为,也包括验证功能。此外,canopy还可以通过实用的错误信息帮助用户修复一些常见的问题,例如某个选择器的拼写错误。它还支持以多种方式选择元素,并且易于对这些功能进行扩展。

举例来说,如果用户的屏幕上有一个显示“Save”文字的按钮,那么只需要在代码中写为 click "Save",就可以实现单击的目的。而在常规的Selenium代码中,用户必须在ByText、ById、ByCSS、ByXPath等方法中进行选择。如果要扩展这一功能,只需为用户网页的惯用方式添加对应的finder实现,例如在表单数据中的placeholder值,或是为了表示元数据而人为定义的data-*标签。

canopy还提供了一套简明的API,让用户更方便地阅读与编写测试。它还能够克服html中的各种区别。比方说,每种输入类型在html中都有着不同的表现方式,因此通过原始的Selenium操作他们的方式也是不同的。而在canopy中,操作方式都是相同的。举例来说:

// Assign a value to a textbox or dropdown"#state" << "New York"

InfoQ:canopy是否支持与外部自动化服务的集成,例如Browserstack?

CH:是的,只要是Selenium支持的功能,canopy也同样支持。为了支持Browserstack,用户需要使用RemoteWebdriver。由于canopy本身内置了大量的重试功能,因此交互的次数将有所增加。不过,因为用户不必经常调用Sleep,因此这种增加的交互是可以接受的。canopy还提供了大量可选的优化方式,如果你打算具体地表述选择器的类型,而不是让canopy分析你的选择器类型,就可以应用这些优化。

InfoQ:在页面中选择元素有没有推荐的做法?比方说,通过id选择元素是否会为测试带来更好的可维护性与健壮性?

CH:在UI自动化中所用到的多数“技巧”都与选择元素相关。至于是应该使用整洁的选择器,还是必须要在标签中加入class或id等属性,这两者之间需要找到一个平衡点。我认为,CSS与JQuery选择器的语法是最优秀的,用户可以在80-90%的场景中使用这种方式。而在其余10%-20%的场景中可以使用XPath。在进行准确的文字匹配或是找到某个元素的父元素时需要用到XPath。而通过值或内部文字进行查找也是非常方便的做法,假如上文所述的click "Save"这个示例,它的内部实现就用到了XPath。

经过一段时间的实践之后,用户就可以熟练地掌握创建选择器的方法了,工建议用户通过实践进行学习,而不是通过某种工具去生成选择器。这种方式更准确,并且当页面结构发生变化而影响了用户的测试时,它也更容易进行修正。一旦用户对于选择器有了一定的心得体会之后,用户就会懂得如何让html代码更易于维护,从而简化了选择器的创建。

选择器的编写可以通过某些方式让人更易于理解,例如#header .links这个选择器就表示在页面的header这个div中所有的links元素。而在自动生成的XPath中,它或许会变成html/body/div/div/div[2]/ul/li/a这种形式,这对于理解它的意义毫无帮助。而且如果一旦在这条选择链中多加了或是删除了某个div,就会使选择器无法工作。通过CSS方式编写的选择器“永远”都是有效的,除非有人改动了header这个id,或者删除/改变了links这个class。

InfoQ:用户是否可以自定义错误报告?比方说,我们是否能够在测试失败时自动截屏呢?

CH:canopy目前 内置了3种reporter实现,即ConsoleReporter、TeamCityReporter和HtmlReporter。如果用户需要新增一个自定义的功能,只需简单地实现IReporter这个接口就行了。

InfoQ:有哪些方法能够扩展canopy的功能?

1)通过实现IReporter接口, 自定义测试结果的输出。

2) 在canopy所使用的finder集合中 添加新的通用finder实现,以帮助用户找到页面元素。

3) 为用户常用的action添加新的函数。由于F#会运行某个函数最新定义的版本,因此用户还能够“重写”现有的函数,以满足自身的需求。

比方说,用户可以实现自定义的“click”功能,只需创建一个模块,例如“canopyExtensions”,并在“打开canopy”操作后“打开”这一模块,将所有扩展方法与重写的方法定义在其中。这样一来,所有测试都会调用由用户所定义的功能,而无需改动任何现有的功能。

这个示例表现的是某人希望能够在多选框中实现对元素的Ctrl+Click操作。由于canopy本身不具备这一特性,因此作者编写了一段扩展方法。

4) canopy并没有隐藏任何Selenium中的特性,或是对其进行抽象化。它只是使用了IWebDriver与IWebElement接口。用户在Stackoverflow网站上看到的各种问题与回复对canopy都是100%有效的。用户所要做的唯一一件事就是将代码转换为F#。

InfoQ:在持续集成(CI)服务器上运行canopy测试需要经过哪些步骤?

CH:测试的运行方式是执行由构建过程所生成的控制台应用。测试结果支持不同的 输出格式。支持TeamCity的配置过程只需一行代码:

reporter <- new TeamCityReporter() :> IReporter

我个人会选择使用一些简单的任务来实现整个构建过程,因此我在TeamCity中创建的任务都是很简单的,例如从源代码控制系统中获取最新代码,随后通过一个命令行语句启动我的任务,并完成其余工作。

在Jenkins环境中,我会选用HtmlReporter,通过一个Jenkins的插件生成html文档,并保存到整个任务的结果中。这同样也可以通过简短的几行代码完成设置工作。

canopy是一个托管在 GitHub上的开源项目。如果读者有兴趣了解对它的更多介绍,可以观看Chris Holt最近 在fsharpConf大会上关于canopy的演讲。

查看英文原文: UI Testing in F# with canopy

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn