美文网首页软件测试细说测试软件测试脚本
Node.js结合selenium做web自动化测试第十一课

Node.js结合selenium做web自动化测试第十一课

作者: 齐小猴 | 来源:发表于2018-03-28 14:34 被阅读406次

大家好,欢迎来好好学习,天天向上。本节课的主要内容是多浏览器的操作,一个测试脚本打开多个浏览器,炫不炫酷,刺不刺激
在这之前,先说一个浏览器的兼容性测试,我们之前的测试中一直在用chrome浏览器,但是自动化测试不能只用一个单一的浏览器走到底,偶尔也可能用一用火狐或者IE,下面用IE浏览器举个栗子

可以先看一眼我们在CukeTest上的webdrvier.js文件,这里已经给我们引入了三个浏览器驱动,第一个chromedriver,这个再熟悉不过了,第二个是火狐,它好像在第一课的笔记里出现过一个镜头,然后就去领盒饭了,第三个很明显是ie,跟火狐一起领的盒饭,现在召回ie 既然让它重新出境了,那第一步肯定是跟当年chrome一样,安装浏览器驱动啊,package.json文件上右键,打开命令行窗口,像下面这样输入cnpm install iedriver --save
如果下载的时候网速不给力或者其他原因cnpm install不管用也不要慌,可以去网上下载一个驱动,selenium官网上点击链接就能下载对应的驱动

下载完成后放入自己喜欢的路径下面,然后配置一下环境变量,不会配?没事,我教你

这个界面,win7和win10的打开路径好像是不一样的,win10:双击此电脑->右键->属性,win7貌似是在控制面板里,自己找一找哈,我也记不住了,没有win7系统只能帮你们到这了 这个界面找到后记得选择“高级”目录,然后点“环境变量”,点完之后找一个名叫Path的变量,把它打开 打开后的界面,点一下新建,下面会多出一行可编辑的输入框,这里面输入刚刚iedriver放置的路径,copy下来就好,配置变量就搞定了,简单吧 不过这个时候呢,你去运行脚本,它还是打不开ie浏览器的,不信你运行一下试试,试好回来我再教你,CukeTest里面再配置一下,编辑运行配置里面新建一个配置,然后选择ie浏览器 这下子再试试,我猜,结果是打开ie浏览器了,可是运行报错了对不对,别慌嘛,还有一波操作,跟上一起来,这波操作是在ie浏览器里面,打开浏览器,右上角的设置按钮,然后Internet选项 安全列表下面,这一排的几个统统要把启用保护模式勾选上,记得一个都不能少啊 这几波操作都走完了再试试,ie浏览器就能打开了,喜欢就点下面小心心,哈哈,开个玩笑,进行下一话题。
多浏览器的操作,这里大家注意一下,为了方便演示所以多浏览器的例子还都是chrome的操作,上面的ie暂时先忘掉,别被误导,还拿我们的老搭档,老猴子和小猴子来说吧:有一天小猴子在我们Cnode社区上发了个帖子说“山下的桃树上桃子熟了,再不摘就都被隔壁老王抢走了”,老猴子看到了回帖说“你站在此处不要走动,我先去摘两个橘子回来”

这个场景让我们用自动化脚本来实现的话就是这样的:
1.小猴子先打开一个浏览器,登录网站
2.老猴子再打开一个浏览器,登录网站
3.小猴子发帖
4.老猴子回帖

一猴一个浏览器,不用来回退出是不是很方便,那么怎么实现呢 首先,两个用户登录的操作一定是相同的,只需要传入不同的参数即可,那么我们就先定义一个公共的登录方法
async function Userlogin(username, passwd) {
    await driver.get('http://118.31.19.120:3000/signin');
    await driver.findElement({ id: 'name' }).sendKeys(username)
    await driver.findElement({ id: 'pass' }).sendKeys(passwd)
    await driver.findElement({ id: 'pass' }).submit();
}

接下来,你一定会把老猴子和小猴子的登录操作写进来,已经定义过登陆的方法Userlogin了,直接调用就行了

Given(/^用户小猴子登录系统$/, async function () {
    await Userlogin('testuser2', '123456')

});

Then(/^用户老猴子也登录系统$/, async function () {

    await Userlogin('testuser3', '123456')
});

没有错,小猴子用的testuser2登录,老猴子用testuser3,但是这个时候你去运行一下,好像哪里不太对嘛,两个用户用的同一个浏览器登录的,我们不是说好的两只猴子各用一个吗,有bug,得改!

其实呢,这个问题不严重,只不过是两只猴子的行为用了同一个驱动而已,没关系,打开webdriver.js这个文件 看到最后这个导出的方法了吗?就是这样驱动的,有一个driver是给小猴子用了,那再给老猴子导出一个,名字叫otherdriver吧,最后添加一行代码
exports.otherdriver = createDriver();

webdriver.js里面添加的别搞错了啊,然后去hook.js文件里,这里也要改的,耐心一点,最开始定义常量的部分加一个otherdriver

const { driver, otherdriver} = require('./web_driver');

最后再回到我们写脚本的地方,有两个driver了,代码里当然要改了

async function Userlogin(driver, username, passwd) {
    await driver.get('http://118.31.19.120:3000/signin');
    await driver.findElement({ id: 'name' }).sendKeys(username)
    await driver.findElement({ id: 'pass' }).sendKeys(passwd)
    await driver.findElement({ id: 'pass' }).submit();
}
Given(/^用户小猴子登录系统$/, async function () {
    await Userlogin(driver, 'testuser2', '123456')

});

Then(/^用户老猴子也登录系统$/, async function () {

    await Userlogin(otherdriver, 'testuser3', '123456')
});
在参数前面把各自的driver加上了,没有太大改动,这时候运行试试

真的是两个浏览器没骗你哈,接下来的操作,那就是常规操作了,记得两个用户各自用自己的driver,代码怎么写的,还是那句话,之前的课里,蹲墙角补课去!
发帖和回帖的过程中,大家有没有发现,在编辑文字的时候,元素定位以及操作都是一样一样的,那么这里面,我们把编辑文字的部分,再用一个统一的方法提炼出来,叫它edit_context,小猴子发帖和老猴子回帖的时候都会调用这个方法,sendkeys里面传对应的参数,这里面我们给参数命名为content

async function edit_context(driver,content){
    await driver.findElement({css:'.CodeMirror-scroll'}).click();
    let input_area = await driver.findElement({css:'.CodeMirror-cursor.CodeMirror-secondarycursor'})
    await driver.actions().mouseMove(input_area).sendKeys(content).perform();
    await driver.findElement({css:'.span-primary.submit_btn'}).click();
}

接下来是小猴子和老猴子的发布和回复部分
发布话题,用post_topic方法,最后就是调用了上面那个编辑话题的function看出来了吧

async function post_topic(driver,title,content){
    await driver.get('http://118.31.19.120:3000/topic/create');
    await driver.findElement({id:'tab-value'}).click();
    await driver.findElement({css:'#tab-value > option:nth-child(2)'}).click();
    await driver.findElement({id:'title'}).sendKeys(title);
    await edit_context(driver,content)
}

回复话题,用reply_topic方法,同样是在最后调用编辑话题的方法,这里面有一个刷新页面的操作,为什么这么做呢,因为我们在一开始的时候分别做了小猴子和老猴子登录的操作,小猴子发布话题后,老猴子刷新一下页面就可以立马看到小猴子刚刚发布的话题,进行回复了

async function reply_topic(driver,content){
    await driver.navigate().refresh();
    await driver.findElement({css:'#topic_list > div:nth-child(1) > div > a'}).click();
    await edit_context(driver,content)
}

最后小猴子和老猴子的动作,引号部分就是给上面方法里传的对应参数,title和contect

When(/^用户小猴子发布一个话题$/, async function () {

    await post_topic(driver, '山下的桃树上桃子熟了','山下的桃树上桃子熟了,再不摘就都被隔壁老王抢走了');
});

Then(/^用户老猴子回复用户小猴子的话题$/, async function () {

    await reply_topic(otherdriver, '你站在此处不要走动,我先去摘两个橘子回来')
});

附上完整代码

const { Given, When, Then } = require('cucumber');
const assert = require('assert');
const { driver, otherdriver } = require('../support/web_driver');

async function Userlogin(driver, username, passwd) {
    await driver.get('http://118.31.19.120:3000/signin');
    await driver.findElement({ id: 'name' }).sendKeys(username)
    await driver.findElement({ id: 'pass' }).sendKeys(passwd)
    await driver.findElement({ id: 'pass' }).submit();
}


async function edit_context(driver,content){
    await driver.findElement({css:'.CodeMirror-scroll'}).click();
    let input_area = await driver.findElement({css:'.CodeMirror-cursor.CodeMirror-secondarycursor'})
    await driver.actions().mouseMove(input_area).sendKeys(content).perform();
    await driver.findElement({css:'.span-primary.submit_btn'}).click();
}

async function post_topic(driver,title,content){
    await driver.get('http://118.31.19.120:3000/topic/create');
    await driver.findElement({id:'tab-value'}).click();
    await driver.findElement({css:'#tab-value > option:nth-child(2)'}).click();
    await driver.findElement({id:'title'}).sendKeys(title);
    await edit_context(driver,content)
}


async function reply_topic(driver,content){
    await driver.navigate().refresh();
    await driver.findElement({css:'#topic_list > div:nth-child(1) > div > a'}).click();
    await edit_context(driver,content)
}

Given(/^用户小猴子登录系统$/, async function () {
    await Userlogin(driver, 'testuser2', '123456')

});

Then(/^用户老猴子也登录系统$/, async function () {

    await Userlogin(otherdriver, 'testuser3', '123456')
});

When(/^用户小猴子发布一个话题$/, async function () {

    await post_topic(driver, '山下的桃树上桃子熟了','山下的桃树上桃子熟了,再不摘就都被隔壁老王抢走了');
});

Then(/^用户老猴子回复用户小猴子的话题$/, async function () {

    await reply_topic(otherdriver, '你站在此处不要走动,我先去摘两个橘子回来')
});

运行出的结果就是

伴随着老猴子和小猴子完美的完成了多浏览器的互动,今天的课程结束了
更多精彩内容,欢迎关注腾讯课堂
https://ke.qq.com/course/281565#tuin=173f40be,周一至周五晚上8:00
有问题欢迎加入QQ讨论群:707467292(node.js自动化测试)
测试工具CukeTest下载地址http://www.cuketest.com/

相关文章

网友评论

本文标题:Node.js结合selenium做web自动化测试第十一课

本文链接:https://www.haomeiwen.com/subject/jxbjcftx.html