Новый год (пфф, уже почти середина года)
Раньше, из-за проблем с работой предыдущей компании, большие увольнения год назад, после долгого Праздника Весны. После этого я устроился в новую компанию, и как раз случайно нагнал очень срочный проект, был так занят, что давно не обновлял статью. Однако я вернулся!
оригинальный
Сделайте интерфейсную архитектуру Vue с нуля (6), модульное тестирование и покрытие кода
предисловие
Тест автоматизации, мы будем использовать карму и кошмар, содержание будет включать в себя:
- модульный тест
- e2e тестирование (кинуть статью) На самом деле модульное тестирование обычно используется при написании общедоступных пакетов, таких как общие библиотеки функций js и общие библиотеки компонентов пользовательского интерфейса. В основном модульное тестирование не используется при выполнении бизнес-проектов. Затем, для e2e-тестирования, это часто то, что нужно делать инженерам-испытателям, часто с использованием селена. Так разве фронтенду не нужно изучать тест? Ответ однозначно нет, иначе я напишу волос... Проект vue использует модульное тестирование и e2e. Библиотеки компонентов пользовательского интерфейса на основе Vue, такие как элемент Ele.me, cube-ui Didi и vant Zan, имеют модульные тесты (e2e, потому что это не обязательно). Слова Диди я спросил у Хуанга И, который использовал модульное тестирование и e2e для автоматизированного тестирования интерфейса своего проекта. Короче говоря, оба они основаны на сценариях приложений.Хотя e2e используется мало, а иногда и не входит в область автоматизации интерфейса, на самом деле это очень просто сделать, и этому нужно учиться!
1. Модульное тестирование
установить карму
npm install karma --save-dev
npm install karma-jasmine karma-chrome-launcher jasmine-core --save-dev
существуетpackage.json
изscripts
настроить"test": "karma start"
инициализировать карму
$ karma init my.conf.js
Which testing framework do you want to use?
Press tab to list possible options. Enter to move to the next question.
> mocha
Do you want to use Require.js?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no
Do you want to capture a browser automatically?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
>
What is the location of your source and test files?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Press Enter to move to the next question.
> test/**/*.js
>
Should any of the files included by the previous patterns be excluded?
You can use glob patterns, eg. "**/*.swp".
Press Enter to move to the next question.
>
Do you want Karma to watch all the files and run the tests on change?
Press tab to list possible options.
> yes
После первоначального успеха копияkarma.conf.js
конфигурационный файл.
Кстати, создайтеtest
папку, создайте копию в этой папкеindex.js
, содержание такое:
describe('A spec suite', function() {
it('contains a passing spec', function() {
console.log('Hello Karma')
})
})
Запустить его:npm run test
Мы увидим, что программа автоматически открывает браузер Chrome, а затем отображает результаты теста.
Формально напишите модульный тест
Реорганизуйте тестовую папку
.
└── unit
├── index.js
├── karma.conf.js
└── specs
└── dom.spec.js
Поскольку нам все еще нужно провести e2e-тестирование, поэтому при тестировании используйте каждую папку для различения, под блоком находится содержимое модульного теста.
Установите серию пакетов
karma-webpack
karma-sourcemap-loader
karma-coverage
chai
sinon
sinon-chai
karma-sinon-chai
karma-mocha-reporter
karma-webpack
: Поскольку код нашего проекта написан на es6 или es7, необходима компиляция веб-пакета.karma-sourcemap-loader
: SourceMap, очевидно, необходимоkarma-coverage
: Выполняйте покрытие кода, когда это необходимо.chai
: с утверждениями моккоsinon
: Шпионить, заглушать, издеваться над моккоsinon-chai
: Используйте chai, чтобы сделать утверждение sinon, которое можно назвать расширениемkarma-sinon-chai
: Удобно вызывать в тестовом коде, можно использовать expect, sinon.spy и т.д. напрямую, без импорта каждого файлаkarma-mocha-reporter
: отчет о завершении теста мокко
Как и Karma, Mocha, Chai, Sinon, этот тестовый инструмент я не буду представлять, все они представлены, и это тоже скучно. Я хочу научиться видеть свою справочную информацию, я потратил много времени на просмотр.
Изменить karma.conf.js
const webpackConfig = require('../../webpack.config.test.js')
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'sinon-chai'],
// list of files / patterns to load in the browser
files: [
'./index.js'
],
// list of files / patterns to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'./index.js': ['webpack', 'sourcemap', 'coverage']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['mocha', 'coverage'],
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
},
.
.
.
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
}
})
}
Изначально Karma находилась в корневом каталоге, мы просто переместили ее напрямую. Тогда не так много модификаций, позвольте мне немного объяснить:
- files: файлы для тестирования
- препроцессоры: перед импортом файлов нам нужно обработать каким образом, мы видели, включая веб-пакет, исходную карту, покрытие
- репортеры: отчет после завершения теста, нам нужен отчет мокко и отчет о покрытии
- coverageReporter: адрес файла отчета и настройки формы существования для генерации покрытия кода
- WebPack: В этом нужно ввести конфигурацию WebPack, мы видим вершину, представим файл webpack.test.config.js, мы введем конфигурацию
- промежуточное ПО веб-пакета:
stats: 'errors-only'
Мы делаем процесс компиляции веб-пакета не отображаемым, если компиляция не сообщает об ошибке
настроить webpack.test.config.js
const webpackConfigBase = require('./webpack.config.base.js')
const config = Object.assign(webpackConfigBase.config, {
// sourcemap 模式
devtool: '#inline-source-map',
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
},
})
module.exports = config
``
#### 编辑index.js入口文件
这个文件是为了配合`karma-webpack`的,详情见[Alternative Usage](https://github.com/webpack-contrib/karma-webpack#alternative-usage)
```js
// require all test files (files that ends with .spec.js)
// 语法说明:https://doc.webpack-china.org/guides/dependency-management/#require-context
const testsContext = require.context('./specs', true, /\.spec$/)
testsContext.keys().forEach(testsContext)
// require all src files which in the app/common/js for coverage.
// you can also change this to match only the subset of files that
// you want coverage for.
const srcContext = require.context('../../app/common/js/', true, /\.js$/)
srcContext.keys().forEach(srcContext)
тестовый код в./specs
В папке исходный файл для тестирования находится в../../app/common/js/
Вниз. Здесь я тестирую только некоторые общедоступные файлы js, если вам нужно протестировать другие, вы можете изменить их самостоятельно. Например, для некоторых библиотек компонентов пользовательского интерфейса на основе Vue, если вы хотите протестировать все коды компонентов, вам также необходимо внести некоторые изменения в конфигурацию.Для этого вы можете обратиться к проекту Didi cube-ui, который является достаточно полным и имеет высокая степень охвата.
Официальный тестовый код записи
редактироватьdom.spec.js
документ:
/**
* 测试common/utils/dom.js
*/
import * as dom from 'common/js/utils/dom.js'
// const expect = require('chai').expect 装过sinon-chai就不需要这句了;sinon同理
describe('utils/dom', () => {
// 测试hasClass
it('hasClass', () => {
const ele = document.createElement('div')
ele.className = 'base kitty'
// 是否含有base
expect(dom.hasClass(ele, 'base')).to.be.equal(true)
// 是否含有kitty
expect(dom.hasClass(ele, 'kitty')).to.be.equal(true)
// 是否含有tom
expect(dom.hasClass(ele, 'tom')).to.be.equal(false)
// 无参数
expect(dom.hasClass()).to.be.equal(false)
})
// 测试addClass
it('addClass', () => {
const ele = document.createElement('div')
ele.className = 'base'
// 增加类名kitty
dom.addClass(ele, 'kitty')
expect(ele.className).to.be.equal('base kitty')
// 再增加类名kitty,希望并不会有重复类名
dom.addClass(ele, 'kitty')
expect(ele.className).to.be.equal('base kitty')
})
// 测试removeClass
it('removeClass', () => {
const ele = document.createElement('div')
ele.className = 'base kitty'
// 删除类名kitty
dom.removeClass(ele, 'kitty')
expect(ele.className).to.be.equal('base')
// 删除不存在的类名
dom.removeClass(ele, 'tom')
expect(ele.className).to.be.equal('base')
})
// 测试noce
it('once', () => {
const ele = document.createElement('div')
const callback = sinon.spy()
dom.once(ele, 'click', callback)
// 点击一次
ele.click()
expect(callback).to.have.been.calledOnce
// 再点击一次,预期应该是不调用callback的,所以依然为calledOnce
ele.click()
expect(callback).to.have.been.calledOnce
})
})
Комментарии к коду уже очень понятны~
запустить тест
Сначала измените егоpackage.json
Конфигурация:"test:unit": "karma start test/unit/karma.conf.js"
бегать:
➜ construct git:(master) npm run test:unit
> vue-construct@1.0.0 test:unit /Users/Terry/WFE/vue-study/construct
> karma start test/unit/karma.conf.js
START:
ℹ 「wdm」:
ℹ 「wdm」: Compiled successfully.
ℹ 「wdm」: Compiling...
ℹ 「wdm」:
ℹ 「wdm」: Compiled successfully.
23 04 2018 01:25:39.438:INFO [karma]: Karma v2.0.0 server started at http://0.0.0.0:9876/
23 04 2018 01:25:39.440:INFO [launcher]: Launching browser Chrome with unlimited concurrency
23 04 2018 01:25:39.448:INFO [launcher]: Starting browser Chrome
23 04 2018 01:25:41.778:INFO [Chrome 66.0.3359 (Mac OS X 10.13.2)]: Connected on socket A9ZeKTNtnUU9MAceAAAA with id 51610088
utils/dom
✔ hasClass
✔ addClass
✔ removeClass
✔ once
Finished in 0.008 secs / 0.004 secs @ 01:25:41 GMT+0800 (CST)
SUMMARY:
✔ 4 tests completed
=============================== Coverage summary ===============================
Statements : 87.12% ( 142/163 ), 14 ignored
Branches : 61.25% ( 49/80 ), 22 ignored
Functions : 86.11% ( 31/36 ), 5 ignored
Lines : 90.79% ( 138/152 )
================================================================================
использованная литература
Прошлое и настоящее системы проверки кармы
Обзор интерфейсных инструментов автоматизированного тестирования
Анализ интерфейсных решений для автоматизированного тестирования
Поговорим об автоматизированном тестировании переднего плана.
Руководство Sinon: Написание тестов JavaScript с помощью макетов, шпионов и заглушек
Диссертация - очень интересная штука.Почитав дальше, вы с удивлением обнаружите, что многие подробные статьи от крупных компаний на самом деле являются чистыми переводами диссертации~ Также обратитесь к части тестирования проекта vue и cube-ui от Didi.