如何对第一个Vue.js组件进行单元测试
by Sarah Dayan
通過莎拉·達揚
In Build Your First Vue.js Component we made a star rating component. We’ve covered many fundamental concepts to help you create more complex Vue.js components.
在“ 構建您的第一個Vue.js組件”中,我們制作了星級評分組件。 我們介紹了許多基本概念,以幫助您創建更復雜的Vue.js組件。
Yet, there’s one crucial point you need to build bulletproof components you can use in production: unit testing.
但是,構建可在生產中使用的防彈組件的關鍵一點是: 單元測試 。
為什么要對組件進行單元測試? (Why unit test a component?)
Unit tests are a crucial part of continuous integration. They make your code a lot more reliable by focusing on small, isolated entities and making sure these always behave as expected. You can confidently iterate on your project without fear of breaking things.
單元測試是持續集成的關鍵部分。 通過專注于小的孤立實體并確保它們始終表現出預期的行為,它們使您的代碼更加可靠。 您可以放心地在您的項目上進行迭代,而不必擔心會遇到麻煩。
Unit tests aren’t limited to scripts. Anything we can test in isolation is unit testable, as long as you respect a few good practices. These practices include single-responsibility, predictability, and loose coupling.
單元測試不僅限于腳本。 只要您尊重一些良好做法,我們可以單獨測試的所有內容都是可以單元測試的。 這些實踐包括單一職責,可預測性和松散耦合。
As reusable entities of our app, Vue.js components are great candidates for unit testing. We’ll test the one we made as a single unit with various inputs and user interactions, and make sure it always behaves as we expect.
作為我們應用程序的可重用實體, Vue.js組件非常適合進行單元測試 。 我們將測試具有多個輸入和用戶交互的單個單元,并確保其始終像我們期望的那樣運行。
開始之前 (Before we start)
A few things have changed since the initial tutorial. Vue CLI 3 was released. Vue Test Utils — the official Vue.js unit testing utility library — has matured to beta version. In the first tutorial, we used webpack-simple, a prototyping template that doesn’t include testing features. For these reasons, the simplest thing to do is to wipe the slate clean and migrate the project from the tutorial to a more recent Vue.js install.
自從最初的教程以來,發生了一些變化。 Vue CLI 3已發布。 Vue Test Utils —官方的Vue.js單元測試實用程序庫—已成熟到beta版。 在第一個教程中,我們使用了webpack-simple ,這是一個不包含測試功能的原型模板。 由于這些原因,最簡單的方法是清除所有內容并將項目從教程遷移到最新的Vue.js安裝。
I re-created the project from the first tutorial so you can download it directly from GitHub. Then, navigate to the unzipped directory and install dependencies.
我從第一個教程中重新創建了該項目,因此您可以直接從GitHub下載它。 然后,導航到解壓縮目錄并安裝依賴項。
Note: make sure you install Node.js before going further:
注意:在繼續操作之前, 請確保安裝Node.js :
cd path/to/my/project npm installThen, run the project:
然后,運行項目:
npm run serveVue測試實用程序和笑話 (Vue Test Utils and Jest)
For this tutorial, we’ll use Vue Test Utils, the official Vue.js testing toolkit, along with Jest, a JavaScript test runner backed by Facebook.
在本教程中,我們將使用Vue Test Utils (官方Vue.js測試工具包)以及Jest (由Facebook支持JavaScript測試運行程序)一起使用。
Vue Test Utils lets you mount Vue components in isolation and simulate user interactions. It has all the necessary utilities to test single-file components, including those using Vue Router or Vuex.
Vue Test Utils可讓您隔離安裝Vue組件并模擬用戶交互。 它具有測試單文件組件的所有必需實用程序,包括使用Vue Router或Vuex的組件。
Jest is a full-featured test runner that requires almost no configuration. It also provides a built-in assertion library.
Jest是功能齊全的測試運行程序,幾乎不需要配置。 它還提供了一個內置的斷言庫。
Vue CLI 3 (which I used to generate the boilerplate) allows you to pick your favorite test runner, and sets it up for you. If you want to use another test runner (like Mocha), install Vue CLI 3 and generate your own starter project. Then you can migrate the source files from my boilerplate right in it.
Vue CLI 3(我用來生成樣板 )使您可以選擇自己喜歡的測試運行器,并為您進行設置。 如果要使用其他測試運行程序(例如Mocha ),請安裝Vue CLI 3并生成您自己的啟動程序項目。 然后,您可以在其中直接從樣板遷移源文件。
我們應該測試什么? (What should we test?)
A common approach of unit testing is to only focus on the public API (aka black box testing). By overlooking implementation details, you’re allowing internals to change without having to adapt tests. After all, what you want to do is make sure your public API won’t break. What happens under the hood is indirectly tested, but all that matters is for the public API to remain reliable.
單元測試的常見方法是僅關注公共API (又名黑盒測試)。 通過忽略實施細節,您無需更改測試即可允許內部更改。 畢竟,您要做的就是確保您的公共API不會損壞 。 幕后發生的事情經過間接測試,但重要的是公共API保持可靠。
This is also the official recommendation from the Vue Test Utils guides. Therefore, we’ll only test what we can access from the outside of the component:
這也是Vue Test Utils指南中的官方建議。 因此,我們僅測試可以從組件外部訪問的內容:
- user interactions 用戶互動
- props changes 道具變更
We won’t directly test computed properties, methods, or hooks. These will be implicitly tested by testing the public interface.
我們不會直接測試計算的屬性,方法或掛鉤。 這些將通過測試公共接口進行隱式測試。
設置規格文件 (Setting up a spec file)
Like with regular tests, each component has a spec file which describes all tests we want to run.
與常規測試一樣,每個組件都有一個規范文件,該文件描述了我們要運行的所有測試。
Specs are JavaScript files. By convention, they have the same name as the components they’re testing, plus a .spec suffix.
規范是JavaScript文件。 按照慣例,它們與要測試的組件同名,并帶有.spec后綴。
Go ahead and create a test/unit/Rating.spec.js file:
繼續創建一個test/unit/Rating.spec.js文件:
// Rating.spec.jsimport { shallowMount } from '@vue/test-utils'import Rating from '@/components/Rating'describe('Rating', () => { // your tests go here})We’ve imported our Rating component and shallowMount. The latter is a Vue Test Utils function which lets us mount our component without mounting its children.
我們已經導入了我們的Rating組件和shallowMount 。 后者是Vue Test Utils函數,它使我們可以在不安裝子組件的情況下安裝組件。
The describe function call wraps all the test we’re about to write — it describes our testing suite. It has its own scope, and can itself wrap other nested suites.
describe函數調用包裝了我們將要編寫的所有測試,它描述了我們的測試套件 。 它具有自己的作用域,并且本身可以包裝其他嵌套套件。
Enough said, let’s start writing tests.
夠了, 讓我們開始編寫測試 。
確定測試方案 (Identifying testing scenarios)
When we look at Rating from the outside, we can see it does the following:
當我們從外部查看Rating ,我們可以看到它執行以下操作:
it renders a list of stars which is equal to the value of the maxStars prop the user passes
它呈現一個與用戶通過的maxStars值相等的星星列表
it adds an active class to each star whose index is lower than or equal to the stars prop the user passes
它為索引小于或等于用戶通過的stars每個星星添加一個active類
it toggles the active class on a star when the user clicks it and removes it on the next stars
當用戶單擊某個active類別時,它將在該active類別上切換,然后在下一個active類別中將其刪除
it toggles the icons star and star-o when the user clicks a star
當用戶單擊星號時,它將在star和star-o切換
it renders a counter if the user sets the hasCounter prop to true, hides it if they set it to false, and displays text saying how many stars of the maximum number of stars are currently active.
如果用戶將hasCounter prop設置為true ,則將呈現一個計數器;如果將hasCounter prop設置為false ,則將隱藏該計數器;并顯示文本,說明當前處于活動狀態的最大星數中的幾顆。
Notice we’re only looking at what the component does from the outside. We don’t care that clicking a star executes the rate method, or that the internal stars data property changes. We could rename these, but this shouldn’t break our tests.
注意,我們只是從外部查看組件的功能。 我們不在乎單擊星標執行rate方法,還是在內部stars數據屬性更改。 我們可以重命名它們,但這不會破壞我們的測試。
我們的第一個測試 (Our first test)
Let’s write our first test. We first need to manually mount our component with shallowMount, and store it in a variable on which we’ll perform assertions. We can also pass props through the propsData attribute, as an object.
讓我們寫我們的第一個測試。 首先,我們需要使用shallowMount手動安裝組件,并將其存儲在將要執行斷言的變量中。 我們還可以將props作為對象通過propsData屬性傳遞。
The mounted component is an object which comes with a handful of useful utility methods:
掛載的組件是一個對象,帶有一些有用的實用程序方法:
describe('Rating', () => { const wrapper = shallowMount(Rating, { propsData: { maxStars: 6, grade: 3 } }) it('renders a list of stars with class `active` equal to prop.grade', () => { // our assertion goes here })})Then, we can write our first assertion:
然后,我們可以編寫第一個斷言:
it('renders a list of stars with class `active` equal to prop.grade', () => { expect(wrapper.findAll('.active').length).toEqual(3)})Let’s analyze what’s happening here. First, we’re using Jest’s expect function, which takes the value we want to test as an argument. In our case, we call the findAll method on our wrapper to fetch all elements with an active class. This returns a WrapperArray, which is an object that contains an array of Wrappers.
讓我們分析一下這里發生的事情。 首先,我們使用玩笑的expect功能,這需要我們想要的值來測試作為參數。 在我們的例子中,我們在wrapper上調用findAll方法來獲取具有active類的所有元素。 這將返回WrapperArray ,該對象是包含Wrappers數組的對象。
A WrapperArray has two properties: wrappers (the contained Wrappers) and length (the number of Wrappers). The latter is what we need to have the expected number of stars.
甲WrapperArray具有兩個屬性: wrappers (所包含的Wrappers )和length (的數量Wrappers )。 后者是我們需要具有預期星數的東西。
The expect function also returns an object on which we can call methods to test the passed value. These methods are called matchers. Here, we use the toEqual matcher and pass it the expected value as in arguments. The method returns a boolean, which is what a test expects to either pass or fail.
expect函數還返回一個對象,我們可以在該對象上調用方法以測試傳遞的值。 這些方法稱為匹配器 。 在這里,我們使用toEqual匹配器并將期望的值傳遞給參數。 該方法返回一個布爾值,這是測試期望通過或失敗的布爾值。
To summarize, here we say we expect the total amount of elements with the class active we find in our wrapper to be equal to 3 (the value we assigned to the grade prop).
總而言之,在這里我們說我們期望在包裝器中找到的active類的元素總數等于3(我們為grade道具分配的值)。
In your terminal, run your test:
在終端中,運行測試:
npm run test:unitYou should see it pass ?
您應該看到它通過嗎?
Time to write some more.
是時候寫更多了。
模擬用戶輸入 (Simulating user input)
Vue Test Utils makes it easy to simulate what real users end up doing in production. In our case, users can click on stars to toggle them. We can fake this in our tests with the trigger method, and dispatch all kinds of events.
Vue Test Utils使模擬真實用戶最終在生產中所做的工作變得容易。 在我們的情況下,用戶可以單擊星號來切換它們。 我們可以使用trigger方法在測試中進行偽造,并調度各種事件。
it('adds `active` class on an inactive star when the user clicks it', () => { const fourthStar = wrapper.findAll('.star').at(3) fourthStar.trigger('click') expect(fourthStar.classes()).toContain('active')})Here, we first get our fourth star with findAll and at, which returns a Wrapper from a WrapperArray at the passed index (zero-based numbering). Then, we simulate the click event on it — we’re mimicking the action from a user who would click or tap the fourth star.
在這里,我們首先使用findAll和at獲得第四顆星,它從WrapperArray返回傳入的索引(從零開始的編號)處的Wrapper 。 然后,我們模擬其上的click事件-我們模仿的是單擊或輕擊第四顆星星的用戶的操作。
Since we set the grade prop to 3, the fourth star should be inactive before we click, therefore the click event should make it active. In our code, this is represented by a class active which we append on stars only when they’re activated. We test it by calling the classes method on the star, which returns its class names as an array of strings. Then, we use the toContain matcher to make sure the active class is here.
由于我們將grade prop設置為3,因此在單擊之前第四顆星星應該處于非活動狀態,因此單擊事件應使其處于活動狀態。 在我們的代碼中,這由active類表示,僅當激活它們時,我們才將它們附加在星星上。 我們通過在星號上調用classes方法來對其進行測試,該方法將其類名稱作為字符串數組返回。 然后,我們使用toContain匹配器確保active類在此處。
設置和拆卸 (Setup and teardown)
Since we’ve triggered a click on our component, we’ve mutated its state. The problem is that we’re using that same component for all our tests. What happens if we change the order of our tests, and move this one to first position? Then the second test would fail.
由于我們觸發了組件的點擊,因此我們改變了它的狀態。 問題是我們在所有測試中都使用了相同的組件。 如果我們更改測試順序并將其移至第一位會發生什么? 然后第二次測試將失敗。
You don’t want to rely on brittle things like order when it comes to tests. A test suite should be robust, and existing tests should ideally not change unless you’re breaking the API.
在測試中,您不想依賴諸如訂單之類的易碎物品。 測試套件應該很健壯,并且理想情況下,除非破壞API,否則現有測試不應更改。
We want to make sure we always have a predictable wrapper to perform assertions on. We can achieve this with setup and teardown functions. These are helpers which let us initialize things before we run tests, and clean up afterward.
我們要確保始終有一個可預測的包裝器來執行斷言。 我們可以通過設置和拆卸功能來實現。 這些幫助程序使我們可以在運行測試之前初始化事情,然后進行清理。
In our case, a way of doing it could be to create our wrapper before each test and destroy it afterwards.
在我們的情況下,一種方法是在每次測試之前創建包裝,然后再銷毀它。
let wrapper = nullbeforeEach(() => { wrapper = shallowMount(Rating, { propsData: { maxStars: 6, grade: 3 } })})afterEach(() => { wrapper.destroy()})describe('Rating', () => { // we remove the `const wrapper = …` expression // …}As their names suggest, beforeEach and afterEach run before and after each test, respectively. This way we can be 100% sure we’re using a fresh wrapper whenever we run a new test.
顧名思義, beforeEach和afterEach分別在每個測試之前和之后運行。 這樣,我們可以在每次運行新測試時100%確保使用新包裝。
測試的特殊標識符 (Special identifiers for tests)
It’s never a good idea to mix selectors for styling and other purposes, such as test hooks.
混合使用選擇器以進行樣式設計和其他用途(例如測試掛鉤)絕不是一個好主意。
What if you change the tag name or the class?
如果更改標簽名稱或類怎么辦?
What if you don’t have a specific identifier on an element you want to test such as, in our case, the counter?
如果在要測試的元素(例如我們的計數器)上沒有特定的標識符怎么辦?
You don’t want to pollute your production code with classes which would be useless there. It would be much better to have dedicated hooks for tests, such as a dedicated data attribute, but only during tests. This way a mess isn’t left in the final build.
您不想用在那里沒有用的類來污染您??的生產代碼。 最好有專用的鉤子來進行測試,例如專用的數據屬性, 但只在測試期間進行 。 這樣一來,就不會在最終版本中留下混亂。
One way to handle this is to create a custom Vue directive.
一種解決方法是創建自定義Vue指令 。
The Vue instance has a directive method which takes two arguments — a name, and an object of functions for each hook of the component lifecycle when injected in the DOM. You can also pass a single function if you don’t care about a specific hook.
Vue實例具有一個directive方法,該方法帶有兩個參數- 名稱 ,和注入到DOM 中的組件生命周期的每個掛鉤的 函數對象 。 如果您不關心特定的鉤子,也可以傳遞一個函數。
Let’s create a new directory called directives in src/, and add a test.js file. We’ll export the function we want to pass in our directive.
讓我們在src/創建一個名為directives的新目錄,并添加一個test.js文件。 我們將導出要傳遞給指令的函數。
// test.jsexport default (el, binding) => { // do stuff}A directive hook can take several arguments and, in our case, we only need the first two: el and binding. The el argument refers to the element the directive is bound to. The binding argument is an object which contains the data we passed in the directive. This way we can manipulate the element as we like.
指令掛鉤可以帶有多個參數 ,在我們的例子中,我們僅需要前兩個參數: el和binding 。 el參數是指指令綁定到的元素。 binding參數是一個對象,其中包含我們在指令中傳遞的數據。 這樣,我們可以根據需要操縱元素。
export default (el, binding) => { Object.keys(binding.value).forEach(value => { el.setAttribute(`data-test-${value}`, binding.value[value]) })}We’re passing an object to our directive, so we can generate data attributes starting with data-test-. In the handler function, we iterate over each property of binding, and we set a data attribute — based on the name and value — on our element.
我們將一個對象傳遞給指令,因此我們可以生成以data-test-開頭的數據屬性。 在處理程序函數中,我們迭代binding每個屬性,并在元素上設置一個基于名稱和值的data屬性。
Now we need to register our directive so we can use it. We can do it globally but, in our case, we’re only going to register it locally — right in our Rating.vue component.
現在我們需要注冊指令,以便可以使用它。 我們可以在全球范圍內進行操作,但就我們而言,我們只打算在本地進行注冊-就在我們的Rating.vue組件中。
<script>import Test from '@/directives/test.js'export default { // … directives: { Test }, // …}</script>Our directive is now accessible under the v-test name. Try setting the following directive on the counter:
現在可以使用v-test名稱訪問我們的指令。 嘗試在柜臺上設置以下指令:
<span v-test="{ id: 'counter' }" v-if="hasCounter"> {{ stars }} of {{ maxStars }}</span>Now inspect the HTML in your browser with the developer tools. Your counter should look like this:
現在,使用開發人員工具在瀏覽器中檢查HTML。 您的柜臺應如下所示:
<span data-test-id="counter">2 of 5</span>Great, it works! Now, we don’t need this either in dev mode nor when we build the project. The sole purpose of this data attribute is to be able to target elements during tests, so we only want to set it up when we run them. For this, we can use the NODE_ENV environment variable provided by Webpack, the module bundler powering our project.
太好了! 現在,無論是在開發模式下還是在構建項目時,我們都不需要它。 此數據屬性的唯一目的是能夠在測試期間定位元素,因此我們只想在運行它們時進行設置。 為此,我們可以使用NODE_ENV提供的NODE_ENV環境變量,該模塊是為我們的項目提供動力的模塊捆綁器。
When we run tests, NODE_ENV is set to 'test'. Therefore, we can use it to determine when to set the test attributes or not.
當我們運行測試時, NODE_ENV設置為'test' 。 因此,我們可以使用它來確定何時設置測試屬性。
export default (el, binding) => { if (process.env.NODE_ENV === 'test') { Object.keys(binding.value).forEach(value => { el.setAttribute(`data-test-${value}`, binding.value[value]) }) }}Refresh your app in the browser and inspect the counter again: the data attribute is gone.
在瀏覽器中刷新您的應用,然后再次檢查計數器: data屬性消失了 。
Now we can use the v-test directive for all elements we need to target. Let’s take our test from earlier:
現在,我們可以對需要定位的所有元素使用v-test指令。 讓我們從前面進行測試:
it('adds `active` class on an inactive star when the user clicks it', () => { const fourthStar = wrapper.findAll('[data-test-id="star"]').at(3) fourthStar.trigger('click') expect(fourthStar.classes()).toContain('active')})We’ve replaced the .star selector with [data-test-id="star"], which allows us to change classes for presentation purposes without breaking tests. We get one of the benefits of the single-responsibility principle and loose coupling — when your abstractions only have a single reason to change, you avoid all kinds of pesky side-effects.
我們將.star選擇器替換為[data-test-id="star"] ,這使我們可以為演示目的而更改類而不會破壞測試。 我們得到的好處之一單一職責原則和松散的耦合 -當你的抽象只有一個理由去改變,你避免各種討厭的副作用。
我們還應該在測試的類中使用這些鉤子嗎? (Should we also use these hooks for the classes we test?)
After setting this directive to target elements to test, you may be wondering if you should also use them to replace the classes we actively look for. Let’s look at the assertion from our first test:
在將此指令設置為要測試的目標元素之后,您可能想知道是否還應該使用它們來代替我們積極尋找的類。 讓我們看一下第一個測試的斷言:
expect(wrapper.findAll('.active').length).toEqual(3)Should we use v-test on the elements with the active class, and replace the selector in the assertion? Great question.
我們是否應該在active類的元素上使用v-test ,并在斷言中替換選擇器? 好問題 。
Unit tests are all about testing one thing at a time. The first argument of the it function is a string, with which we describe what we’re doing from a consumer perspective.
單元測試都是一次測試一件事。 it函數的第一個參數是一個字符串,我們從消費者的角度描述我們在做什么。
The test that wraps our assertion says renders a list of stars with class active equal to prop.grade. This is what the consumer expects. When they pass a number to the grade property, they expect to retrieve an equal number of active or selected stars. Yet, in our component’s logic, the active class is precisely what we use to define this trait. We assign it depending on a specific condition, so we can visually differentiate active stars from the others. Here, the presence of this specific class is exactly what we want to test.
包含斷言的測試將renders a list of stars with class active equal to prop.grade. 這就是消費者的期望。 當他們將數字傳遞給grade屬性時,他們希望檢索到相等數量的活動或選定的恒星。 但是,按照組件的邏輯, active類正是我們用來定義此特征的類。 我們根據特定條件對其進行分配,因此我們可以在視覺上區分活躍恒星和其他恒星。 在這里,這個特定類的存在正是我們要測試的。
So, when deciding whether you should use a selector you already have or set a v-test directive, ask yourself the question: what am I testing, and does using this selector makes sense for a business logic perspective?
因此,在決定是否應該使用已有的選擇器或設置v-test指令時,請問自己一個問題: 我正在測試什么,并且從業務邏輯角度來看,使用此選擇器是否有意義?
它與功能或端到端測試有何不同? (How is it different from functional or end-to-end tests?)
At first, it might look odd to unit test components. Why would you unit test UI and user interactions? Isn’t that what functional tests are here for?
首先,對于單元測試組件而言,它看起來很奇怪。 為什么要對UI和用戶交互進行單元測試? 這不是功能測試嗎?
There is a fundamental yet subtle difference to make between testing a component’s public API — aka from a consumer perspective — and testing a component from a user perspective. First, let’s underline something important: we’re testing well-defined JavaScript functions, not pieces of UI.
從消費者的角度測試組件的公共API(從用戶角度來看)與從用戶的角度測試組件之間存在根本但微妙的區別。 首先,讓我們強調一些重要的事情: 我們正在測試定義明確JavaScript函數,而不是UI部分 。
When you look at a single-file component it’s easy to forget the component compiles into a JavaScript function. We’re not testing the underlying Vue mechanism which, from this function, causes UI-oriented side-effects like injecting HTML in the DOM. That’s what Vue’s own tests already take care of. In our case, our component is no different from any other function: it accepts input and returns an output. These causes and consequences are what we’re testing, and nothing else.
當您查看單個文件組件時,很容易忘記該組件會編譯為JavaScript函數。 我們沒有測試底層的Vue機制,該機制會從此函數引起面向UI的副作用,例如在DOM中注入HTML。 這就是Vue自己的測試已經解決的問題。 在我們的例子中,我們的組件與其他函數沒有什么不同: 它接受輸入并返回輸出 。 這些因果關系是我們正在測試的,僅此而已。
What’s confusing is that our tests look a bit different from regular unit tests. Usually, we write things like:
令人困惑的是我們的測試看起來與常規單元測試有些不同。 通常,我們這樣寫:
expect(add(3)(4)).toEqual(7)There’s no debate here. Input and output of data, that’s all we care about. With components, we’re expecting things to render visually. We’re traversing a virtual DOM and testing for the presence of nodes. That’s also what you do with functional or end-to-end tests, with tools like Selenium or Cypress.io. So how does that differ?
這里沒有辯論。 數據的輸入和輸出,這就是我們關心的全部。 對于組件,我們期望事物能夠以可視方式呈現。 我們正在遍歷虛擬DOM并測試節點的存在。 您也可以使用Selenium或Cypress.io之類的工具來進行功能或端到端測試。 那有什么不同呢?
You need not to confuse what we’re doing to fetch the data we want to test and the actual purpose of the test. With unit tests, we’re testing isolated behaviors. With functional or end-to-end tests, we’re testing scenarios.
你不必混淆我們正在做的事情來獲取我們想要的測試和試驗的實際目的的數據。 通過單元測試,我們正在測試孤立的行為。 通過功能測試或端到端測試,我們正在測試場景 。
A unit test makes sure a unit of the program behaves as expected. It’s addressed to the consumer of the component — the programmer who uses the component in their software. A functional test ensures a feature or a workflow behaves as expected, from a user perspective — the final user, who consumes the full software.
單元測試可確保程序的單元行為符合預期。 它面向的是組件的使用者 -在其軟件中使用該組件的程序員。 從用戶的角度(即使用完整軟件的最終用戶)的角度出發,功能測試可確保功能或工作流程的行為符合預期。
更進一步 (Going further)
I won’t go into the detail of each test, because they all share a similar structure. You can find the full spec file on GitHub, and I strongly recommend you try to implement them yourself first. Software testing is an art as much as it is a science, and requires twice as much practice as it requires theory.
我不會詳細介紹每個測試,因為它們都具有相似的結構。 您可以在GitHub上找到完整的規范文件 ,我強烈建議您嘗試首先自己實現它們。 軟件測試既是一門科學,又是一門科學,它需要的實踐是理論的兩倍。
Don’t worry if you didn’t get everything, or if you struggle with writing your first tests: testing is notoriously hard. Also, if you have a question, don’t hesitate to hit me up on Twitter!
如果您一無所獲,也不必擔心編寫第一個測試的麻煩: 眾所周知,測試很難 。 另外,如果您有任何疑問,請隨時在Twitter上與我聯系!
Originally published at frontstuff.io.
最初發布在frontstuff.io上 。
翻譯自: https://www.freecodecamp.org/news/how-to-unit-test-your-first-vue-js-component-14db6e1e360d/
總結
以上是生活随笔為你收集整理的如何对第一个Vue.js组件进行单元测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怀孕梦到大出血怎么回事
- 下一篇: vue生成静态js文件_如何立即使用Vu