-
Notifications
You must be signed in to change notification settings - Fork 39
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组件单元测试 #122
Comments
karma,jest和mocha选择哪一个?这个问题很愚蠢。 jest, mocha, karma, chai, sinon, jsmine, vue-test-utils都是些什么东西?
通过上述的表格,作为一个vue项目,引入单元测试,大致思路已经有了:
这并不是最终结果,测试vue单文件组件,当然少不了vue-test-utils,但是将它放在什么位置呢。 |
chai,sinon是什么?chai是什么?
const chai = require('chai');
const assert = chai.assert;
const expect = chai.expect();
const should = chai.should(); sinon是什么?
function once(fn) {
var returnValue, called = false;
return function () {
if (!called) {
called = true;
returnValue = fn.apply(this, arguments);
}
return returnValue;
};
} Fakesit('calls the original function', function () {
var callback = sinon.fake();
var proxy = once(callback);
proxy();
assert(callback.called);
}); 只调用一次更重要: it('calls the original function only once', function () {
var callback = sinon.fake();
var proxy = once(callback);
proxy();
proxy();
assert(callback.calledOnce);
// ...or:
// assert.equals(callback.callCount, 1);
}); 而且我们同样觉得this和参数重要: it('calls original function with right this and args', function () {
var callback = sinon.fake();
var proxy = once(callback);
var obj = {};
proxy.call(obj, 1, 2, 3);
assert(callback.calledOn(obj));
assert(callback.calledWith(1, 2, 3));
}); 行为once返回的函数需要返回源函数的返回。为了测试这个,我们创建一个假行为: it("returns the return value from the original function", function () {
var callback = sinon.fake.returns(42);
var proxy = once(callback);
assert.equals(proxy(), 42);
}); 同样还有 Testing Ajax,Fake XMLHttpRequest,Fake server,Faking time等等。 sinon.spy()?test spy是一个函数,它记录所有的参数,返回值,this值和函数调用抛出的异常。
匿名函数测试函数如何处理一个callback。 "test should call subscribers on publish": function() {
var callback = sinon.spy();
PubSub.subscribe("message", callback);
PubSub.publishSync("message");
assertTrue(callback.called);
} 对象的方法用spy包裹一个存在的方法。 {
setUp: function () {
sinon.spy(jQuery, "ajax");
},
tearDown: function () {
jQuery.ajax.restore();// 释放出spy
},
} 引申问题BDD/TDD是什么?What’s the difference between Unit Testing, TDD and BDD? |
为什么以spec.js命名?SO上有这样一个问题:What does “spec” mean in Javascript Testing spec是sepcification的缩写。 就测试而言,Specification指的是给定特性或者必须满足的应用的技术细节。最好的理解这个问题的方式是:让某一部分代码成功通过必须满足的规范。 |
如何为聊天的文字消息组件写单元测试?运行在哪个文件夹下?test文件夹下即可,文件名以.spec.js结尾即可,通过files和preprocessors中的配置可以匹配到。 karma.conf.js怎么看?看不懂karma.conf.js,到 http://karma-runner.github.io/0.13/config/configuration-file.html 学习配置。 const webpackConfig = require('../../build/webpack.test.conf');
module.exports = function karmaConfig(config) {
config.set({
browsers: ['PhantomJS'],// Chrome,ChromeCanary,PhantomJS,Firefox,Opera,IE,Safari,Chrome和PhantomJS已经在karma中内置,其余需要插件
frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],// ['jasmine','mocha','qunit']等等,需要额外通过NPM安装
reporters: ['spec', 'coverage'],// 默认值为progress,也可以是dots;growl,junit,teamcity或者coverage需要插件。spec需要安装karma-spec-reporter插件。
files: ['./index.js'],// 浏览器加载的文件, `'test/unit/*.spec.js',`等价于 `{pattern: 'test/unit/*.spec.js', watched: true, served: true, included: true}`。
preprocessors: {
'./index.js': ['webpack', 'sourcemap'],// 预处理加载的文件
},
webpack: webpackConfig,// webpack配置,karma会自动监控test的entry points
webpackMiddleware: {
noInfo: true, // webpack-dev-middleware配置
},
// 配置reporter
coverageReporter: {
dir: './coverage',
reporters: [{ type: 'lcov', subdir: '.' }, { type: 'text-summary' }],
},
});
}; 结合实际情况,通过https://vue-test-utils.vuejs.org/guides/testing-single-file-components-with-karma.html 添加切合vue项目的karma配置。 demo地址:https://github.com/eddyerburgh/vue-test-utils-karma-example 人生中第一次单元测试karma.conf.js // This is a karma config file. For more details see
// http://karma-runner.github.io/0.13/config/configuration-file.html
// we are also using it with karma-webpack
// https://github.com/webpack/karma-webpack
const webpackConfig = require('../../build/webpack.test.conf');
module.exports = function karmaConfig(config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['Chrome'],
frameworks: ['mocha'],
reporters: ['spec', 'coverage'],
files: ['./specs/*.spec.js'],
preprocessors: {
'**/*.spec.js': ['webpack', 'sourcemap'],
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true,
},
coverageReporter: {
dir: './coverage',
reporters: [{ type: 'lcov', subdir: '.' }, { type: 'text-summary' }],
},
});
}; test/unit/specs/chat.spec.js import { mount } from '@vue/test-utils';
import { expect } from 'chai';
import ChatText from '@/pages/chat/chatroom/view/components/text';
describe('ChatText.vue', () => {
it('人生中第一次单元测试:', () => {
const wrapper = mount(ChatText);
console.log(wrapper.html());
const subfix = '</p> <p>默认文字</p></div>';
expect(wrapper.html()).contain(subfix);
});
}); 注意,被测试组件必须以index.js暴露出组件。 意外收获1.PhantomJS是什么?
下载好phantomjs后,就可以在终端中模拟浏览器操作了。 var page = require('webpage').create();
page.open('http://www.google.com', function() {
setTimeout(function() {
page.render('google.png');
phantom.exit();
}, 200);
});
运行上述代码后,会生成一张图片,但是画质感人。 |
vue-test-utils的常用api及其option?
啥玩意儿???一一搞定。 mount:propsData,attachToDocument,slots,mocks,stubs?
后知后觉,这些都可以在Mounting Options文档查看:https://vue-test-utils.vuejs.org/api/options.html#context mount和shallowMount的区别是什么?mount仅仅挂载当前组件实例;而shallowMount挂载当前组件实例以外,还会挂载子组件。 |
前端的单元测试,到底该测什么?这是一个一直困扰我的问题。 就拿我负责的项目来说:
上述适用于单元测试的内容都有一个共同点:复用性高! 所以我们在纠结要不要写单元测试时,抓住复用性高这个特点去考虑就好了。 单元测试是为了保证什么呢?
所以,其实单元测试是为了帮助开发者的突破自己内心的最后一道心理障碍,建立老子的代码完全ojbk,不可能出问题的自信。 其实最终还是保证用户有无bug的组件可用,有好的软件或平台使用,让自己的生活变得更加美好。 如何为vue插件 eventbus 写单元测试?/*
title: vue插件eventbus单测
author:frankkai
target: 1.Vue.use(eventBus)是否可以正确注入$bus到prototype
2.注入的$bus是否是一个正常的Vue实例
*/
import eventbusPlugin from '@/plugins/bus';
import { createLocalVue, createWrapper } from '@vue/test-utils';
import { expect } from 'chai';
const localVue = createLocalVue();
localVue.use(eventbusPlugin);
describe('/plugins/bus.js', () => {
it('Vue.use(eventBus)是否可以正确注入$bus到prototype:', () => {
expect('$bus' in localVue.prototype).to.equal(true);
});
it('注入的$bus是否是一个正常的Vue实例:', () => {
const localVueInstance = (() =>
localVue.component('empty-vue-component', {
render(createElement) {
return createElement('div');
},
}))();
const Constructor = localVue.extend(localVueInstance);
const vm = new Constructor().$mount();
const wrapper = createWrapper(vm);
if ('$bus' in localVue.prototype) {
expect('$bus' in wrapper.vm).to.equal(true);
}
});
}); |
记录一些自己的困惑。
The text was updated successfully, but these errors were encountered: