關於單元測試,咱們須要知道什麼?- 實踐篇 - 偏方法論層面

實踐篇

前言

本篇並不是完整指導讀者如何進行單元測試,可是會結合部分例子講解如何編寫測試代碼,從而引起讀者自行思考,而後會給出編寫單元測試途中建議。javascript

普通函數

舉個例子,咱們本身寫了一個校驗密碼格式(同時知足數字大小寫字母)的函數以下:html

function isRightPassWord(password) {
  const pattern = new RegExp(/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,16}$/);
  const isMatched = pattern.test(password);
  if (!isMatched) {
    return false;
  }
  return true;
}
複製代碼

那問題來了,咱們如何去進行測試呢?若咱們並無寫過任何的單元測驗,其實很難下手,咱們並不清楚測試點在哪裏?那咱們一塊兒思考幾個問題吧。vue

你測試的是什麼?

這部分咱們要描述好,咱們對應測試的函數是什麼,轉化成代碼就以下:java

describe('isRightPassWord function', () => {});
複製代碼

Ta 是來作什麼?

這部分咱們須要想一想,該函數的做用究竟是什麼,已經想一想對應的邊際狀況。因此該函數是幫助咱們校驗字符串是否同時知足數字大小寫字母的,想到一個如傳空的邊際狀況,如上思路轉成代碼,就是以下:react

test('with empty params', () => {});

test('with wrong params Aasdfxzs', () => {});

test('with correct params 123aAbBCc', () => {});
複製代碼

Ta 實際輸出什麼?預期輸出什麼?

這部分咱們須要講對應的上述條件的參數傳入被測函數,斷言對應的預期輸出,而後運行程序,查看實際輸出是否知足咱們預期,轉化成對應的代碼段,就是以下:git

// with empty params
expect(isRightPassWord()).toBe(false);
// with wrong params Aasdfxzs
expect(isRightPassWord('Aasdfxzs')).toBe(false);
// with correct params 123aAbBCc
expect(isRightPassWord('123aAbBCc')).toBe(true);
複製代碼

最後一步,運行程序查看實際輸出是否符合咱們的預期,而後繼續書寫其餘測試代碼,以後即是紅綠燈遊戲了。github

有一個問題,按照上文思路咱們是在函數完成後,進行補充對應的單測。過程實際體驗上和直接在業務層使用並無什麼差異,只是幫助咱們後續維護對應模塊有了一層保障機制。api

可是可否先寫好對應的測試,而後根據測試在驅動咱們編寫對應的函數呢?這就是TDD概念。其實這樣更符合咱們的編寫代碼習慣,只是將部分前置條件轉化爲對應的測試代碼。app

解釋一下,在編寫代碼以前會思考對應的需求,更可能是實現部分是如何實現該需求,而後邊在業務邏輯層使用,邊修改對應的代碼段,然則這樣循環機制中跳出的條件,直觀的是知足了直接需求條件,但部分邊界條件或許在需求測試期間被發現,而後從新開啓循環機制,而跳出的條件就是修復對應問題並知足直接條件。框架

咱們一塊兒優化對應的流程,起點咱們會思考對應的需求,將其拆解出若干個問題。如何對應的直接需求?對應的邊際狀況有哪些?而後根據對應的問題,進行書寫測試代碼,完成後運行測試,開始根據紅綠燈遊戲進行編寫功能。

這時候你應該會有一個問題,這樣作會形成時長大量增多吧?固然,其實思考的時候二者是差很少的,或是隻是多了一步將思考轉化成對應測試的步驟。那咱們的問題簡化爲如何減小書寫測試的時間?多寫,提取對應的模型,加入編輯器的 live Template 中。

結合 Vue

推薦官方教程,結合澳大利亞小哥的指南進行食用。若使用的CLI建立,可借鑑此文

借用Edd Yerburgh文中的一個例子,改寫以下:

// src/components/Foo.vue
<template>
  <div class="foo">
    <button id="change-message" @click="changeMessage">Change message</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    };
  },
  methods: {
    changeMessage() {
      this.msg = 'new message'
    }
  }
}
</script>
複製代碼

注意:你須要根據官網去安裝一堆的依賴包,而後如果自建項目,你須要處理好 Webpack 對應的loader問題。

// src/components/Foo.spec.js

import { expect } from 'chai'
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

describe('Foo.vue', () => {
  it('changes h1 text when #change-text is clicked', () => {
    const wrapper = mount(Foo)
    const changeMessage = wrapper.find('#change-message')
    changeMessage.trigger('click')
    const h1 = wrapper.find('h1')
    expect(h1.text()).to.equal('new message')
  })
})
複製代碼

@vue/test-utils提供了對應的函數,在測試環境實現了不一樣的掛載方式,或是你不清楚掛載方式的區別,請查看對應的官網,或是React單元測試筆記中的部分概念。官網也總結了對應的經常使用技巧

結合 React

很久沒主要寫過了 React 測試相關代碼,因此就不一一贅述對應的思路以及流程,畢竟單測方式是同樣的。查看了對應官網是有提供對應的測試依賴的。但我記得通常都是測試框架使用Jest + EnzymeEnzyme@vue/test-utils包裹組件,而後暴露出來的接口使用習慣仍是和jQuery的使用習慣差很少的。

如何實踐?

還記得引言篇的問題嗎?

你是否信任你寫的代碼嗎?

你如何檢測代碼質量?

你如何驗證你的記性?

將單測加入咱們實踐中,確實存在不少阻力,其做用是長遠的。不只幫助咱們細化自身處理方式,還幫助咱們引起自身的思考。如何將函數/函數抽離的更符合單一原則?如何區分功能界限?單測要不要強調覆蓋率?

參考文獻

  1. Vue 官方教程
  2. 【譯】每一個單元測試必須回答的 5 個問題
  3. Five Traps to Avoid While Unit Testing Vue.js
  4. How to unit test Vue components for beginners
  5. Vue testing handbook
相關文章
相關標籤/搜索