其他测试框架 强大的全新 Web UI 测试框架 Cypress - 优雅地处理提示消息

非洲赵子龙 for Cypress · March 07, 2019 · Last by 非洲赵子龙 replied at March 25, 2020 · 2766 hits

今天群里一位Qian℡儭‖ 的伙伴问了一个非常好的问题,关于web页面中的提示消息如何处理,瞬间就来了兴趣,现在把今晚调试的成果放上来。

自动化有一个古老而经典的原则:
不要显式地使用wait这种固定时间的等待

强迫症表示,这个原则适用于提示消息场景吗? 试一试就知道了...

  • 环境准备

web提示消息一般来说有两种实现方式:

  1. 提示本身就一直存在在页面上,触发某个事件时通过设置css属性display来显示和隐藏起来;
  2. 提示信息不是一直存在在页面上的,而是在事件触发时,通过新增/删除Dom元素来表现“出现”和“消失”

以下HTML模拟了上述两种效果:

tip.tmpl

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>js弹框3秒后自动消失</title>
<link rel="stylesheet" type="text/css" href="/helper/css/bootstrap.css"/>
<link rel="stylesheet" type="text/css" href="/helper/css/demo.css"/>
</head>
<body>
<button id="alwaysExist" onclick="showModal()">点击弹出模态框-提示一直存在</button>
<button id="addAndDelete">点击出现模态框-新增删除消息Dom</button>
<div class='modal my-modal-alert' id='my-modal-alert'>
<div class='modal-dialog boxBodySmall'>
<div class='modal-content'>
<div class='modal-header boxHeader'>
<button type='button' class='close boxClose' data-dismiss='modal'>
<span aria-hidden='true'>&times;</span><span class='sr-only'>Close</span>
</button>
<h4 class='modal-title boxTitle' id='modal-title'>模态框</h4>
</div>
<div class='modal-body' id='modal-body-alert'>
<div id='modal_message'>js弹框自动消失案例</div>
<span id='num'></span>
</div>
<div class='modal-footer boxFooter' id='modal-footer'>
<button type='button' class='btn btn-default boxButton' data-dismiss='modal'>关闭</button>
<button type='button' class='btn btn-primary boxButton'>保存</button>
</div>
</div>
</div>
</div>



<script src="/helper/js/jquery-1.11.2.min.js"></script>
<script src="/helper/js/bootstrap.min.js"></script>
<script src="/helper/js/jquery-ui.min.js"></script>

<script>
var clearFlag = 0;
var count = 3;//设置3秒后自动消失
var showModal = function(){
$("#my-modal-alert").toggle();//显示模态框

$("#my-modal-alert").draggable({//设置模态框可拖动(需要引入jquery-ui.min.js)
handle: ".modal-header"
});

clearFlag = self.setInterval("autoClose()",1000);//每过一秒调用一次autoClose方法
}

var autoClose = function(){
if(count>0){
$("#num").html(count + "秒后窗口将自动关闭");
count--;
}else if(count<=0){
window.clearInterval(clearFlag);
$("#num").html("");
$("#my-modal-alert").fadeOut("slow");
count = 3;
$("#my-modal-alert").toggle();
}
}
</script>

<script>
$("#addAndDelete").click(function () {
var l = $("body>div").length;
if(l===1)
{
$("body").append(function () {
return '<div class="addAndDelete">\n' +
' <h4>我是提示消息,点击后会以新增的方式布局到HTML里,3秒后自动消失</h4>\n' +
'</div>'
});
setTimeout(function () {
$("
.addAndDelete").remove();
}, 3000);
}
});

</script>

</body>
</html>

注:上面的html代码是用go/gin作为基础框架写的,其中的bootstrapjQuery相关的库,都可以在网上下载到,实在不知道如何运行的可以在群里交流,需要的话,我会把源文件传到群里……唔,好像很啰嗦又不是很高端的样子.jpg

  • 运行效果


    点击第一个按钮,会出现第一张图的弹框,3秒后消失;点击第二个按钮,出现第二张图的文本提示,同样3秒后消失

  • 测试代码示例

测试以上两种情况下,提示信息有没有出现和提示信息有没有正常的消失,一共4个用例。

/// <reference types='Cypress' />
describe("百毒网站首页测试用例集", function() {
beforeEach(() => {
cy.visit("/");
});
it.skip("百度一下按钮文本检查", function() {
cy.get("#su").then($button_start_search => {
expect($button_start_search.attr("value")).to.eq("百度一下");
});
cy.url().should("include", "www.baidu.com"); // => true
cy.url().should($url => {
expect($url).to.contains("www.baidu.com");
console.log($url);
});
});

it("一直存在-点击后出现提示信息", function() {
cy.get("#my-modal-alert").then($alert => {
expect($alert).have.not.property("style");
cy.get("#alwaysExist")
.then($triggerButton => {
$triggerButton.click();
})
.then(() => {
expect($alert).have.attr("style", "display: block;");
});
});
});

it("一直存在-3秒后提示信息消失", function() {
cy.get("#my-modal-alert").then($alert => {
cy.get("#alwaysExist")
.trigger("click")
.then(() => {
cy.get("#my-modal-alert", { timeout: 4000 }).should("not.be.visible");
});
});
});

it("点击后新增然后自动消失-点击后出现提示信息", function() {
cy.get("#addAndDelete").click();
cy.get(".addAndDelete").then($tip => {
expect($tip).to.exist;
});
});

it("点击后新增然后自动消失-3秒后提示信息消失", function() {
cy.get("#addAndDelete").click();
cy.get(".addAndDelete").then($tip => {
expect($tip).to.exist;
});
cy.get(".addAndDelete", {timeout:4000}).should("not.exist");
});

});

  • 测试结果


运行过程中可以看到,提示信息消失时,我们的关于“3秒后提示信息消失”的两个用例才会通过。

  • 解析

我们没有写任何关于wait的函数,一切的发生都尽可能的快,没有无畏的等待。这样的用例才是好的用例哦!should判断会因get传了timeout参数而在超时时间内循环判断,直至成功或超时为止,参考官方Commands关于should的描述

遇到一个有趣的问题,为什么expect("xxx").to.exist,xxx好像随便传什么都能通过?~唔,留到明天研究下...~原来是这样,也就是说,Cypress采用了包括ChaiJS在内的断言方式,而ChaiJS的断言是:对exist的判断的话,如果判断的是字符串,那么只要此字符串不是nullundefined,结果都会是pass,问题解决。

Cypress入门系列:

注:目前官方团队正在开发Python版本,同样的Free to use,对JS恐惧的同学不妨等一等,或者直接JS上手,非常简单,VSCode装上之后,你会爱上Cypress和JS,笔者会慢慢介绍各种Web UI自动化复杂场景下Cypress的强大应对,目前还没发现Cypress无法处理的问题!欢迎一起入坑!QQ群:947886065.

共收到 5 条回复 时间 点赞

我来了😁,一大早满满的干货,timeout这种智能判断确实比写死要好,不会浪费时间,学习了🙏 …如你所说我以前用sublime,现在vscode真是爽的一B,瞬间对js提起了兴趣。
我昨天群里提的那个断言函数是还得研究下,也不知道是不是我用错了~

不要显示地使用wait这种固定时间的等待

俺们村村长说那个词叫显式😂

槽神 回复

Good catch, 已修正 😄谢谢指正

楼主,有cypress的群吗

sunmengshine 回复

Q群:947886065

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up