matmanjs / matman

Web 端对端测试(E2E,End-to-End Testing)解决方案
https://matmanjs.github.io/matman
MIT License
46 stars 10 forks source link

[FEAT]matman中集成whistle并提供流程化的语法 #173

Closed jessejyang closed 4 years ago

jessejyang commented 4 years ago

For BUG

For question

For feature request

相对于目前matman提供的crawleractiontest case分离的开发方式,提供一种语义化的测试用例语法,以降低上手成本,也更符合业界通用的方案。 希望matman提供如下类似的语法:

const path = require('path');
const expect = require('chai').expect;
const matman = require('matman');
const { e2eTest } = require('@tencent/iv-tester');

describe('页面渲染', () => {
    it('渲染昵称并成功跳转上报', function(done) {
        // 打开指定url
        matman('http://test.test.com/test/index.html', {
            // 设置本次测试用例mock数据
            mocks: [
                `/^https?://test\\\.test\\\.com/test/([\\\w\\\-]*).html(.*)$/ ${path.resolve(__dirname, '../../dist/webserver/$1.html')}`,
                `/^https?://test\\\.url\\\.cn/test/test/(.*\\\.(js|css|png|jpg|gif|jpeg|svg|blob).*)$/ ${path.resolve(__dirname, '../../dist/cdn/$1')} resCors://enable`,
                `cgi-bin/test ${path.resolve(__dirname, './mocks/nb_rcmd_1.json')}`
            ],
            // show: true,
            useRecorder: true
        })
            .addAction(browser => { // addAction 与原语法相同
                return browser.wait(2000);
            })
            .crawl('userLength', function () { // crawl爬取网页元素并赋值到当前key
                return document.querySelectorAll('.nick-text').length;
            })
            .crawl('firstUserName', function () {
                return document.querySelector('.nick-text').innerText;
            })
            .crawl('secondUserName', function () {
                return document.querySelectorAll('.nick-text')[1].innerText;
            })
            .crawl('thirdlyUserName', function () {
                return document.querySelectorAll('.nick-text')[2].innerText;
            })
            .addAction(browser => {
                return browser.click('.greeting').wait(500);
            })
            .end()
            .then(({ data = [], globalInfo }) => {
                let error = null;
                try {
                    expect(data[0].userLength).to.equal(3);
                    expect(data[0].firstUserName).to.equal('淡淡的云');
                    expect(data[0].secondUserName).to.equal('~~莹造窝窝~~');

                    const e2eQueue = new e2eTest.RequestQueue(globalInfo.recorder.queue);

                    expect(e2eQueue.isExistCGI('report.url.cn/cgi-bin/tdbank?table_id=nearby_report')).to.be.true;
                } catch (err) {
                    error = err;
                }

                done(error);
            });
    });
});

带来的优点:

  1. 提供开箱即用的体验,简化了配置,只需要配置mock就可以运行测试用例
  2. 降低上手成本,跟几个接入e2e的小伙伴聊过普遍反映刚开始接触式需要理解整个架构,采用这样的语法,只需要关注测试用例本身就可以了

希望 @helinjiang 大佬可以考虑下。 thanks for your time!

helinjiang commented 4 years ago

已支持类似的写法,参考 https://github.com/matmanjs/matman-demo-getting-started/blob/master/baidu_01/test/basic-check-in-single-file.test.js

const { expect } = require('chai');

const matman = require('matman');

describe('百度首页:常规检查,使用单文件形式', function () {
    this.timeout(30000);

    it('检查基本信息', function (done) {
        matman

            // 创建 PageDriver,页面驱动控制器
            .createPageDriver(__filename, { doNotCloseBrowser: false, useRecorder: true, tag: __filename })

            // 无头浏览器使用 nightmare.js 框架提供,其底层用的是 Google 的 electron,基于 chromium 内核
            .useNightmare({ show: false })

            // 设置浏览器参数
            .setDeviceConfig({
                'UA': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36 mycustomua',
                'width': 1250,
                'height': 400
            })

            // 设置截屏
            .setScreenshotConfig(true)

            // 加载页面地址
            .goto('https://www.baidu.com')

            // 需要等待某些条件达成,才开始运行爬虫脚本
            .wait('#su')

            // 爬虫脚本的函数,用于获取页面中的数据
            .evaluate(() => {
                return {
                    title: document.title,
                    width: window.innerWidth,
                    height: window.innerHeight,
                    userAgent: navigator.userAgent,
                    _version: Date.now(),
                    searchBtnTxt: document.querySelector('#su').value
                };
            })

            // 结束,获取结果
            .end()
            .then(function (matmanResult) {
                // console.log(JSON.stringify(matmanResult));
                const { data } = matmanResult;

                // 网站title应该为:百度一下,你就知道
                expect(data.title).to.equal('百度一下,你就知道');

                // 搜索按钮的文字应该为:百度一下
                expect(data.searchBtnTxt).to.equal('百度一下');

                //userAgent应该正确
                expect(data.userAgent).to.equal('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36 mycustomua');

                // 窗体宽度 width=1250
                expect(data.width).to.equal(1250);

                done();
            });
    });
});