はじめに
PlaywrightでE2Eテストを作成する際のテストデータを用意しやすいように、PlaywrightにSequelizeを導入してみました。
今回はわかりやすいように、Playwrightプロジェクトを新規で作り、Sequelizeでテストデータを用意し、テストを実行するところまで行います。
この記事で扱わないこと
・Playwright、Sequelizeが何かの説明
・DBの用意することに関して
目次
プロジェクトの作成と初期設定
まずはPlaywrightのプロジェクトを作成します
Playwrightの初期設定は全てenterで作成しています
$ mkdir playwright-qiita
$ cd playwright-qiita
$ npm init playwright@latest
今回必要なライブラリ類をインストールします
$ npm install sequelize oracledb
tsconfig.jsonファイルを作成します
{
"compilerOptions": {
"esModuleInterop": true,
"paths": {
"@/*": ["./*"]
}
}
}
接続設定
接続のhelper関数を作成します
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が有料会員を示す
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に値を代入します。
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を利用して、テストデータを用意してみました。
テストデータの用意は高速に実行するには大切なので、誰でもわかりやすく簡単にテストデータを用意できる機構を探していきたいと思います。