成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

在Vue項(xiàng)目中使用snapshot測(cè)試

blair / 3122人閱讀

摘要:在項(xiàng)目中使用測(cè)試介紹測(cè)試又稱(chēng)快照測(cè)試,可以直觀地反映出組件是否發(fā)生了未預(yù)見(jiàn)到的變化。結(jié)合進(jìn)行測(cè)試生成快照時(shí)需要渲染并掛載組件,在中可以使用官方的單元測(cè)試實(shí)用工具。

在Vue項(xiàng)目中使用snapshot測(cè)試 snapshot介紹

snapshot測(cè)試又稱(chēng)快照測(cè)試,可以直觀地反映出組件UI是否發(fā)生了未預(yù)見(jiàn)到的變化。snapshot如字面上所示,直觀描述出組件的樣子。通過(guò)對(duì)比前后的快照,可以很快找出UI的變化之處。

第一次運(yùn)行快照測(cè)試時(shí)會(huì)生成一個(gè)快照文件。之后每次執(zhí)行測(cè)試的時(shí)候,會(huì)生成一個(gè)快照,然后對(duì)比最初生成的快照文件,如果沒(méi)有發(fā)生改變,則通過(guò)測(cè)試。否則測(cè)試不通過(guò),同時(shí)會(huì)輸出結(jié)果,對(duì)比不匹配的地方。

jest中的快照文件以為snap拓展名結(jié)尾,格式如下(ps: 在沒(méi)有了解之前,我還以為是快照文件是截圖)。一個(gè)快照文件中可以包含多個(gè)快照,快照的格式其實(shí)是HTML字符串,對(duì)于UI組件,其HTML會(huì)反映出其內(nèi)部的state。每次測(cè)試只需要對(duì)比字符串是否符合初始快照即可。

exports[`button 1`] = `"
1
"`;

snapshot測(cè)試不通過(guò)的原因有兩個(gè)。一個(gè)原因是組件發(fā)生了未曾預(yù)見(jiàn)的變化,此時(shí)應(yīng)檢查代碼。另一個(gè)原因是組件更新而快照文件并沒(méi)有更新,此時(shí)要運(yùn)行jest -u更新快照。

? 1 snapshot failed from 1 test suite. Inspect your code changes or re-run jest with -u to update them.
結(jié)合Vue進(jìn)行snapshot測(cè)試

生成快照時(shí)需要渲染并掛載組件,在Vue中可以使用官方的單元測(cè)試實(shí)用工具Vue Test Utils。

Vue Test Utils 提供了mount、shallowMount這兩個(gè)方法,用于創(chuàng)建一個(gè)包含被掛載和渲染的 Vue 組件的 Wrapper。component是一個(gè)vue組件,options是實(shí)例化Vue時(shí)的配置,包括掛載選項(xiàng)和其他選項(xiàng)(非掛載選項(xiàng),會(huì)將它們通過(guò)extend覆寫(xiě)到其組件選項(xiàng)),結(jié)果返回一個(gè)包括了一個(gè)掛載組件或 vnode,以及測(cè)試該組件或 vnode 的方法的Wrapper實(shí)例。

mount(component:{Component}, options:{Object})

shallowMountmount不同的是被存根的子組件,詳細(xì)請(qǐng)戳文檔。

Wrapper上的豐富的屬性和方法,足以應(yīng)付本文中的測(cè)試需求。html()方法返回Wrapper DOM 節(jié)點(diǎn)的 HTML 字符串。find()findAll()可以查找Wrapper里的DOM節(jié)點(diǎn)或Vue組件,可用于查找監(jiān)聽(tīng)事件的元素。trigger可以在DOM節(jié)點(diǎn)/組件上觸發(fā)一個(gè)事件。

結(jié)合上述的方法,我們可以完成一個(gè)模擬事件觸發(fā)的快照測(cè)試。

細(xì)心的讀者可能會(huì)發(fā)現(xiàn),我們平時(shí)在使用Vue時(shí),數(shù)據(jù)更新后視圖并不會(huì)立即更新,需要在nextTick回調(diào)中處理更新完成后的任務(wù)。但在 Vue Test Utils 中,為簡(jiǎn)化用法,更新是同步的,所以無(wú)需在測(cè)試中使用 Vue.nextTick 來(lái)等待 DOM 更新。

demo演示

Vue Test Utils官方文檔中提供了一個(gè)集成VTU和Jest的demo,不過(guò)這個(gè)demo比較舊,官方推薦用CLI3創(chuàng)建項(xiàng)目。

執(zhí)行vue create vue-snapshot-demo創(chuàng)建demo項(xiàng)目,創(chuàng)建時(shí)要選擇單元測(cè)試,提供的庫(kù)有Mocha + ChaiJest,在這里選擇Jest.安裝完成之后運(yùn)行npm run serve即可運(yùn)行項(xiàng)目。

本文中將用一個(gè)簡(jiǎn)單的Todo應(yīng)用項(xiàng)目來(lái)演示。這個(gè)Todo應(yīng)用有簡(jiǎn)單的添加、刪除和修改Todo項(xiàng)狀態(tài)的功能;Todo項(xiàng)的狀態(tài)有已完成和未完成,已完成時(shí)不可刪除,未完成時(shí)可刪除;已完成的Todo項(xiàng)會(huì)用一條線橫貫文本,未完成項(xiàng)會(huì)在鼠標(biāo)懸浮時(shí)展示刪除按鈕。

組件簡(jiǎn)單地劃分為T(mén)odo和TodoItem。TodoItem在Todo項(xiàng)未完成且觸發(fā)mouseover事件時(shí)會(huì)展示刪除按鈕,觸發(fā)mouseleave時(shí)則隱藏按鈕(這樣可以在快照測(cè)試中模擬事件)。TodoItem中有一個(gè)checkbox,用于切換Todo項(xiàng)的狀態(tài)。Todo項(xiàng)完成時(shí)會(huì)有一個(gè)todo-finished類(lèi),用于實(shí)現(xiàn)刪除線效果。

為方便這里只介紹TodoItem組件的代碼和測(cè)試。




進(jìn)行快照測(cè)試時(shí),除了測(cè)試數(shù)據(jù)渲染是否正確外還可以模擬事件。這里只貼快照測(cè)試用例的代碼,完整的代碼戳我。

describe("TodoItem snapshot test", () => {
    it("first render", () => {
        const wrapper = shallowMount(TodoItem, {
            propsData: {
                item: {
                    finished: true,
                    content: "test TodoItem"
                }
            }
        })
        expect(wrapper.html()).toMatchSnapshot()
    })

    it("toggle checked", () => {
        const renderer = createRenderer();
        const wrapper = shallowMount(TodoItem, {
            propsData: {
                item: {
                    finished: true,
                    content: "test TodoItem"
                }
            }
        })
        const checkbox = wrapper.find("input");
        checkbox.trigger("click");
        renderer.renderToString(wrapper.vm, (err, str) => {
            expect(str).toMatchSnapshot()
        })
    })
    
    it("mouseover", () => {
        const renderer = createRenderer();
        const wrapper = shallowMount(TodoItem, {
            propsData: {
                item: {
                    finished: false,
                    content: "test TodoItem"
                }
            }
        })
        wrapper.trigger("mouseover");
        renderer.renderToString(wrapper.vm, (err, str) => {
            expect(str).toMatchSnapshot()
        })
    })
})

這里有三個(gè)測(cè)試。第二個(gè)測(cè)試模擬checkbox點(diǎn)擊,將Todo項(xiàng)從已完成切換到未完成,期待類(lèi)todo-finished會(huì)被移除。第三個(gè)測(cè)試在未完成Todo項(xiàng)上模擬鼠標(biāo)懸浮,觸發(fā)mouseover事件,期待刪除按鈕會(huì)展示。

這里使用toMatchSnapshot()來(lái)進(jìn)行匹配快照。這里生成快照文件所需的HTML字符串有wrapper.html()Renderer.renderToString這兩種方式,區(qū)別在于前者是同步獲取,后者是異步獲取。

測(cè)試模擬事件時(shí),最好以異步方式獲取HTML字符串。同步方式獲取的字符串并不一定是UI更新后的視圖。

盡管VTU文檔中說(shuō)所有的更新都是同步,但實(shí)際上在第二個(gè)快照測(cè)試中,如果使用expect(wrapper.html()).toMatchSnapshot(),生成的快照文件中Todo項(xiàng)仍有類(lèi)todo-finished,期待的結(jié)果應(yīng)該是沒(méi)有類(lèi)todo-finished,結(jié)果并非更新后的視圖。而在第三個(gè)快照測(cè)試中,使用expect(wrapper.html()).toMatchSnapshot()生成的快照,按鈕如期望展示,是UI更新后的視圖。所以才不建議在DOM更新的情況下使用wrapper.html()獲取HTML字符串。

下面是兩種對(duì)比的結(jié)果,1是使用wrapper.html()生成的快照,2是使用Renderer.renderToString生成的。

exports[`TodoItem snapshot test mouseover 1`] = `
  • test TodoItem
  • `; exports[`TodoItem snapshot test mouseover 2`] = `
  • test TodoItem
  • `; exports[`TodoItem snapshot test toggle checked 1`] = `
  • test TodoItem
  • `; exports[`TodoItem snapshot test toggle checked 2`] = `
  • test TodoItem
  • `;

    這里使用vue-server-renderer提供的createRenderer來(lái)生成一個(gè)Renderer實(shí)例,實(shí)例方法renderToString來(lái)獲取HTML字符串。這種是典型的回調(diào)風(fēng)格,斷言語(yǔ)句在回調(diào)中執(zhí)行即可。

        // ...
        wrapper.trigger("mouseover");
        renderer.renderToString(wrapper.vm, (err, str) => {
            expect(str).toMatchSnapshot()
        })

    如果不想使用這個(gè)庫(kù),也可以使用VTU中提供的異步案例。由于wrapper.html()是同步獲取,所以獲取操作及斷言語(yǔ)句需要在Vue.nextTick()返回的Promise中執(zhí)行。

        // ...
        wrapper.trigger("mouseover");
        Vue.nextTick().then(()=>{
            expect(wrapper.html()).toMatchSnapshot()
        })
    觀察測(cè)試結(jié)果

    執(zhí)行npm run test:unityarn test:unit運(yùn)行測(cè)試。

    初次執(zhí)行,終端輸出會(huì)有Snapshots: 3 written, 3 total這一行,表示新增三個(gè)快照測(cè)試,并生成初始快照文件。

     ? 3 snapshots written.
    Snapshot Summary
     ? 3 snapshots written from 1 test suite.
    
    Test Suites: 1 passed, 1 total
    Tests:       7 passed, 7 total
    Snapshots:   3 written, 3 total
    Time:        2.012s
    Ran all test suites.
    Done in 3.13s.

    快照文件如下示:

    // Jest Snapshot v1, https://goo.gl/fbAQLP
    
    exports[`TodoItem snapshot test first render 1`] = `
  • test TodoItem
  • `; exports[`TodoItem snapshot test mouseover 1`] = `
  • test TodoItem
  • `; exports[`TodoItem snapshot test toggle checked 1`] = `
  • test TodoItem
  • `;

    第二次執(zhí)行測(cè)試后,輸出中有Snapshots: 3 passed, 3 total,表示有三個(gè)快照測(cè)試成功通過(guò),總共有三個(gè)快照測(cè)試。

    Test Suites: 1 passed, 1 total
    Tests:       7 passed, 7 total
    Snapshots:   3 passed, 3 total
    Time:        2s
    Ran all test suites.
    Done in 3.11s.

    修改第一個(gè)快照中傳入的content,重新運(yùn)行測(cè)試時(shí),終端會(huì)輸出不匹配的地方,輸出數(shù)據(jù)的格式與Git類(lèi)似,會(huì)標(biāo)明哪一行是新增的,哪一行是被刪除的,并提示不匹配代碼所在行。

        - Snapshot
        + Received
    
        - 
  • test TodoItem
  • +
  • test TodoItem content change
  • 88 | } 89 | }) > 90 | expect(wrapper.html()).toMatchSnapshot() | ^ 91 | }) 92 | 93 | it("toggle checked", () => { at Object.toMatchSnapshot (tests/unit/TodoItem.spec.js:90:32)

    同時(shí)會(huì)提醒你檢查代碼是否錯(cuò)誤或重新運(yùn)行測(cè)試并提供參數(shù)-u以更新快照文件。

    Snapshot Summary
     ? 1 snapshot failed from 1 test suite. Inspect your code changes or re-run jest with `-u` to update them.

    執(zhí)行npm run test:unit -- -uyarn test:unit -u更新快照,輸出如下示,可以發(fā)現(xiàn)有一個(gè)快照測(cè)試的輸出更新了。下次快照測(cè)試對(duì)照的文件是這個(gè)更新后的文件。

    Test Suites: 1 passed, 1 total
    Tests:       7 passed, 7 total
    Snapshots:   1 updated, 2 passed, 3 total
    Time:        2.104s, estimated 3s
    Ran all test suites.
    Done in 2.93s.
    其他

    除了使用toMatchSnapshot()外,還可以使用toMatchInlineSnapshot()。二者不同之處在于toMatchSnapshot()從快照文件中查找快照,而toMatchInlineSnapshot()則將傳入的參數(shù)當(dāng)成快照文件進(jìn)行匹配。

    配置Jest

    Jest配置可以保存在jest.config.js文件里,可以保存在package.json里,用鍵名jest表示,同時(shí)也允許行內(nèi)配置。

    介紹幾個(gè)常用的配置。

    rootDir

    查找Jest配置的目錄,默認(rèn)是pwd。

    testMatch

    jest查找測(cè)試文件的匹配規(guī)則,默認(rèn)是[ "**/__tests__/**/*.js?(x)", "**/?(*.)+(spec|test).js?(x)" ]。默認(rèn)查找在__test__文件夾中的js/jsx文件和以.test/.spec結(jié)尾的js/jsx文件,同時(shí)包括test.jsspec.js

    snapshotSerializers

    生成的快照文件中HTML文本沒(méi)有換行,是否能進(jìn)行換行美化呢?答案是肯定的。

    可以在配置中添加snapshotSerializers,接受一個(gè)數(shù)組,可以對(duì)匹配的快照文件做處理。jest-serializer-vue這個(gè)庫(kù)做的就是這樣任務(wù)。

    如果你想要實(shí)現(xiàn)這個(gè)自己的序列化任務(wù),需要實(shí)現(xiàn)的方法有testprint。test用于篩選處理的快照,print返回處理后的結(jié)果。

    后記

    在未了解測(cè)試之前,我一直以為測(cè)試是枯燥無(wú)聊的。了解過(guò)快照測(cè)試后,我發(fā)現(xiàn)測(cè)試其實(shí)蠻有趣且實(shí)用,同時(shí)由衷地感嘆快照測(cè)試的巧妙之處。如果這個(gè)簡(jiǎn)單的案例能讓你了解快照測(cè)試的作用及使用方法,就是我最大的收獲。

    如果有問(wèn)題或錯(cuò)誤之處,歡迎指出交流。

    參考鏈接

    vue-test-utils-jest-example

    Jest - Snapshot Testing

    Vue Test Utils

    Vue SSR 指南

    文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/100522.html

    相關(guān)文章

    • 10秒鐘構(gòu)建你自己的”造輪子”工廠! 2019年github/npm工程化協(xié)作開(kāi)發(fā)棧最佳實(shí)踐

      摘要:年工程化協(xié)作開(kāi)發(fā)棧最佳實(shí)踐我們將花半小時(shí)實(shí)戰(zhàn)擼一個(gè)包含,的標(biāo)準(zhǔn)的用于工程協(xié)作的包開(kāi)發(fā)棧。使用腳手架,秒鐘構(gòu)建可自由配置的開(kāi)發(fā)棧。分別表示詢問(wèn)彈窗自動(dòng)執(zhí)行任務(wù)執(zhí)行任務(wù)后操作。 發(fā)起一個(gè)github/npm工程協(xié)作項(xiàng)目,門(mén)檻太高了??! 最基礎(chǔ)的問(wèn)題,你都要花很久去研究: 如何在項(xiàng)目中全線使用es2017代碼? 答案是babel 如何統(tǒng)一所有協(xié)作者的代碼風(fēng)格? 答案是eslint + pr...

      dongfangyiyu 評(píng)論0 收藏0
    • 使用Maven管理Java項(xiàng)目

      摘要:添加的的依賴,可以從項(xiàng)目的中拷貝使用命令編譯項(xiàng)目。在子模塊中我們可以這樣使用引入父模塊坐標(biāo)三使用建立項(xiàng)目新建一個(gè)項(xiàng)目,選擇,如圖所示在中配置插件可參見(jiàn)官方文檔。部署項(xiàng)目到即可。 一、Maven入門(mén) 1.下載maven Maven是基于項(xiàng)目對(duì)象模型(Project Object Model),可以通過(guò)一小段描述信息來(lái)管理項(xiàng)目的構(gòu)建、報(bào)告和文檔的項(xiàng)目管理工具,提供了一個(gè)倉(cāng)庫(kù)的概念,統(tǒng)一...

      yiliang 評(píng)論0 收藏0
    • SpringBoot-vue 基于Java的微服務(wù)全??焖匍_(kāi)發(fā)實(shí)踐

      摘要:本項(xiàng)目將使用配合最簡(jiǎn)單的邏輯來(lái)展示一個(gè)基于的微服務(wù)全??焖匍_(kāi)發(fā)實(shí)踐的。提供一系列大型項(xiàng)目常用的非功能性特征,比如內(nèi)嵌服務(wù)器,安全,指標(biāo),健康檢測(cè),外部化配置。 SprintBoot-Vue SpringBoot + 前端MVVM 基于Java的微服務(wù)全棧快速開(kāi)發(fā)實(shí)踐 showImg(https://segmentfault.com/img/remote/1460000010167913...

      FleyX 評(píng)論0 收藏0
    • SpringBoot-vue 基于Java的微服務(wù)全??焖匍_(kāi)發(fā)實(shí)踐

      摘要:本項(xiàng)目將使用配合最簡(jiǎn)單的邏輯來(lái)展示一個(gè)基于的微服務(wù)全棧快速開(kāi)發(fā)實(shí)踐的。提供一系列大型項(xiàng)目常用的非功能性特征,比如內(nèi)嵌服務(wù)器,安全,指標(biāo),健康檢測(cè),外部化配置。 SprintBoot-Vue SpringBoot + 前端MVVM 基于Java的微服務(wù)全棧快速開(kāi)發(fā)實(shí)踐 showImg(https://segmentfault.com/img/remote/1460000010167913...

      neu 評(píng)論0 收藏0
    • 前端每周清單第 10 期:Firefox53、React VR發(fā)布、Microsoft Edge現(xiàn)代

      摘要:新聞熱點(diǎn)國(guó)內(nèi)國(guó)外,前端最新動(dòng)態(tài)發(fā)布近日,正式發(fā)布新版本中提供了一系列的特性與問(wèn)題修復(fù)。而近日正式發(fā)布,其能夠幫助開(kāi)發(fā)者快速構(gòu)建應(yīng)用。 前端每周清單第 10 期:Firefox53、React VR發(fā)布、JS測(cè)試技術(shù)概述、Microsoft Edge現(xiàn)代DOM樹(shù)構(gòu)建及性能之道 為InfoQ中文站特供稿件,首發(fā)地址為這里;如需轉(zhuǎn)載,請(qǐng)與InfoQ中文站聯(lián)系。從屬于筆者的 Web 前端入門(mén)...

      MingjunYang 評(píng)論0 收藏0

    發(fā)表評(píng)論

    0條評(píng)論

    閱讀需要支付1元查看
    <