Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从零开始做Vue前端架构(7)e2e测试 #16

Open
CodeLittlePrince opened this issue Apr 22, 2018 · 1 comment
Open

从零开始做Vue前端架构(7)e2e测试 #16

CodeLittlePrince opened this issue Apr 22, 2018 · 1 comment

Comments

@CodeLittlePrince
Copy link
Owner

CodeLittlePrince commented Apr 22, 2018

前言

吐槽

e2e测试在前端测试中,也许是最不被看重的一项吧。
小公司就不说了,即使是大厂,也极少有e2e测试。因为它需要花费的精力,相比得到的回报而言,可以说是相差悬殊,说白了,就是吃力不讨好- -||
e2e测试其实就是模拟用户行为,我们得根据业务写各种各样的不同操作。而几乎所有的项目,业务都是会变的。所以,因为业务变了,模拟用户行为也会随之改变。最后,就各种改,即改业务代码,又改测试代码,结果,无端端多出一大堆工作量,而且,很大的可能,下一轮迭代还得改,我上次就是这么死的。

燃鹅

但并不是所有的项目都不适合e2e测试的。比如,一个大项目,已经上线多年了,需求内容等基本都成形了。这种情况,就比较适合上e2e了。
项目大的缺点就是,修改的时候,一不小心就会牵一发而动全身。当年刚初来乍到的时候,就经常不小心改了公共样式,或者公共js,然后导致多个页面发生了变化,从而产生bug。因此,这种时候就很需要e2e测试了。

运用场景

总的来说,e2e的运用场景就是:上线久、业务稳、体量大的项目啦~(千万不要在刚启动或迭代很快的项目上e2e,切记,切记)

nightmare

nightmare是高阶浏览器自动测试库。

对比phantom

nightmare相比phantom而言,api更加简洁方便,比如引用的比较多的就是,同样是实现一个向yahoo自动提交关键词并搜索的功能:

  1. PhantomJS实现
phantom.create(function (ph) {
  ph.createPage(function (page) {
    page.open('http://yahoo.com', function (status) {
      page.evaluate(function () {
        var el =
          document.querySelector('input[title="Search"]');
        el.value = 'github nightmare';
      }, function (result) {
        page.evaluate(function () {
          var el = document.querySelector('.searchsubmit');
          var event = document.createEvent('MouseEvent');
          event.initEvent('click', true, false);
          el.dispatchEvent(event);
        }, function (result) {
          ph.exit();
        });
      });
    });
  });
});
  1. nightmare实现
yield Nightmare()
  .goto('http://yahoo.com')
  .type('input[title="Search"]', 'github nightmare')
  .click('.searchsubmit');

是不是感觉世界突然变得很美好?

工具

另外,官方文档还推荐了两个很棒的工具:

  1. niffy:UI diff工具
  2. daydream:这个就厉害了,chrome插件,我们可以直接在浏览器上操作,然后,它会生成对应的nightmare测试代码

配置

安装包

npm i -D nightmare

因为nightmare是基于electron的,安装的时候还会安装electron相关的东西,所以安装会比较慢,这个时候,可以打开网易云音乐来首歌。

牛刀小试

我们先用其他网站来做个小测试,比如github
test文件夹中,和unit文件夹同级,新建一个e2e文件夹,然后在e2e文件夹下新建一个叫test.js的文件,内容为:

const Nightmare = require('nightmare')
const chai = require('chai')
const expect = chai.expect

describe('test CodeLittlePrince results', () => {
  it('should find the CodeLittlePrince\'s blog github link first', function(done) {
    // 设定整个模拟的时长,超过则GG
    this.timeout('60s')

    const nightmare = Nightmare({
      show: true
    })

    nightmare
      .goto('https://github.com/login')
      .wait('input[name="login"]')
      .type('input[name="login"]', '1006312908@qq.com')
      .type('input[name="password"]', '******') // 用户名和密码自行修改
      .click('input[name="commit"]')
      .wait('input[placeholder="Search GitHub"]')
      .type('input[placeholder="Search GitHub"]', 'CodeLittlePrince/blog \u000d')
      .wait('a[href="/CodeLittlePrince/blog"]')
      .click('a[href="/CodeLittlePrince/blog"]')
      // .evaluate(() => document.querySelector('#links .result__a').href)
      // evaluate的作用就是将值return,给expect用
      .evaluate(() => location.href)
      .end()
      .then(link => {
        expect(link).to.equal('https://github.com/CodeLittlePrince/blog')
        done()
      })
  })
})

然后修改package.json的scripts:

"test:e2e": "mocha ./test/e2e/test.js"

最后运行看效果:

感觉棒棒的~

正式配置

因为运行过我的项目的同学知道,我只有三个页面,所以,可交互太少,所以我牛刀小试让同学们可以更加直观的感受到nightmare的方便。
接下来我们就来正式地配置吧。

文件组织

还是刚才的test/e2e文件夹下,删除text.js文件,创建index.js作为入口文件:

/**
 * e2e测试文件的入口文件
 */

// 测试页面的路由和文案是否正确
require('./specs/page.spec.js')

然后,创建specs文件夹,然后在该文件夹下创建文件page.spec.js:

const Nightmare = require('nightmare')
const chai = require('chai')
const expect = chai.expect
const nightmare = Nightmare({
  show: true 
})

describe('pages', () => {
  it('page ', function(done) {
    // 设定整个模拟的时长,超过则GG
    this.timeout('30s')
    nightmare
      .viewport(1200, 600)
      .goto('http://0.0.0.0:9999')
      .wait('h1')
      .click('a[href="#/pageA"]')
      .wait(() => {
        return location.hash === '#/pageA'
      })
      .click('a[href="#/pageB"]')
      .wait(() => {
        return location.hash === '#/pageB'
      })
      .evaluate(() => location.hash)
      .end()
      .then(hash => {
        expect(hash).to.equal('#/pageB')
        done()
      })
  })
})

修改下package.json的scripts:

"test:e2e": "mocha ./test/e2e/index.js"

运行

  1. 先运行:npm run dev
  2. 再运行:npm run test:e2e

结果

➜  construct git:(master) ✗ npm run test:e2e

> vue-construct@1.0.0 test:e2e /Users/Terry/WFE/vue-study/construct
> mocha ./test/e2e/index.js

  pages
    ✓ page  (1431ms)

  1 passing (1s)

评价

感觉测试流程,这样有点鸡肋,因为得先run dev,说不定有需要还需要run mock,最后再run test:e2e,略繁琐。当然,这些都可以被优化成一步。
不过,个人感觉,e2e在联调以后,进入开发环境,或者测试环境以后测也可以。或者说,在测试环境测就好了,测试环境和线上环境比较接近,效果更好。本身e2e测试就是测试开发工程师写的,所以,在测试环境测也合理。不然,本地要测一遍,开发环境又测,测试环境又测,多累呐。
最后,也希望各位有什么好的意见或者建议,可以在评论区留言,讨论讨论呐~

预告

有同学反应我的vue项目没有加入vuex,额,好吧,下一篇我们加一下vuex,也出一篇文章,以免我自己偷偷加,发生断片,让同学们迷糊。
再之后呢,我们就会把这个项目利用yeoman做成脚手架啦!

@CodeLittlePrince
Copy link
Owner Author

e2e参考项目实在是太少,也希望大家能够推荐一些文章或者项目,谢谢啦!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant