AtCoderNoviSteps icon indicating copy to clipboard operation
AtCoderNoviSteps copied to clipboard

CRUDにテストを追加しましょう

Open KATO-Hiro opened this issue 1 year ago • 2 comments

WHY

  • CRUDの動作の担保 + 不具合をCIで検出したい
  • 最近のバグのいくつかはCRUDをテストしていればすぐに気がつけた可能性が高い

CRUDのテストの障壁

  • [ ] テスト用のDBのセットアップ
  • [ ] seedスクリプトの動作を担保
  • [ ] DBが関連するテストの書き方
  • [ ] CIの設定変更

TODO

  • [ ] Vitestの設定を必要に応じて更新
  • [ ] テスト用のDBを用意
  • [ ] テスト用のPrismaクライアントを用意
  • [ ] 想定されるテストケースを列挙
  • [ ] 上記の内容をテスト
  • [ ] CIの設定を必要に応じて追加

KATO-Hiro avatar Sep 04 '24 09:09 KATO-Hiro

はい、SvelteKitアプリでPrismaをORMとして使用し、Vitestを使用してCRUD操作のテストを実現することができます。以下に、Vitestを使用してPrismaのCRUD操作をテストする方法を示します。

1. Vitestのセットアップ

まず、Vitestをプロジェクトにインストールします。

npm install -D vitest

次に、vitest.config.tsファイルを作成し、設定を追加します。

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
  },
});

2. Prismaのセットアップ

Prismaのセットアップが完了していることを確認します。prisma/schema.prismaファイルが存在し、データベース接続が設定されていることを確認してください。

3. テストデータベースの設定

テスト用のデータベースを設定します。通常のデータベースとは別に、テスト用のデータベースを使用することをお勧めします。prisma/.env.testファイルを作成し、テスト用のデータベース接続情報を追加します。

DATABASE_URL="postgresql://user:password@localhost:5432/testdb"

4. テスト用のPrismaクライアントを作成

テスト用のPrismaクライアントを作成します。src/lib/prisma.tsファイルを作成し、以下のコードを追加します。

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient({
  datasources: {
    db: {
      url: process.env.DATABASE_URL,
    },
  },
});

export default prisma;

5. CRUD操作のテストを作成

CRUD操作のテストを作成します。例えば、tests/taskResults.test.tsファイルを作成し、以下のようにテストを記述します。

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import prisma from '../src/lib/prisma';
import { updateTaskResult, getTaskResult } from '../src/lib/services/task_results';

describe('Task Results CRUD', () => {
  beforeAll(async () => {
    // テスト用のデータベースを初期化
    await prisma.$executeRaw`TRUNCATE TABLE TaskResults CASCADE`;
  });

  afterAll(async () => {
    // Prismaクライアントを閉じる
    await prisma.$disconnect();
  });

  it('should create and update a task result', async () => {
    const taskId = 'test-task';
    const userId = 'test-user';
    const submissionStatus = 'completed';

    // タスク結果を作成
    await updateTaskResult(taskId, submissionStatus, userId);

    // タスク結果を取得
    const taskResult = await getTaskResult(taskId, userId);

    // 検証
    expect(taskResult).not.toBeNull();
    expect(taskResult.status_name).toBe(submissionStatus);
  });
});

6. テストの実行

テストを実行します。

npx vitest

まとめ

これで、Vitestを使用してPrismaのCRUD操作をテストすることができます。Vitestの設定、Prismaのセットアップ、テストデータベースの設定、テスト用のPrismaクライアントの作成、CRUD操作のテストの作成と実行の手順を示しました。これにより、SvelteKitアプリでPrismaを使用したCRUD操作のテストを効率的に行うことができます。

KATO-Hiro avatar Sep 04 '24 09:09 KATO-Hiro

はい、Prismaのクライアントメソッドを使用してデータベースを初期化する方法もあります。これにより、生SQLを使用せずにデータベースの初期化を行うことができます。以下に、Prismaのクライアントメソッドを使用してデータベースを初期化する方法を示します。

1. テストデータベースの初期化

Prismaのクライアントメソッドを使用して、テストデータベースを初期化する方法を示します。beforeAllフック内で、PrismaのdeleteManyメソッドを使用してテーブルのデータを削除します。

2. テストコードの修正

以下に、修正後のテストコードを示します。

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import prisma from '../src/lib/prisma';
import { updateTaskResult, getTaskResult } from '../src/lib/services/task_results';

describe('Task Results CRUD', () => {
  beforeAll(async () => {
    // テスト用のデータベースを初期化
    await prisma.taskAnswer.deleteMany({});
    await prisma.taskResult.deleteMany({});
  });

  afterAll(async () => {
    // Prismaクライアントを閉じる
    await prisma.$disconnect();
  });

  it('should create and update a task result', async () => {
    const taskId = 'test-task';
    const userId = 'test-user';
    const submissionStatus = 'completed';

    // タスク結果を作成
    await updateTaskResult(taskId, submissionStatus, userId);

    // タスク結果を取得
    const taskResult = await getTaskResult(taskId, userId);

    // 検証
    expect(taskResult).not.toBeNull();
    expect(taskResult.status_name).toBe(submissionStatus);
  });
});

説明

  • beforeAllフック内で、prisma.taskAnswer.deleteMany({})prisma.taskResult.deleteMany({})を使用して、taskAnswertaskResultテーブルのデータを削除します。これにより、テストのたびにデータベースが初期化されます。
  • afterAllフック内で、Prismaクライアントを閉じます。

まとめ

Prismaのクライアントメソッドを使用してデータベースを初期化することで、生SQLを使用せずにデータベースの初期化を行うことができます。これにより、コードの可読性とメンテナンス性が向上します。

KATO-Hiro avatar Sep 04 '24 09:09 KATO-Hiro