自动化用例如何优雅地sleep?

无处不在的sleep

自动化测试用例由若干测试步骤组成。测试步骤之间往往需要保持同步关系:前一个步骤执行成功之后,才能执行下一个步骤。

然而,有时候执行某个测试步骤之后我们不能立即取到执行结果。例如,打开网址后,由于网络时延、页面加载等原因,登录按钮不一定能立即出现,也就无法立即进行登录。

这时候,我们唯一能做的就是等待(sleep):等待期望的结果出现时再执行下一个测试步骤。

自动化用例如何优雅地sleep?

等待可以通过调用sleep方法实现。各种编程语言,各种自动化测试框架,几乎没有不提供sleep方法的。

在自动化测试用例中,sleep无处不在。然而据观察,很多人写自动化用例习惯于简单调用sleep方法等待一个固定时间。这是一种粗暴sleep。

自动化用例如何优雅地sleep?

粗暴sleep的问题

粗暴sleep的主要问题是等待时间很难确定:等待时间太短,用例可能不稳定;等待时间太长,用例执行速度慢。

为此,我们不得不在用例稳定性与用例执行效率之间做取舍。一般情况下,为了优先保障用例的稳定性,我们简单粗暴,会设置一个足够长的等待时间(即超时时间)。

如果用例只是偶尔执行,这样做没有太大问题。但是,当自动化用例被集成到DevOps流水线中作为提交代码和发布版本的门禁时,大家对用例的反馈时间会很敏感。粗暴地等待固定时间,其效率是无法接受的。

要兼顾用例稳定性与执行效率,我们需要精细化sleep。

分片sleep

分片sleep就是一种精细化的等待方式。它将超时时间进行切片,每等待一个分片时间之后,用例唤醒并检查执行结果:如果成功就结束等待,否则继续等待一个分片时间。重复这一过程,直到超时为止。

例如,Robot Framework最重要的关键字之一 Wait Until Keyword Succeeds,就采用了类似方法实现。

自动化用例如何优雅地sleep?

使用分片sleep,执行结果返回得越快,用例等待的时间就越短。当分片时间设置得足够小时,用例就实现了精确等待。分片sleep可以显著降低异步操作尤其是异步UI操作的执行时间。

因此,UI自动化测试框架通常都会提供原生的分片sleep能力,用来精细化等待元素(element)可见或元素使能(enabled)。例如SeleniumLibrary提供的Wait系列方法:

自动化用例如何优雅地sleep?

交互sleep

在自动化用例中,sleep的另外一个使用场景是暂停用例执行。在debug用例时,可能需要让用例停在某一步。常见的做法是在这一步插入一条sleep语句,让用例暂停一段时间。

这种做法很简单,但是问题也很明显:sleep时间很难确定。sleep时间不够,会打断我们的debug工作,需要再来一次;sleep时间过长,我们需要无谓等待或不得不强制终止用例(可能导致测试环境/数据被破坏)。

这种场景下,一种更精细化的sleep方式是交互sleep:在需要暂停用例的地方,调用系统方法等待外部输入,例如输入字符,点击按钮。用户完成输入后,用例才继续执行。

这样做,我们就可以想要用例暂停多久就暂停多久,并且想什么时候恢复用例就什么时候恢复。这是不是更灵活高效呢?注意到Robot Framework标准库Dialogs就提供了这种功能。

自动化用例如何优雅地sleep?

总结

看似简单的sleep,其实也是有学问的。一个自动化测试工具或框架,分片sleep应当是必备能力,交互sleep则是一件锦上添花的事情。

在编写自动化用例时,我们应该充分利用框架能力,尽量避免粗暴等待。

源自公众号 测试不将就



留言