如何對第一個Vue.js組件進行單元測試 (下) 原

我們的首次測試

       讓我們來寫首個測試。我們首先需要使用shallowMount手動掛載我們的組件,並將其存儲在我們將執行斷言的變量中。我們還可以通過propsData屬性傳遞道具作爲對象。

       已安裝的組件是一個對象,它有一些實用方法:

屏幕快照 2018-10-31 下午7.13.02.png

       然後,我們可以寫第一個斷言:

屏幕快照 2018-10-31 下午7.13.20.png

       讓我們來分析一下這裏發生了什麼。首先,我們使用Jest的expect函數,它將我們想要測試的值作爲參數。在我們的例子中,在父級上用findAll方法來獲取具有活動類的所有元素。這將返回一個WrapperArray,包含Wrappers數組的對象。

       一個WrapperArray有兩個屬性:父級(包含的Wrappers)和長度(Wrappers的數量)。後者是我們需要擁有預期數量的stars。

       expect函數還返回一個對象,我們可以在其上調用方法來測試傳遞的值。這些方法稱爲匹配器。在這裏,我們使用toEqual匹配器並將其作爲參數傳遞給期望值。該方法返回一個布爾值(boolean),這是測試通過或失敗的原因。

       總而言之,在這裏,我們期望在父級中找到的具有活動類的元素的總量應等於3(我們分配給等級道具的值)。

       在您的終端中,運行您的測試:

屏幕快照 2018-10-31 下午7.13.31.png

       你應該看到它通過。 

模擬用戶輸入

       Vue Test Utils可以輕鬆模擬真實用戶最終在實際中所做的事情。在我們的用例中,用戶可以點擊stars來切換它們。我們可以在測試中使用觸發器方法僞造它,並調度各種事件。

屏幕快照 2018-10-31 下午7.13.41.png

       在這裏,我們首先用findAll獲取第四顆star,它在傳遞的索引(從零開始的編號)中從WrapperArray返回一個Wrapper。然後,我們模擬它上面的點擊事件- 我們模仿點擊第四顆star的用戶行爲。

       由於我們將prop等級設置爲3,因此在我們點擊之前,第四個star應該處於非活動狀態,因此click事件應該使其處於活動狀態。在我們的代碼中,這由一個活動類表示,我們僅在它們被激活時附加在star上。我們通過調用star上的classes方法來測試它,它將類名作爲字符串數組返回。然後,我們使用toContain匹配器來確保活動類在這裏。

設置和拆解

       由於我們觸發了對組件的點擊,我們已經改變了它的狀態。問題是我們在所有測試中使用相同的組件。如果我們改變測試順序並將其移到第一個位置會發生什麼?然後第二次測試將失敗。

       在測試時,你不想依賴諸如命令這樣的脆弱的東西。測試套件應該是強大的,並且除非您破壞API,否則理想情況下現有測試應該不會改變。

       我們希望確保始終有一個可預測的父級來執行斷言。我們可以通過設置和拆卸功能實現這一目標。這可以幫助我們在運行測試之前初始化,然後進行清理。

       在我們的例子中,有一種方法可以是在每次測試之前創建我們的父級並在之後銷燬它。

屏幕快照 2018-10-31 下午7.13.59.png

       正如他們的名字所暗示的那樣,beforeEach和afterEach分別在每次測試之前和之後運行。通過這種方式,我們可以100%確定每當我們運行新測試時,我們都能使用新的父級。

測試的特殊標識符

       將選擇器與樣式和其他目的(例如測試鉤子)混合絕不是一個好主意。

       如果更改標籤名稱或類怎麼辦?

       如果您在要測試的元素上沒有特定的標識符,例如計數器,該怎麼辦?

您不想使用無用的類污染您的生產代碼。爲測試提供專用鉤子會更好,例如專用數據屬性,但僅限於測試期間。這樣就不會在最終構建中留下一團糟。

       處理此問題的一種方法是創建自定義Vue指令。

       Vue.js實例有一個指令方法,它接受兩個參數- 一個名稱,以及在DOM中注入時組件生命週期的鉤子函數。如果您不關心特定的鉤子,也可以傳遞單個函數。

       讓我們在src /中創建一個名爲directives的新目錄,並添加一個test.js文件。我們將在我們的指令中導出我們想要傳遞的函數。

屏幕快照 2018-10-31 下午7.14.10.png

       一個指令鉤子可以帶幾個參數,在我們的例子中,我們只需要前兩個:el和binding。el參數引用指令綁定的元素。binding參數是一個對象,它包含我們在指令中傳遞的數據。這樣我們就可以按照自己的意願操縱元素。

屏幕快照 2018-10-31 下午7.14.23.png

       我們將一個對象傳遞給我們的指令,因此我們可以從data-test-開始生成數據屬性。在處理函數中,我們綁定的每個屬性,並在元素上設置一個基於名稱和值的數據屬性。

       我們將一個對象傳遞給我們的指令,因此我們可以從data-test-開始生成數據屬性。在處理函數中,我們反覆綁定每個binding屬性,並在元素上設置一個基於名稱和值的數據屬性。

       現在我們需要註冊我們的指令,以使用它。我們可以在全球範圍內進行,但在我們的情況下,我們只會在本地註冊- 就在我們的Rating.vue組件中。

屏幕快照 2018-10-31 下午7.14.38.png

       我們的指令現在可以在v-test名稱下訪問。嘗試在計數器上設置以下指令:

屏幕快照 2018-10-31 下午7.14.47.png

       現在使用開發人員工具檢查瀏覽器中的HTML。你的面板應該是這樣的:

屏幕快照 2018-10-31 下午7.14.55.png

       開始工作了!現在,我們在開發模式和構建項目時都不需要這個。此數據屬性的唯一目的是能夠在測試期間定位元素,因此我們只想在運行它們時進行設置。爲此,我們可以使用Webpack提供的NODE_ENV環境變量,這是爲我們的項目提供動力的模塊捆綁器。

       當我們運行測試時,NODE_ENV被設置爲'test'。因此,我們可以使用它來確定何時設置測試屬性。

屏幕快照 2018-10-31 下午7.15.06.png

       在瀏覽器中刷新您的應用並再次檢查計數器:數據屬性已消失。

       現在我們可以對我們需要定位的所有元素使用v-test指令。讓我們從前面開始測試:

屏幕快照 2018-10-31 下午7.15.18.png

       我們用[data-test-id =“star”]替換了.star選擇器,它允許我們在不破壞測試的情況下更改類以用於演示目的。這也是單一責任原則和鬆散耦合的好處之一 。

       我們是否還應該爲我們測試的類使用這些鉤子?

       在將此指令設置爲要測試的目標元素之後,您可能想知道是否還應該使用它們來替換我們主動查找的類。讓我們看看第一次測試的斷言:

屏幕快照 2018-10-31 下午7.15.27.png

       我們應該對具有活動類的元素使用v-test,並在斷言中替換選擇器嗎?好問題。

       單元測試都是關於一次測試一件事。it函數的第一個參數是一個字符串,我們用它來描述我們從消費者的角度做的事情。

       包裝我們斷言的測試表示渲染一個類活動等於prop.grade的star列表。這是消費者的期望。當他們將數字傳遞給grade屬性時,他們希望獲得相同數量的活躍或選定的star。然而,在我們組件的邏輯中,活動類正是我們用來定義這個特徵的東西。我們根據具體情況進行分配,因此我們可以在視覺上區分活躍的stars。在這裏,這個特定類的存在正是我們想要測試的。

       因此,在決定是否應該使用已有的選擇器或設置v-test指令時,請問自己一個問題:我在測試什麼,並且使用此選擇器對業務邏輯透視圖有意義嗎?

它與功能或端到端測試有何不同?

       首先,單元測試組件可能看起來很奇怪。爲什麼要對UI和用戶交互進行單元測試?這不是功能測試嗎?

       在測試組件的公共API(也就是從消費者的角度來看)和從用戶角度測試組件之間存在着根本但微妙的差異。首先,讓我們強調一些重要的東西:我們正在測試定義良好的JavaScript函數,而不是UI。

       當您查看單個文件組件時,很容易忘記組件編譯成JavaScript函數。我們沒有測試底層的Vue機制,它從這個函數中導致了面向UI的副作用,比如在DOM中注入HTML。這就是Vue自己的測試已經解決的問題。在我們的例子中,我們的組件與任何其他函數沒有區別:它接受輸入並返回輸出。這些原因和後果是我們正在測試的,而不是其他任何東西。

       令人困惑的是,我們的測試與常規單元測試略有不同。通常,我們寫的東西如下:

屏幕快照 2018-10-31 下午7.15.35.png

       這裏沒有爭論。輸入和輸出數據,這就是我們所關心的。對於組件,我們期望呈現視覺的東西。我們正在通過虛擬DOM並測試節點的存在。這也是您使用Selenium或Cypress.io等工具進行功能或端到端測試的方法。那有什麼不同呢?

       通過單元測試,我們正在測試單獨的行爲。通過功能或端到端測試,我們正在測試場景。單元測試可確保程序單元的行爲符合預期。它面向組件的消費者- 在軟件中使用該組件的程序員。功能測試從用戶角度確保功能或工作流的行爲符合預期 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章