抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

利用 F#库 canopy 进行 UI 测试

2016 年 3 月 18 日

虽然 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"

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 接口。用户在 Stack
overflow 网站上看到的各种问题与回复对 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

2016 年 3 月 18 日 19:00799
用户头像

发布了 428 篇内容, 共 153.9 次阅读, 收获喜欢 27 次。

关注

评论

发布
暂无评论
发现更多内容

AQS之ReentrantReadWriteLock精讲分析上篇

伯阳

AQS 读写锁 ReentrantReadWriteLock 多线程与高并发 lock

《价值》- 护城河(6)

石云升

读书笔记 护城河 28天写作

android开发培训!深度解析跳槽从开始到结束完整流程,系列篇

欢喜学安卓

android 程序员 面试 移动开发

快了何止100%?阿里巴巴Java性能调优实战(2021华山版)PDF版开源

Java架构追梦

Java 阿里巴巴 架构 性能优化 华山版

DDD分层架构最佳实践

程序员小毕

Java 编程 架构 面试 DDD

认识产品经理(第一节)

让我思考一会儿

【Redis】- Redis Cluser之数据分布

双木之林

第一周作业

Esther

百度首届智能小程序高校大赛圆满结束:关注学生心理健康小程序获全国一等奖

DT极客

边缘安全 | 正确使用CDN 让你更好规避安全风险

阿里云Edge Plus

安全 CDN

LeetCode题解:105. 从前序与中序遍历序列构造二叉树,递归+哈希表,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

首次公开!阿里巴巴技术团队共同携手编写的“大厂面试参考指南”v1.0版本

Crud的程序员

Java 架构 Java 面试

蝉联 Apache 最活跃项目,Flink 社区是如何保持高速发展的?

Apache Flink

flink

阿里云 RTC QoS 屏幕共享弱网优化之若干编码器相关优化

阿里云视频云

音视频 WebRTC 网络 RTC 视频会议

区块链电子合同技术方案,区块链电子合同存证

135深圳3055源中瑞8032

AES128解密只能解一半的问题

李日盛

AES 问题定位

万字带你深入阿里开源的Canal工作原理

大数据老哥

大数据 canal

你kin你擦!阿里终于肯把内部高并发编程高阶笔记开源出来了

Java架构之路

Java 程序员 架构 面试 编程语言

【Java虚拟机】- Java虚拟机之逃逸分析

双木之林

吉他谱怎么看?看谱大攻略送上!

懒得勤快

音乐 吉他学习 吉他谱 看谱

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

Crud的程序员

Java spring 程序员 架构

Redis 学习笔记 08:数据结构与对象小结

架构精进之路

redis 七日更 28天写作

江苏智慧平安社区建设,智慧社区管理平台开发

135深圳3055源中瑞8032

一文读懂 Serverless,将配置化思想复用到平台系统中

Serverless Devs

Serverless 云原生 PaaS

架构师训练营第三周作业 - 学习总结

阿德儿

EXCEL数据太“脏”无从下手?何须用python,ETL一分钟搞定

智分析

Excel ETL

为什么你家的 K8s 应用平台不好用?

孙健波

Kubernetes PaaS KubeVela

胜天半子!阿里内部力荐SpringBoot全栈笔记全网首发,源码实战齐飞

Java架构之路

Java 程序员 架构 面试 编程语言

Android经典面试:46道面试题带你了解中高级Android面试,附面试题答案

欢喜学安卓

android 程序员 面试 移动开发

阿里开源SpringSecurity:用户+案例+认证+框架

996小迁

Java 程序员 架构 面试 springsecurity

​Kubernetes资源清单篇:如何创建资源?​

xcbeyond

Kubernetes 28天写作 Kubernetes从入门到精通

Study Go: From Zero to Hero

Study Go: From Zero to Hero

利用F#库canopy进行UI测试-InfoQ