Upgrade to Pro — share decks privately, control downloads, hide ads and more …

VitestのIn-Source Testingが便利

taro
April 23, 2025

VitestのIn-Source Testingが便利

Mita.ts #5
https://mitats.connpass.com/event/340678/

での登壇資料です。

taro

April 23, 2025
Tweet

More Decks by taro

Other Decks in Programming

Transcript

  1. VitestのIn-Source Testingとは その名の通り、実装と同じファイルにテストが書けるやつ export function add(...args: number[]) { return args.reduce((a,

    b) => a + b, 0); } // ソースコード内にテストが書ける if (import.meta.vitest) { it("add", () => { expect(add()).toBe(0); expect(add(1)).toBe(1); expect(add(1, 2, 3)).toBe(6); }); } https://vitest.dev/guide/in-source
  2. テストのためのexportが不要になる テストのために関数をexportしてコメントを書く… // export for test export const swap =

    <T>(data: T[], i: number, j: number) => { // data のi 番目とj 番目を入れ替える処理 // ... }; import { swap } from "./swap"; describe("swap", () => { it("basic", () => { expect(swap(["a", "b", "c"], 0, 1)).toEqual(["b", "a", "c"]); }); it("out of range", () => { // ...
  3. テストのためのexportが不要になる テストのためのexportが不要! const swap = <T>(data: T[], i: number, j:

    number) => { // data のi 番目とj 番目を入れ替える処理 // ... }; if (import.meta.vitest) { it("swap: basic", () => { expect(swap(["a", "b", "c"], 0, 1)).toEqual(["b", "a", "c"]); }); it("swap: out of range", () => { // ... } const useSwap = (initialData: Props) => {
  4. テストのためのexportが不要になる テストのために定数をexport… // export for test export const userStatus =

    { // ... } as const; export const checkUserStatus = (user: User): UserStatus => { if (user.lastLoggedIn === null) { return userStatus.NEW; } if (user.lastLoggedIn > 30) { return userStatus.ACTIVE; } return userStatus.INACTIVE; };
  5. テストのためのexportが不要になる テストのための定数や型などのexportが不要になる! const userStatus = { // ... } as

    const; export const checkUserStatus = (user: User): UserStatus => { // ... }; if (import.meta.vitest) { describe("checkUserStatus", () => { test.each([ // テスト内で定数が使える! { lastLoggedIn: null, expected: userStatus.NEW }, // ...
  6. プライベートな関数にテストが書ける const swap = <T>(data: T[], i: number, j: number)

    => { // data のi 番目とj 番目を入れ替える処理 }; const useSwap = (initialData: Props) => { // swap 関数を使って、データを入れ替える }; export const Swapper: FC<Props> = (initialData) => { const { data, swapData } = useSwap(initialData); // ... }; exportしている関数やコンポーネントに、まとめて全てのケースのテストを書く… describe("Swapper", () => { // ...
  7. プライベートな関数にテストが書ける プライベートな関数に細かくテストを書ける! const swap = <T>(data: T[], i: number, j:

    number) => { // data のi 番目とj 番目を入れ替える処理 // ... }; if (import.meta.vitest) { it("swap: basic", () => { expect(swap(["a", "b", "c"], 0, 1)).toEqual(["b", "a", "c"]); }); it("swap: out of range", () => { // ... } const useSwap = (initialData: Props) => {
  8. プライベートな関数にテストが書ける 条件分岐で色んな関数を呼ぶ関数に全てのケースのテストを書く… export const dataConverter = (data: Data) => {

    switch (data.type) { case "type1": return convertType1(data); case "type2": return convertType2(data); // ... } }; describe("dataConverter", () => { // 全てのtype のテストをdataConverter に対して書く… // ... });
  9. プライベートな関数にテストが書ける プライベートな関数に細かくテストを書ける! const convertType1 = (data: Data) => { //

    ... if (import.meta.vitest) { it("convertType1", () => { // ... }); } // ... // この関数のテストは薄くできる! export const dataConverter = (data: Data) => { switch (data.type) { case "type1": return convertType1(data); // ...