1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PlaywrightでORMを導入し、テストデータの用意を便利にした

Last updated at Posted at 2024-09-23

はじめに

PlaywrightでE2Eテストを作成する際のテストデータを用意しやすいように、PlaywrightにSequelizeを導入してみました。
今回はわかりやすいように、Playwrightプロジェクトを新規で作り、Sequelizeでテストデータを用意し、テストを実行するところまで行います。

この記事で扱わないこと
・Playwright、Sequelizeが何かの説明
・DBの用意することに関して

目次

  1. プロジェクトの作成と初期設定
  2. 接続設定
  3. スキーマを定義
  4. テストで利用する
  5. まとめ

プロジェクトの作成と初期設定

まずはPlaywrightのプロジェクトを作成します
Playwrightの初期設定は全てenterで作成しています

$ mkdir playwright-qiita
$ cd playwright-qiita
$ npm init playwright@latest

今回必要なライブラリ類をインストールします

$ npm install sequelize oracledb

tsconfig.jsonファイルを作成します

tsconfig.json
{
  "compilerOptions": {
    "esModuleInterop": true,
    "paths": {
      "@/*": ["./*"]
    }
  }
}

接続設定

接続のhelper関数を作成します

sequelize-connection.helpers.ts
import { Sequelize } from 'sequelize'

export const sequelize = new Sequelize({
  dialect: 'oracle',
  username: 'username',
  password: 'password',
  define: {
    freezeTableName: true,
  },
  dialectOptions: {
    connectString: '(DESCRIPTION=(CONNECT_TIMEOUT=30)(HOST=host.com)'(PORT=1500)),
  }
})

解説
1. DB接続先の設定

dialect: 'oracle',

アクセス先のDBを指定します。今回はoracleを指定していますが、mysql・postgres・sqlite・ mariadb・mssqlが利用できます。
接続するDBによって追加で必要なライブラリが存在するので、インストールをしてください(詳しくは公式ドキュメントを確認してください)。
今回はoracleなので、npm install oracledbを実行しています。

2. テーブル名を自動で変更しないように設定

define: {
    freezeTableName: true,
}

この設定をtrueにしておかなければ、接続時にテーブル名の語尾にsをつけてしまいます。
今回接続するテーブルがACCOUNTのためsが付与されてしまうと、接続に失敗してしまうので設定しています。

3. hostやDBを指定

dialectOptions: {
    connectString: '(DESCRIPTION=(CONNECT_TIMEOUT=30)(RETRY_COUNT=10)(HOST=host.com)(PORT=1500))',
}

今回はtimeoutやportを文字列で設定しましたが、以下のように個別での設定も可能です。

import { Sequelize } from 'sequelize'

export const sequelize = new Sequelize({
  dialect: 'oracle',
  username: 'username',
  password: 'password',
  host: 'host.com'
  port: 1500
  define: {
    freezeTableName: true,
  },
  dialectOptions: {
    timeout: 30
  }
})

スキーマを定義

ACCOUNTスキーマの定義を作成します
DBが以下の状況であることを想定しています

テーブル名
ACCOUNT

カラム
ID      :NUMBER型・primaryKey
MAIL_ADDRESS:VARCHAR型・ユニーク制約
COURSE      :NUMBER型・0が無料会員、1が有料会員を示す
Account.ts
import { DataTypes, ModelDefined, Optional } from 'sequelize'
import { sequelize } from '@/sequelize/sequelize-connection.helpers'

interface Account {
  ID: number
  MAIL_ADDRESS: string
  COURSE: number
}

interface AccountCreationAttributes extends Optional<Account, 'ID'> {}

interface AccountModel
  extends ModelDefined<Account, AccountCreationAttributes> {
  COURSE: typeof COURSE
}

export const Account: AccountModel = sequelize.define(
  'ACCOUNT',
  {
    ID: {
      type: DataTypes.INTEGER,
    },
    MAIL_ADDRESS: {
      type: DataTypes.STRING,
    },
    COURSE_ID: {
      type: DataTypes.INTEGER,
    }
  },
  { timestamps: false },
) as AccountModel

const COURSE = {
  // 無料会員
  FREE: 0,
  // 有料会員
  PAID: 1,
} as const

Account.COURSE = COURSE

解説
1. スキーマを定義する

interface Account {
  ID: number
  MAIL_ADDRESS: string
  COURSE: number
}

export const Account: AccountModel = sequelize.define(
  'ACCOUNT',
  {
    ID: {
      type: DataTypes.INTEGER,
    },
    MAIL_ADDRESS: {
      type: DataTypes.STRING,
    },
    COURSE: {
      type: DataTypes.INTEGER,
    }
  },
  { timestamps: false },
) as AccountModel

defineの第1引数にテーブル名、第2引数に各カラムの設定、第3引数にオプションを設定します。
interfaceにてIDやMAIL_ADDRESSの型を設定することで、実際に値を入れる時に型チェックをしてくれます
また、デフォルトでDBにタイムスタンプを追加するので、設定していない場合は{ timestamps: false }を設定しておきましょう。

2. オブジェクトリテラルでわかりにくい数値の値を定義しておく

interface AccountModel
  extends ModelDefined<Account, AccountCreationAttributes> {
  COURSE: typeof COURSE
}

const COURSE = {
  // 無料会員
  FREE: 0,
  // 有料会員
  PAID: 1,
} as const

Account.COURSE = COURSE

このように設定しておくと、Account.COURSE.FREEで0が代入されるので、テストデータを用意するときにCOURSEの値が何のステータスを指すのかをわかりやすくできます。

テストで利用する

sample.spec.tsを作成
実際に先ほど作成したスキーマ定義を使い、テストファイルでテストデータを用意します
スキーマから使える関数が定義されているので、それにIDやMAIL_ADDRESSに値を代入します。

sample.spec.ts
import { test } from '@playwright/test'
import { Account } from '@/sequelize/entity/Account'

const testPrefix = 'sample'

test('テストデータを用意する', async ({ }) => {
    // 初期データの挿入
    {
        await Account.create({
            ID: 1,
            MAIL_ADDRESS: `${testPrefix}@example.com`,
            COURSE: Account.COURSE.FREE,
        })
    }
})

まとめ

E2Eのテストデータについては、永続化やそれ専用のAPIを作成するなど方法はありますが、今回はSequelizeを利用して、テストデータを用意してみました。
テストデータの用意は高速に実行するには大切なので、誰でもわかりやすく簡単にテストデータを用意できる機構を探していきたいと思います。

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?