この記事では主に Vue のユニットテストの詳細な説明を紹介します。Karma+Mocha の学習メモを共有して参考にします。
vue-cli を使用してプロジェクトを作成する場合、単体テストと e2e テストをインストールするかどうかを尋ねられます。これら 2 つのテスト フレームワークの使用が公式に推奨されているので、学習して実践してみましょう。
はじめに
Karma
Karma は、Node.js をベースにした JavaScript テスト実行プロセス管理ツール (Test Runner) です。 Vue におけるこのツールの主な機能は、テストのためにさまざまな主流の Web ブラウザーでプロジェクトを実行することです。
言い換えれば、ブラウザ環境でコードをテストできるようにするテストツールです。これが必要な理由は、コードがブラウザー側で実行されるように設計されている可能性があり、ノード環境でのテストでは一部のバグが検出されない可能性があるためです。また、ブラウザーに互換性の問題がある場合、karma は次の手段を提供します。複数のブラウザ上でコードを自動的に実行します。ブラウザ (Chrome、Firefox、IE など) 環境で実行します。コードがノード側でのみ実行される場合は、karma を使用する必要はありません。
Mocha
Mocha は、chai アサーション ライブラリを使用して vue-cli で単体テストを実装するテスト フレームワークです。
Chai アサーション ライブラリについては、Chai.js アサーション ライブラリ API の中国語ドキュメントを参照してください。それを確認して使用するだけですぐに習得できます。
テストフレームワークについての私の理解
npm実行ユニット実行プロセス
npm実行ユニットコマンドを実行します
Karma実行環境を開きます
Mochaを使用して書かれたものを1つずつテストしますChai アサーションを使用したテスト ケース
は、ターミナルにテスト結果を表示します
テストが成功すると、karma-coverage はテスト カバレッジ結果を含む Web ページを ./test/unit/coverage フォルダーに生成します。
Karma
Karma については、その構成オプションについて学びました。
以下は簡単なコメント付きの Vue の Karma 構成です:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | var webpackConfig = require ('../../build/webpack.test.conf')
module.exports = function (config) {
config.set({
browsers: ['PhantomJS'],
frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
reporters: ['spec', 'coverage'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
}
})
}
|
ログイン後にコピー
Mocha と Chai
公式の例を見てみましょう (すべてコードの意味を説明するコメント付き):
1 2 3 4 5 6 7 8 9 10 11 12 13 | import Vue from 'vue'
import Hello from '@/components/Hello'
describe('Hello.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(Hello)
const vm = new Constructor(). $mount ()
expect(vm. $el .querySelector('.hello h1').textContent)
.to.equal('Welcome to Your Vue.js App')
})
})
|
ログイン後にコピー
知識知っておくべき点:
テスト スクリプトは test/unit/specs/ ディレクトリに配置する必要があります。
スクリプトの命名方法は[コンポーネント名].spec.jsです。
いわゆるアサーションは、コンポーネントに対していくつかの操作を実行し、結果を予測することです。テスト結果がアサーションと同じであれば、テストは合格します。
デフォルトでは、単体テストは main.js を除く src ディレクトリ内のすべてのファイルをテストします。main.js は test/unit/index.js ファイルで変更できます。
Chai アサーション ライブラリでは、to be は、that と have with at を同じものとします。これらの言語チェーンは意味がなく、理解を容易にするためのものです。
テストスクリプトは複数の descibe で構成され、それぞれの description は複数の it で構成されます。
非同期テストを理解する
1 2 3 4 5 6 7 8 | it('异步请求应该返回一个对象', done => {
request
.get('https:
. end ( function (err, res){
expect(res).to.be.an('object');
done();
});
});
|
ログイン後にコピー
describeのフック(ライフサイクル)を理解する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | describe('hooks', function () {
before( function () {
});
after( function () {
});
beforeEach( function () {
});
afterEach( function () {
});
});
|
ログイン後にコピー
実践
上記は単体テストの使い方を簡単に紹介したので、Vueで単体テストを始めてみましょう!
util.js
公式の Vue デモからわかるように、Vue 単体テストではコンポーネントを Vue インスタンスにインスタンス化する必要があり、場合によってはそれを DOM にマウントする必要があります。
1 2 | const Constructor = Vue.extend(Hello)
const vm = new Constructor(). $mount ()
|
ログイン後にコピー
上記の記述方法は単にコンポーネントを取得するためのものであり、場合によっては props 属性やカスタム メソッドなどを渡す必要があり、サードパーティの UI フレームワークを使用する必要がある場合もあります。したがって、上記の書き方は非常に面倒です。
ここでは、Vue 単体テストで一般的に使用されるメソッドをカプセル化する、Element の単体テスト ツール スクリプト Util.js をお勧めします。次のデモも Util.js に基づいて作成されています。
各メソッドの目的について簡単に説明します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
exports.destroyVM = function (vm) {}
exports.createVue = function (Compo, mounted = false) {}
exports.createTest = function (Compo, propsData = {}, mounted = false) {}
exports.triggerEvent = function (elm, name, ...opts) {}
exports.triggerClick = function (elm, ...opts) {}
|
ログイン後にコピー
例 1
例 1 では、Hello コンポーネントのさまざまな要素のデータをテストし、util.js の destroyVM メソッドと createTest メソッドの使用法、およびテスト用のターゲット要素を取得する方法を学びました。 DOM 要素の取得方法については、「DOM オブジェクトのチュートリアル」を参照してください。
Hello.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <template>
<p class = "hello" >
<h1 class = "hello-title" >{{ msg }}</h1>
<h2 class = "hello-content" >{{ content }}</h2>
</p>
</template>
<script>
export default {
name: 'hello',
props: {
content: String
},
data () {
return {
msg: 'Welcome!'
}
}
}
</script>
|
ログイン後にコピー
Hello.spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import { destroyVM, createTest } from '../util'
import Hello from '@/components/Hello'
describe('Hello.vue', () => {
let vm
afterEach(() => {
destroyVM(vm)
})
it('测试获取元素内容', () => {
vm = createTest(Hello, { content: 'Hello World' }, true)
expect(vm. $el .querySelector('.hello h1').textContent).to.equal('Welcome!')
expect(vm. $el .querySelector('.hello h2').textContent).to.have.be.equal('Hello World')
})
it('测试获取Vue对象中数据', () => {
vm = createTest(Hello, { content: 'Hello World' }, true)
expect(vm.msg).to.equal('Welcome!')
expect(vm.content).which.have.to.be.that.equal('Hello World')
})
it('测试获取DOM中是否存在某个 class ', () => {
vm = createTest(Hello, { content: 'Hello World' }, true)
expect(vm. $el .classList.contains('hello')).to.be.true
const title = vm. $el .querySelector('.hello h1')
expect(title.classList.contains('hello-title')).to.be.true
const content = vm. $el .querySelector('.hello-content')
expect(content.classList.contains('hello-content')).to.be.true
})
})
|
ログイン後にコピー
出力結果
Hello.vue
√ 要素のコンテンツを取得するテスト
√ Vue オブジェクト内のデータを取得するテスト
√ クラスかどうかを取得するテストDOM に存在します
例 2
例 2 では、createTest を使用してクリック イベントをテストするテスト コンポーネントを作成し、createVue を使用して Vue サンプル オブジェクトを作成して Click コンポーネントの使用をテストします。ここでは主に createVue メソッドの使用方法を確認できます。
Click.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <template>
<p>
<span class = "init-num" >初始值为{{ InitNum }}</span><br>
<span class = "click-num" >点击了{{ ClickNum }}次</span><br>
<span class = "result-num" >最终结果为{{ ResultNum }}</span><br>
<button @click= "add" >累加{{ AddNum }}</button>
</p>
</template>
<script>
export default {
name: 'Click',
props: {
AddNum: {
type: Number,
default : 1
},
InitNum: {
type: Number,
default : 1
}
},
data () {
return {
ClickNum: 0,
ResultNum: 0
}
},
mounted () {
this.ResultNum = this.InitNum
},
methods: {
add () {
this.ResultNum += this.AddNum
this.ClickNum++
this. $emit ('result', {
ClickNum: this.ClickNum,
ResultNum: this.ResultNum
})
}
}
}
</script>
|
ログイン後にコピー
Click.spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import { destroyVM, createTest, createVue } from '../util'
import Click from '@/components/Click'
describe('click.vue', () => {
let vm
afterEach(() => {
destroyVM(vm)
})
it('测试按钮点击事件', () => {
vm = createTest(Click, {
AddNum: 10,
InitNum: 11
}, true)
let buttonElm = vm. $el .querySelector('button')
buttonElm.click()
buttonElm.click()
buttonElm.click()
setTimeout(done => {
expect(vm.ResultNum).to.equal(41)
expect(vm. $el .querySelector('.init-num').textContent).to.equal('初始值为11')
expect(vm. $el .querySelector('.click-num').textContent).to.equal('点击了3次')
expect(vm. $el .querySelector('.result-num').textContent).to.equal('最终结果为41')
done()
}, 100)
})
it('测试创建Vue对象', () => {
let result
vm = createVue({
template: `
<click @click= "handleClick" ></click>
`,
props: {
AddNum: 10,
InitNum: 11
},
methods: {
handleClick (obj) {
result = obj
}
},
components: {
Click
}
}, true)
vm. $el .click()
vm. $nextTick (done => {
expect(result).to.be.exist
expect(result.ClickNum).to.equal(1)
expect(result.ResultNum).to.be.equal(21)
done()
})
})
|
ログイン後にコピー
出力結果
click.vue
√ ボタンクリックイベントのテスト
√ Vueオブジェクトの作成テスト
その他
すべてのサンプルコードはGithubに配置されていますリポジトリが見やすい。さらに優れたテスト ケースを確認したい場合は、Util.js を使用して Element の単体テスト スクリプトの作成方法を確認することをお勧めします。学習すべきテスト スクリプトは数多くあります。大多数の Vue ユーザーが使用する UI コンポーネント ライブラリであるため、テスト スクリプトは非常によく書かれている必要があります。これらのスクリプトをコピーすることもでき、Vue コンポーネントの単体テストを学習するのに非常に役立つと思います。
以下は、参考のために要素単体テストを読んだときのメモです。
Util.js 方法包含了大多数Vue组件化的测试需求。
vm.$el vm.$nextTick 和 vm.$ref 都是在测试过程中比较常用的一些Vue语法糖。
需要注意: vm.$nextTick 方法是异步的,所以需要在里面使用done方法。
异步断言,方法参数需要是 _ 或者 done
大多数时候查询元素通过 querySelector 方法查询class获得
1 | vm. $el .querySelector('.el-breadcrumb').innerText
|
ログイン後にコピー
大多数情况下查询是否存在某个Class通过 classList.contains 方法获得,查找的结果为 true 或 false
1 | vm. $el .classList.contains('el-button--primary')
|
ログイン後にコピー
异步测试必须以 done() 方法结尾。setTimeout 和 vm.$nextTick 是常用的异步测试。
实现按钮点击:通过获取按钮元素 btn,执行 btn.click() 方法实现。
由于 Vue 进行异步更新DOM 的情况,一些依赖DOM更新结果的断言必须在 Vue.nextTick 回调中进行。
1 2 3 4 5 6 7 8 | triggerEvent(vm. $refs .cascader. $el , 'mouseenter');
vm. $nextTick (_ => {
vm. $refs .cascader. $el .querySelector('.el-cascader__clearIcon').click();
vm. $nextTick (_ => {
expect(vm.selectedOptions.length).to.be.equal(0);
done();
});
});
|
ログイン後にコピー
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
在mint-ui中使用时间插件及获取选择值
VUE2实现二级省市联动选择
使用react实现分页组件
以上がVue単体テストにおけるKarma+Mochaの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。