成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

測試框架千千萬,我偏愛 vitest

開發 前端
Vitest 由核心Vite團隊成員Anthony fu(一個托尼)開發,它建立在Vite之上,但非vite項目其實也可以使用vitest。而vite想必大家都非常熟悉了,它可以快速的啟動開發服務器,利用瀏覽器的ES模塊系統,從而加快本地開發速度,這讓vite變得十分受歡迎。

前端測試框架千千萬,jest、vitest、Jasmine、mocha等等,但我個人更偏愛 vitest,簡潔,高效,現代化,這篇文章就帶大家了解一下關于vitest的一些知識和特性,幫助大家更好的使用vitest。

why vitest

Vitest 由核心Vite團隊成員Anthony fu(一個托尼)開發,它建立在Vite之上,但非vite項目其實也可以使用vitest。而vite想必大家都非常熟悉了,它可以快速的啟動開發服務器,利用瀏覽器的ES模塊系統,從而加快本地開發速度,這讓vite變得十分受歡迎。

雖然用vite開發的項目也可以和jest一起使用,但是vite和jest中其實有很多配置重復的部分,迫使用戶要維護和運行兩套流程。

所以,vitest一開始要解決的問題就是便于在vite項目中方便集成測試能力;在開發中,將Vitest與Vite結合使用的主要優勢是他們都有很好的性能,方便一起集成,以及他們都共享配置同一份配置。

vite的爆火一定程度上也讓vitest增加了曝光度,它也在社區中十分受歡迎,成為了越來越多測試框架的首選:

Vitest 對比 jest

說到vitest,不得不提另外一個測試框架也就是jest。

早在2011年,還沒有JavaScript測試框架能滿足Facebook(meta)團隊的測試需求,所以他們創建了Jest。Jest在2014年開源,就在React開源后不久,jest也隨著React迅速流行起來。2016年,jest成為create react APP(CRA)命令創建react應用的首選測試框架,Next.js V12版本也把jest作為默認測試框架,jest主流地位已然確立。

2022年,jest所有權已經轉移給OpenJS基金會,由meta外部人員維護,之后jest的更新和維護就變得相對緩慢。jest的最新一次更新版本在1年前,jest的v30版本早在2023年就已經發布alpha版本,但是現在已經2025年了,v30版本仍然沒有發布;但是vitest去年就從v1版本更新到了v3版本......

vitest對比jest一個顯著的優勢是vitest原生支持typescript、ESM,而jest v29版本現在對于ESM的支持還是實驗性的,此外如果要支持typescript還需要配置babel,通過babel來轉譯支持typescript。而vitest對于現代特性都是開箱即用的。

關于性能方面,在redit論壇 (https://www.reddit.com/r/reactjs/comments/10zyse3/is_jest_still_faster_than_vitest/)上有很多關于jest和vitest的性能測試的討論,有的反饋說jest比較快,有的說vitest比較快。但不管怎么樣,vitest的HMR特性是要比jest是要快的,也就是開發過程中只運行修改文件的測試。原因是vitest是基于修改模塊的依賴樹去做的分析重新運行,而jest是基于git未提交代碼做的分析,這可能不太準確,因為并非所有檢測到的更改文件都與現在運行的測試相關。

下面是關于jest和vitest特性的一個全面對比:

vitest有更多的現代特性,以及vitest處于一個快速迭代社區逐漸繁榮的階段,如果是一個使用現代特性的新項目,那么vitest肯定是首選!

vitest的一些特性

關于怎么開始和配置,比較簡單,本文就不展開了,下面詳細聊聊vitest的一些特性,了解完這些特性后,想必你對vitest有更全面的認識。

兼容jest API 但是更強

因為jest的API已經設計的比較優秀(從他的下載占有率可以看出),vitest幾乎完全兼容了jest的API設置。比如Expect、Mock、Setup and TearDown等API。所以從jest項目遷移到vitest只需要做很少的調整,具體可以參考官方文檔(https://vitest.dev/guide/migration.html#jest),其中一個都會遇到的調整是globals的配置,他可以不用引入vitest,也能使用全局API。

此外,vitest的v3 API增加了更多的能力,比如toHaveBeenCalledExactlyOnceWith,他可以檢測某個函數只被調用了一次且調用參數為預期值。

test('vitest mocking example', () => {
const mock = vi.fn();
  mock('hello');
// New matcher for more precise assertions
  expect(mock).toHaveBeenCalledExactlyOnceWith('hello');

// Spy reuse example
const obj = {
    method: () => {}
  };
const spy = vi.spyOn(obj, 'method');
// Spy is automatically reused if spyOn is called again
const sameSpy = vi.spyOn(obj, 'method');
  expect(spy === sameSpy).toBe(true);
});

默認watch模式

在jest中,我們要使用watch模式的時候,需要增加--watch參數(即jest --watch);但是vitest默認使用watch模式(即vitest),不需要增加--watch參數,也能自動進入watch模式。

但是如果是CI環境,我們運行watch模式,是不是不符合預期?

vitest會根據是否有環境變量process.env.CI判斷是否處于CI環境,如果有環境變量則不會啟動watch模式。

當然也可以通過指定--watch參數以及--run參數,來指定watch模式還是單次運行。

源碼內聯測試

什么是源碼內聯測試(In-Source Testing)呢?

這是一個rust模塊測試的方式,他可以讓我們把測試代碼寫在源碼中。

這可以讓測試代碼和源碼代碼使用相同的閉包環境,關注的邏輯和代碼在同一地方,這可以讓我們更快速的發現問題、修復問題,每次代碼修改后都能立即運行測試代碼并進行修復,便于維護;但是由于測試代碼和源代碼在一個文件里,非常容易耦合,所以對代碼質量有一定要求。

下面是一個內聯代碼測試的demo:

export function add(...args: number[]) {
return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}

官方建議對更復雜的測試使用單獨的測試文件,源代碼內測試適用于對小函數進行單元測試和原型設計,因此對于為 JavaScript 庫編寫測試特別有用。

此外,如果我們在生產環境使用該模式,應該為bundler增加變量定義,以便于bundler分析dead code并刪除:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    includeSource: ['src/**/*.{js,ts}'],
  },
  define: { 
    'import.meta.vitest': 'undefined', 
  }, 
})

真正的瀏覽器測試

在vitest v2版本引入了瀏覽器模式,該模式還處于實驗階段。該模式將在瀏覽器環境直接運行代碼,所以他可以訪問真正的dom API,所以理論上在實際環境中運行的測試將會更加可靠。缺點就是慢!

在node環境的測試中,我們一般通過js-dom或者happy-dom來模擬瀏覽器環境,happy-dom支持更少的瀏覽器API,但是更快,js-dom則相反。我們可以根據需要選擇不同的dom模擬環境,vitest同時支持js-dom和happy-dom。

vitest支持在不同的容器運行測試,比如playwright或者webdriverio ,這兩者比較顯著的差異是他們底層協議不同,playwright使用的Chrome DevTools 協議,而webdriverio使用的是WebDriver 協議:

vitest提供了開箱即用的包來渲染常用的前端框架的組件,下面是一個react的demo:

import { expect, test } from'vitest'
import { render } from'vitest-browser-react'
import HelloWorld from'../src/HelloWorld'

test('renders name', async () => {
const { getByText, getByRole } = render(<HelloWorld name="Vitest" />)

await expect.element(getByText('Hello Vitest x1!')).toBeInTheDocument()
await getByRole('button', { name: 'Increment '}).click()

await expect.element(getByText('Hello Vitest x2!')).toBeInTheDocument()
})

可以看到API和用法幾乎和@testing-library/react幾乎相同,相同的代碼可以讓運行環境切換到瀏覽器環境!

其他的特性

  • Browber UI。直接啟動一個前端頁面,在這個頁面中可以更好的調試、運行、修復測試;
  • 類型測試。提供類型斷言的API可以對TS的類型進行測試;
  • 提供benchmark
  • workspace配置。v3版本的vitest增加了workspace配置,它特別適用于monorepo,可以在一個配置文件里配置多個項目的配置。
  • ...

這里就不一一列舉了,感興趣的小伙伴建議直接查看官網。

一些技巧

下面分享個人在使用vitest的過程中的一些有用的技巧。

使用vscode的debug terminal

這是一個node調試比較通用的技巧,對于vitest同樣適用。使用vscode 的debug terminal可以非常方便的查看變量的參數,這非常適合我們在mock出現問題的時候debug。

使用skip或者only來快速調試

在調試單元測試的時候,我們經常會遇到單測報錯,但是可能因為mock或者一些上下文影響,十分難以調試,這個時候可能會用到skiponly API,這兩個API可以只運行某個case或者跳過某個case,可以減少影響面,幫助我們快速調試(而不是注釋代碼)

it.only('should be open', () => {
   //...
  });

 it.skip('should be closed', () => {
   //...
  });

優雅的retry

vitest中有很多重試的方法,比如:

import { expect, test } from"vitest";
import { sum } from"./sum.js";

it(
"adds 1 + 2 to equal 3",
  {
    retry: 3,
    timeout: 3000,
  },
  () => {
    expect(sum(1, 2)).matchSnapshot();
  }
);

it支持傳入第二個配置參數,該參數可以配置retry和timeout等,可以針對一整個case retry的場景。

此外,vitest還支持waifor API,該API可以不斷嘗試和獲取API:

// @vitest-environment jsdom

import { expect, test, vi } from'vitest'
import { getDOMElementAsync, populateDOMAsync } from'./dom.js'

test('Element exists in a DOM', async () => {
// start populating DOM
  populateDOMAsync()

const element = await vi.waitFor(async () => {
    // try to get the element until it exists
    const element = await getDOMElementAsync() as HTMLElement | null
    expect(element).toBeTruthy()
    expect(element.dataset.initialized).toBeTruthy()
    return element
  }, {
    timeout: 500, // default is 1000
    interval: 20, // default is 50
  })
  expect(element).toBeInstanceOf(HTMLElement)
})

上面這個case會在dom真正渲染出來,才會執行下面的語句,之前會一直輪詢執行語句,判斷是否正確執行。

另外,@testing-library/react里面也有很多類似的API底層其實就是使用waitfor,例如findAllByTextAPI,該API會等待元素渲染完成之后,再繼續進行下面的代碼。

Bad case:

使用盡量詳細的斷言

我遇到一些單測的case,因為沒有運行每個case前mockReset,導致之前spy函數調用記錄仍然存在,于是好幾個case在不同的測試場景中,相同的斷言均是toHaveBeenCalledWith,該斷言因為只會判斷歷史調用中是否存在某參數調用就行了,所以導致這幾個case均成功了,但是實際上是有問題的。

我們應該使用更加詳細的斷言,比如toHaveBeenNthCalledWith或者上文提到的toHaveBeenCalledExactlyOnceWith。

總結

vitest能夠快速火起來,我認為其原因有三點。首先提供了和jest兼容的API設計,這一點對于開源工具來說十分重要,讓用戶可以更少的遷移成本;第二個是擁抱社區,提供了很多很現代的功能,比如瀏覽器模式、源碼內聯測試;第三個基于vite的設計理念,使用現代的API和工具,讓開發者開箱即用ESM和typescript,無需任何其他配置,提供更好的開發者體驗。

我們應該關注vitest最新特性,及時升級vitest,使用最新特性和技術來保證我們代碼的穩定性。

責任編輯:姜華 來源: Tecvan
相關推薦

2024-10-10 17:23:31

2013-04-15 10:12:38

2019-10-24 07:50:52

勒索病毒勒索軟件網絡安全

2021-05-14 16:34:53

軟件電腦硬件

2019-11-17 16:09:45

勒索病毒網絡攻擊網絡安全

2019-08-30 16:22:30

編程語言PythonJava

2021-05-17 15:23:07

電腦廣告軟件

2023-12-06 09:02:12

Vitest前端

2017-11-02 10:45:21

2023-09-11 15:34:53

2014-06-17 14:26:25

Windows 7補丁

2011-09-29 10:24:08

項目方法項目變更項目風險

2018-01-10 14:57:56

2022-08-09 13:08:27

VitestJest前端

2011-08-25 10:15:54

視頻演講喬布斯

2020-10-29 18:38:39

PythonGitHub代碼

2023-01-03 10:30:00

Java工具

2023-11-27 17:40:45

VitestPlaywright前端

2023-08-31 08:19:51

ViteSVGBase64
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩中文字幕 | 欧美福利视频一区 | 黄色在线观看 | 国产99久久 | 国产亚洲一区二区三区 | 国产人成精品一区二区三 | 毛片在线免费 | 欧美亚洲综合久久 | 精品久久九 | 日日夜夜天天干 | 成人欧美一区二区三区黑人孕妇 | 欧美视频日韩 | 日韩在线精品视频 | 亚洲精品国产成人 | 中文字幕免费在线 | 日韩欧美精品在线 | 黄色网址免费看 | 观看av| 中文字幕av网站 | 91国内视频在线 | 亚洲精品国产a久久久久久 中文字幕一区二区三区四区五区 | 做a视频 | 99热欧美| 欧美日韩大片 | 国产精品高潮呻吟久久 | 99精品久久久久久中文字幕 | 国产xxxx搡xxxxx搡麻豆 | 99精品免费视频 | 精精国产xxxx视频在线 | 91亚洲欧美| 九九伊人sl水蜜桃色推荐 | 免费一区二区 | 欧美成人免费在线 | 亚洲欧洲视频 | 三级av网址| 午夜视频精品 | 久久se精品一区精品二区 | 天天艹天天干天天 | 国产一区二区精品在线观看 | 国产精品亚洲一区二区三区在线 | 拍真实国产伦偷精品 |