UI自动化测试框架---TestCafe

UI自动化测试框架---TestCafe

2023年6月28日发(作者:)

UI⾃动化测试框架---TestCafe因某个机会轻轻碰了⼀下TestCafe,感受到其强⼤,这⾥写个⽂档,做个⼩结。什么是TestCafe官⽅:A tool to automateend-to-end web testingWrite tests in JS or TypeScript, run them and view resultsTestCafe VS Selenium这时我想你跟我都有个疑问,跟Selenium 有啥区别?这⾥个⼈简单阅读了下官⽅⽂档,写⼏个粗浅的对⽐。对⽐项社区Selenium ⾃动化测试⼀哥 ,学习资料⾮常多TestCafe较新的⼯具,官⽅提供了详细的学习资料,Github上Start⼈数也超过5KJavaScript,TypeScript谁更优SeleniumSeleniumTestCafeTestCafe不分上下⽀持语⾔⽀持的浏览器完善性java,python,ruby,......Chrome,IE,Firefox,Safari,Edge等有Driver的浏览器都⽀持需要跟其它框架结合使⽤,如TestNG等⽀持所有能⽀持JS的浏览器,也就意味着⽀持多端⾃⾝就是⼀个完整的⾃动化测试框架易学性简单易学简单易学Selenium毕竟已经是Web⾃动化测试的W3C标准了,它有⾮常多的优势,但TestCafe 作为后起之秀我这还想夸夸Demo使⽤过程的⼏点优于Selenium的感受。TestCafe 不再像Selenium 通过各个浏览器提供的Driver来驱动浏览器,⽽是有点类似Selenium RC直接往页⾯注⼊JS来操作页⾯,所以使⽤过程中再也不⽤担⼼因为浏览器版本和Driver版本以及Selenium版本不匹配⽽照成的Case执⾏失败。TestCafe 是⼀整套完整的⾃动化测试框架,不仅提供了Cases的管理,运⾏,失败⾃动重跑,错误⾃动截图,并发等,对页⾯和页⾯元素的等待也封装完善⽽且使⽤简单,不像Selenium需要借助其他框架或者⼆次封装智能等待或者使⽤隐⽰/显⽰等待⽽有点复杂。TestCafe 可以控制整体的执⾏速度,甚⾄可以细到某个操作的执⾏速度(这个有点类似慢放,⽤起来⼤家可以感受下,⾮常魔性)TestCafe 因为只要你的浏览器⽀持JS,所以⽀持桌⾯,移动端平台。TestCafe debug模式,通过代码配置或运⾏时设置,可以控制执⾏过程中失败时进⼊调试模式。PS:当然以上的感受并没有经过项⽬的积累,纯粹Demo过程中的总结,也不晓得真正⽤到项⽬中会有哪些坑得踩。TestCafe 快速⼊门安装因为是 项⽬,可以直接通过npm安装,全局安装如下npm install -g testcafe快速Demo⼀个ure `baidu demo` .page ``;test('baidu search', async t=>{ await xt('#kw',"hao123") .click('#su')});通过Chrome运⾏testcafe chrome 上⾯代码看不懂没关系,感受下TestCafe就⾏。Cases管理⾃动化测试,终归还是测试,是测试就离不开测试⽤例,那TestCafe如何组织管理测试⽤例?fixture 和 test⼀个js⽂件可以包含多个fixture,⼀个fixture可以包含多个test。 我们可以理解为fixture是个集合,test标注的每个函数模块是⼀个case。语法fixture("测试集描述")fixture `测试集合描述`test('⽤例描述',fn(t))Demofixture("cases manage").page("");test('this case 1', async I => { ("this is case 1");});test('this case 2', async I => { ("this is case 2");});test('this case 3', async I => { ("this is case 3");});fixture(`cases manage 2`).page(`/#=0`);test('this case 1-1', async I => { ("this is case 1-1");});test('this case 2-1', async I => { ("this is case 2-1");});test('this case 3-1', async I => { ("this is case 3-1");});运⾏结果:其中你会发现每个test 执⾏之前都会执⾏fixture打开页⾯的操作,但只会启动⼀次浏览器。那这时⼜会⼀个新的问题,除了打开页⾯的前提条件,是否框架⾃带了更多的前提/后置条件的处理了,也就是各种beforexxx。当然!fixture 的前置条件Each( fn(t) ):每个test执⾏之前都会被运⾏ach( fn(t) ):每个test执⾏之后都会被运⾏(fn(t)):⽐beforeEach更早运⾏,且每个fixture只运⾏⼀次(fn(t)):⽐afterEach更晚运⾏,且每个fixture只运⾏⼀次Demojfixture(`beforeeach test1`) .page(``) .beforeEach(async I => { ('this is beforeEach') }) .before(async I => { ('this is before') }) .after(async I => { ('this is after') }) .afterEach(async I=>{ ("this is afterEach") });test("test beforeAndafter",I=>{ ("1111")});test("test beforeAndafter",I=>{ ("2222")});运⾏结果:t的前置条件(fun(t)):该test运⾏之前运⾏(fun(t)):该test运⾏之后运⾏Demofixture(`beforeeach test1`) .page(``) .beforeEach(async I => { ('this is beforeEach') }) .before(async I => { ('this is before') }) .after(async I => { ('this is after') }) .afterEach(async I => { ("this is afterEach") });test .before(async t => { (`this is test's before`) }) ("test beforeAndafter", I => { ("1111") }) .after(async t => { (`this is test's after`) });test("test beforeAndafter", I => { ("2222")});运⾏结果:注意: 从控制台输出看,test的before/after 会覆盖fixture中的beforeEach/afterEach。也就是说如果⼀个test⾥⾯包含了before/after 那么fixture中的beforeEach/afterEach对该test⽆效。跳过测试 :跳过该fixture下的所有 : 跳过该 :只执⾏该fixture下的所有test,其余的fixture下的test全部跳过 : 只运⾏该test,其余全部跳过元素定位Demo1. 创建Selectorsimport { Selector } from 'testcafe';2. 使⽤Selectors // 通过css定位 const osCount = Selector('.-2 label').count; // 通过id定位 const submitButtonExists = Selector('#submit-button').exists;同时因为是JS注⼊⽅式,所以定位⽅式⾮常灵活,⼏乎JS中定位元素的⽅式都⽀持。 例如import { Selector } from 'testcafe';fixture `My fixture` .page `/testcafe/example/`;const label = Selector('#tried-section').child('label');test('My Test', async t => { const labelSnapshot = await label(); await (labelSnapshot);});test('My test', async t => { const secondCheckBox = Selector('input') .withAttribute('type', 'checkbox') .nth(1); const checkedInputs = Selector('input') .withAttribute('type', 'checkbox') .filter(node => d); const windowsLabel = Selector('label') .withText('Windows'); await t .click(secondCheckBox) .expect().eql(1) .click(windowsLabel);});操作resizeWindow():设置窗⼝⼤⼩zeWindow( ):最⼤化窗⼝fixture`demo`.page('');test('设置win窗⼝⼤⼩', async I => { await Window(300, 500) ..maximizeWindow( );});getBrowserConsoleMessages():获取页⾯控制台消息test('获取控制台输出', async I => { (await wserConsoleMessages())});wait():暂停test('暂停', async I => { await (3000);});switchToIframe():切换到iframeswitchToMainWindow():返回到主窗体fixture`iframe 处理 ` .page`/tiy/?f=jseg_alert`;test('iframe ', async t => { await t .click('#button-in-main-window') // 切换ifrme .switchToIframe('#iframe-1') // 返回主窗体 .switchToMainWindow();});下拉框选取:其实就是定位下拉框,再定位到下拉框下的选项,然后点击两次。fixture`下拉框选取 ` .page`file:///C:/Note/selenium_html/`;('下拉框选取 ', async t => { const phone = Selector('#moreSelect'); const phoneOption = ('option'); await t .click(phone) .click(xt('oppe'));});三种警告框的处理setNativeDialogHandler(fn(type, text, url) [, options]):fu返回true 点击确定,返回false点击取消,返回⽂本则在prompt输⼊⽂本,这个执⾏过程中就不会看到警告框弹出,直接处理掉。fixture`警告框处理 ` .page`/tiy/?f=jseg_alert`;test('处理alert ', async t => { await t .switchToIframe("iframe[name='i']") // return true 表⽰点击确定

.setNativeDialogHandler(() => true) .click('input[value="显⽰警告框"]') .wait(10000);});fixture`警告框处理 ` .page`/tiy/?f=jseg_prompt`;('处理 提⽰框 ', async t => { await t .switchToIframe("iframe[name='i']") .setNativeDialogHandler((type, text, url) => { switch (type) { case 'confirm': switch (text) { //false 点击 取消 case 'Press a button!': return false; // 返回 true 点击确定 case 'You pressed Cancel!': return true; default: throw 'Unexpected confirm dialog!'; } case 'prompt': // 警告框填⼊值 hi vidor return 'Hi vidor'; case 'alert': throw '我是警告框!!'; } }) .click('input[value="显⽰提⽰框"]') .wait(10000);});上传⽂件setFilesToUpload(),清空上传:clearUpload():fixture`My fixture` .page`/`;test('上传图⽚', async t => { await t .setFilesToUpload('#upload-input', [ './uploads/', './uploads/', './uploads/' ]) // 清除上传 .clearUpload('#upload-input') .click('#upload-button');});断⾔TestCafe⾃带了较为齐全的断⾔⽅法。断⾔都是通过expect()开始;import { Selector } from 'testcafe';fixture `My fixture`;test('My test', async t => { // 断⾔ 通过CSS定位到的有3个元素,eql()表⽰相等,count表⽰定位元素个数 await (Selector('.className').count).eql(3);});test('My test', async t => {// 断⾔ok()表⽰为true,exists表⽰元素是否存在 await (Selector('#element').exists).ok();});特性在介绍⼏个TestCafe⽐较有意思的⼏个地⽅。执⾏速度testcafe ⽀持测试执⾏的速度控制。 speed(x),x⽀持0.01到1之间,1则表⽰正常速度执⾏。全局速度控制可以通过控制台执⾏命令控制:testcafe chrome --speed 0.1控制某个test的执⾏速度test("test setTestSpeed", I => { tSpeed(0.1); ......});控制某个步骤的执⾏速度test("test setTestSpeed", I => { ("#kw").setTestSpeed(0.5);});Chrome设备模拟在启动Chrome浏览器时,可以设定Chrome提供的模拟器。tcafe "chrome:emulation:device=iphone x" Object demo⼤家都知道,做UI⾃动化测试,肯定得使⽤PO或者PF模式,下⾯简单Demo个例⼦看看TestCafe 可以如何组织PO模式。rt {Selector, t as I} from 'testcafe'class baiduPage { baiduInput = Selector('#kw'); baiduButton = Selector('#su').withAttribute('value', '百度⼀下'); async searchBaidu(text) { await I .typeText(nput, text, { // 清空 replace: true, }) .click(utton) };}export default baiduPage = new baiduPage();rt baiduPage from './baidu_page'fixture`baidu search`.page`/`;test('po demo', async I => { await xt(nput, "test");

Baidu("testCafe");

await xt(nput,"居于之前的字符串空两个字符中插⼊",{ caretPos:2 })});参数化/数据驱动其实就是创建⼀个对象,⽤for ... of ... 循环遍历fixture`todoPage test cases`.page`/examples/react/#/`;const testCases = [ { todo: '123', }, { todo: '!@#$', } // 等等可能性的cases,这⾥随便造两个作为data driver];for (const todoText of testCases) { test('create todo list ' + , async t => { await TodoList(); await (ext).eql(); });}运⾏⽅式RunnerTestCafe 可以通过命令⾏的⽅式来执⾏测试脚本,但是感觉实际过程中肯定不是很⽅便,特别如果运⾏时需要跟⼀堆参数的情况下,那么TestCafe 提供了Runner,更⽅便配置和运⾏。如下配置,我需要被运⾏的Cases,错误⾃动截图,并发,⽣成report,智能等待,执⾏速度,执⾏的浏览器等全部配到Runner⾥⾯,这样我就不需要通过命令⾏运⾏,⽽且在项⽬中使⽤⾮常⽅便。const createTestCase = require('testcafe');const fs = require('fs');let testcafe = null;createTestCase('localhost', 1337, 1338) .then(tc => { testcafe = tc; const runner = Runner(); const stream = WriteStream(''); return runner // 需要运⾏的cases .src( [ '../demo/podemo/*.js', '../demo/' ] ) // 设置需要执⾏的浏览器 .browsers([ 'chrome', 'firefox' ]) // 错误⾃动截图 .screenshots( // 保存路径 '../error/', true, // 保存路劲格式 '${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${FILE_INDEX}.png' ) // ⽣成report格式,根据需要安装对应report模块, // 详细看:/testcafe/documentation/using-testcafe/common-concepts/ .reporter('json', stream) // 并发 .concurrency(3) .run({ skipJsErrors: true, // 页⾯js错误是否忽略,建议为true quarantineMode: true, // 隔离模式,可以理解为失败重跑 selectorTimeout: 15000, // 设置页⾯元素查找超时时间,智能等待 assertionTimeout: 7000, // 设置断⾔超时时间 pageLoadTimeout: 30000, // 设置页⾯加载超时时间 debugOnFail: true, // 失败开启调试模式 脚本编写建议开启 speed: 1 // 执⾏速度0.01 - 1 }); }).then(failedCount => { ('Failed Count:' + failedCount); ();}) .catch(err => { (err); });写在最后TestCafe 还有⾮常多有意思的东西可以去发掘,例如跟Jenkins等集成⼀类的。 个⼈demo了⼀些例⼦觉得是个⾮常值得推荐的 UI ⾃动化测试框架,特别是⽤JS编写的在codecept,WebdriverIO我推荐TestCafe。 也许国内现在⽤的⼈不多,但相信是⾦⼦总会发光的。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687931492a58324.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信