<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          基于Vue的Jest單元測(cè)試入門與實(shí)踐

          共 12066字,需瀏覽 25分鐘

           ·

          2020-10-12 16:23

          點(diǎn)擊上方藍(lán)字關(guān)注我們


          介紹

          Vue-Test-UtilsVue.js 官方的單元測(cè)試實(shí)用工具庫,它提供了一系列的 API 來使得我們可以很便捷的去寫 Vue 應(yīng)用中的單元測(cè)試。

          主流的單元測(cè)試運(yùn)行器有很多,比如 JestMochaKarma 等,這幾個(gè)在 Vue-Test-Utils 文檔里都有對(duì)應(yīng)的教程,這里我們只介紹 Vue-Test-Utils + Jest 結(jié)合的示例。

          ?

          Jest 是一個(gè)由 Facebook 開發(fā)的測(cè)試框架。Vue 對(duì)其進(jìn)行描述:是功能最全的測(cè)試運(yùn)行器。它所需的配置是最少的,默認(rèn)安裝了 JSDOM,內(nèi)置斷言且命令行的用戶體驗(yàn)非常好。不過你需要一個(gè)能夠?qū)挝募M件導(dǎo)入到測(cè)試中的預(yù)處理器。我們已經(jīng)創(chuàng)建了 vue-jest 預(yù)處理器來處理最常見的單文件組件特性,但仍不是 vue-loader 100% 的功能。

          ?

          環(huán)境配置

          通過腳手架 vue-cli 來新建項(xiàng)目的時(shí)候,如果選擇了 Unit Testing 單元測(cè)試且選擇的是 Jest 作為測(cè)試運(yùn)行器,那么在項(xiàng)目創(chuàng)建好后,就會(huì)自動(dòng)配置好單元測(cè)試需要的環(huán)境,直接能用 Vue-Test-UtilsJestAPI 來寫測(cè)試用例了。

          但是新建項(xiàng)目之初沒有選擇單元測(cè)試功能,需要后面去添加的話,有兩種方案:

          第一種配置:

          直接在項(xiàng)目中添加一個(gè) unit-jest 插件,會(huì)自動(dòng)將需要的依賴安裝配置好。

          vue?add?@vue/unit-jest

          第二種配置:

          這種配置會(huì)麻煩一點(diǎn),下面是具體的操作步驟。

          安裝依賴

          • 安裝 JestVue Test Utils

            npm?install?--save-dev?jest?@vue/test-utils
          • 安裝 babel-jestvue-jest7.0.0-bridge.0 版本的 babel-core

            npm?install?--save-dev?babel-jest?vue-jest?babel-core@7.0.0-bridge.0
          • 安裝 jest-serializer-vue

            npm?install?--save-dev?jest-serializer-vue

          配置 Jest

          Jest 的配置可以在 package.json 里配置;也可以新建一個(gè)文件 jest.config.js, 放在項(xiàng)目根目錄即可。這里我選擇的是配置在 jest.config.js 中:

          module.exports?=?{
          ????moduleFileExtensions:?[
          ????????'js',
          ????????'vue'
          ????],
          ????transform:?{
          ????????'^.+\\.vue$':?'/node_modules/vue-jest',
          ????????'^.+\\.js$':?'/node_modules/babel-jest'
          ????},
          ????moduleNameMapper:?{
          ????????'^@/(.*)$':?'/src/$1'
          ????},
          ????snapshotSerializers:?[
          ????????'jest-serializer-vue'
          ????],
          ????testMatch:?['**/__tests__/**/*.spec.js'],
          ????transformIgnorePatterns:?['/node_modules/']
          }

          各配置項(xiàng)說明:

          • moduleFileExtensions 告訴 Jest 需要匹配的文件后綴
          • transform 匹配到 .vue 文件的時(shí)候用 vue-jest 處理, 匹配到 .js 文件的時(shí)候用 babel-jest 處理
          • moduleNameMapper 處理 webpack 的別名,比如:將 @ 表示 /src 目錄
          • snapshotSerializers 將保存的快照測(cè)試結(jié)果進(jìn)行序列化,使得其更美觀
          • testMatch 匹配哪些文件進(jìn)行測(cè)試
          • transformIgnorePatterns 不進(jìn)行匹配的目錄

          配置 package.json

          寫一個(gè)執(zhí)行測(cè)試的命令腳本:

          {
          ????"script":?{
          ????????"test":?"jest"
          ????}
          }

          第一個(gè)測(cè)試用例

          為了保證環(huán)境的一致性,我們從創(chuàng)建項(xiàng)目開始一步一步演示操作步驟。

          用 vue-cli 創(chuàng)建一個(gè)項(xiàng)目

          當(dāng)前我用到的是 3.10.0 版本的 vue-cli。開始創(chuàng)建項(xiàng)目:

          vue?create?first-vue-jest

          選擇 Manually select features 進(jìn)行手動(dòng)選擇功能配置:

          Vue?CLI?v3.10.0
          ┌───────────────────────────┐
          │??Update?available:?4.0.4??│
          └───────────────────────────┘
          ??Please?pick?a?preset:
          ??VUE-CLI3?(vue-router,?node-sass,?babel,?eslint)
          ??default?(babel,?eslint)
          ??Manually?select?features

          勾選 BabelUnit Testing

          ??Check?the?features?needed?for?your?project:
          ???Babel
          ???TypeScript
          ???Progressive?Web?App?(PWA)?Support
          ???Router
          ???Vuex
          ???CSS?Pre-processors
          ???Linter?/?Formatter
          ???Unit?Testing
          ???E2E?Testing

          選擇 Jest:

          ??Pick?a?unit?testing?solution:
          ??Mocha?+?Chai
          ??Jest

          選擇 In dedicated config files 將各配置信息配置在對(duì)應(yīng)的 config 文件里:

          ??Where?do?you?prefer?placing?config?for?Babel,?PostCSS,?ESLint,?etc.??(Use?arrow?keys)
          ??In?dedicated?config?files
          ??In?package.json

          輸入n,不保存預(yù)設(shè):

          ??Save?this?as?a?preset?for?future?projects??(y/N)?n

          項(xiàng)目創(chuàng)建完成后,部分文件的配置信息如下:

          babel.config.js:

          module.exports?=?{
          ????presets:?[
          ????????'@vue/cli-plugin-babel/preset'
          ????]
          }

          jest.config.js, 這個(gè)文件的配置默認(rèn)是預(yù)設(shè)插件的,可以按實(shí)際需求改成上面提到的配置 Jest 里的配置一樣。

          module.exports?=?{
          ????preset:?'@vue/cli-plugin-unit-jest'
          }

          package.json:

          {
          ????"name":?"first-vue-jest",
          ????"version":?"0.1.0",
          ????"private":?true,
          ????"scripts":?{
          ????????"serve":?"vue-cli-service?serve",
          ????????"build":?"vue-cli-service?build",
          ????????"test:unit":?"vue-cli-service?test:unit"
          ????},
          ????"dependencies":?{
          ????????"core-js":?"^3.1.2",
          ????????"vue":?"^2.6.10"
          ????},
          ????"devDependencies":?{
          ????????"@vue/cli-plugin-babel":?"^4.0.0",
          ????????"@vue/cli-plugin-unit-jest":?"^4.0.0",
          ????????"@vue/cli-service":?"^4.0.0",
          ????????"@vue/test-utils":?"1.0.0-beta.29",
          ????????"vue-template-compiler":?"^2.6.10"
          ????}
          }

          執(zhí)行測(cè)試命令

          用上面的步驟創(chuàng)建的項(xiàng)目完成項(xiàng)目后,我們可以在 package.jsonscripts 項(xiàng)中看到有個(gè) test:unit ,執(zhí)行它:

          cd?first-vue-jest
          npm?run?test:unit

          然后終端里會(huì)看到輸出結(jié)果,PASS 表示測(cè)試用例通過了,這個(gè)是官方提供單元測(cè)試?yán)印O旅嫖覀儊韺扅c(diǎn)自己的東西。

          實(shí)現(xiàn)一個(gè) ToDoList

          看上面的原型圖,有這么幾點(diǎn)明確的需求:

          • 在頭部右側(cè)輸入框輸入要做的事情,敲回車后,內(nèi)容跑到待完成列表里,同時(shí)清空輸入框
          • 輸入框?yàn)榭盏臅r(shí)候敲回車,不做任何變化
          • 待完成列表支持編輯功能,已完成列表不能進(jìn)行編輯
          • 每個(gè)列表項(xiàng)的右側(cè)都有刪除按鈕,用 - 號(hào)表示,點(diǎn)擊后刪除該項(xiàng)
          • 待完成列表有標(biāo)記為已完成的按鈕,用 號(hào)表示,點(diǎn)擊后當(dāng)前項(xiàng)移動(dòng)到已完成列表
          • 已完成列表有標(biāo)記為未完成的按鈕,用 x 號(hào)表示,點(diǎn)擊后當(dāng)前項(xiàng)移動(dòng)到未完成列表
          • 列表序號(hào)從1開始遞增
          • 當(dāng)待完成列表為空的時(shí)候,不顯示待完成字樣
          • 當(dāng)已完成列表為空的時(shí)候,不顯示已完成字樣

          先把上面的頁面寫好

          寫頁面之前先把創(chuàng)建項(xiàng)目的時(shí)候生成的 HelloWorld.vue 和對(duì)應(yīng)的測(cè)試文件 example.spec.js 刪除;同時(shí)修改 App.vue 文件,引入 ToDoList 組件:

          <template>
          ????<div?id="app">
          ????????<ToDoList>ToDoList>
          ????div>
          template>

          <script>
          import?ToDoList?from?'./components/ToDoList'

          export?default?{
          ????components:?{
          ????????ToDoList
          ????}
          }
          script>

          src/compoents 下新建一個(gè)文件 ToDoList.vue,樣式較多就不貼出來了,具體可以去看本項(xiàng)目源碼:

          <template>
          ????<div?class="todolist">
          ????????<header>
          ????????????<h5>ToDoListh5>
          ????????????<input?class="to-do-text"?
          ????????????????v-model="toDoText"?
          ????????????????@keyup.enter="enterText"?
          ????????????????placeholder="輸入計(jì)劃要做的事情"/>

          ????????header>
          ????????<h4?v-show="toDoList.length?>?0">待完成h4>
          ????????<ul?class="wait-to-do">
          ????????????<li?v-for="(item,?index)?in?toDoList"?:keys="item">
          ????????????????<p>
          ????????????????????<i>{{index?+?1}}i>
          ????????????????????<input?:value="item"?@blur="setValue(index,?$event)"?type="text"?/>
          ????????????????p>
          ????????????????<p>
          ????????????????????<span?class="move"?@click="removeToComplete(item,?index)">span>
          ????????????????????<span?class="del"?@click="deleteWait(index)">-span>
          ????????????????p>
          ????????????li>
          ????????ul>
          ????????<h4?v-show="completedList.length?>?0">已完成h4>
          ????????<ul?class="has-completed">
          ????????????<li?v-for="(item,?index)?in?completedList"?:keys="item">
          ????????????????<p>
          ????????????????????<i>{{index?+?1}}i>
          ????????????????????<input?:value="item"?disabled="true"?type="text"?/>
          ????????????????p>
          ????????????????<p>
          ????????????????????<span?class="move"?@click="removeToWait(item,?index)">xspan>
          ????????????????????<span?class="del"?@click="deleteComplete(index)">-span>
          ????????????????p>
          ????????????li>
          ????????ul>
          ????div>
          template>
          
          
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    国产毛片一区二区三区亖区内套视频 | 动漫黄色视频网站 | 大香蕉一区二区三区 | 波多野结衣一区二区三区漫画 | 色小姐综合网 |