17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NewsPicksAdvent Calendar 2022

Day 6

playwrightの`beforeAll()`, `beforeEach()`について解説

Last updated at Posted at 2022-12-06

こちらはNewsPicksアドベントカレンダー2022の6日目の記事です。

はじめに

業務でPlaywrightを用いたE2E自動テストを実装するタスクをしていて、ハマった場所があったため備忘録も兼ねて記事にしてみました。

Playwrightとは?

PlaywrightとはE2Eテストを自動化するNode.jsのフレームワークです。

ハマったこと

元々、
1つのテストファイル内で実行をする際にtest.beforeAll()を一回動作させ、test.beforeEach()でそれぞれのテストの事前処理を実行して欲しかったのですが、
並列実行で試してみたところ、
test.beforeAll()がそれぞれ毎回呼ばれてしまったことがありました。

test.beforeAll(), test.beforeEach()について認識が浅かったために予想通りに動いてくれませんでした。

ドキュメントの解説はこちらです。

解説

test.beforeAll()はテスト実行前にworker1つごとに一回ずつ実行されます。
そのため、例えば、

1つのファイル内で3つのテストを並列実行しようとすると、合計するとworkerが3つ走るため、test.beforeAll()も結果それぞれのworker(テスト)に対して実行されます。

結論としては、1つのファイル内でテストを並列実行する際にtest.beforeAll()を一回だけ走らせるといったことはできません。
test.beforeAll()を一回だけ走らせたい場合は並列実行ではなく、順次実行でテストを実行させる必要があります。

補足

本記事は事前処理に使われるbeforeAll()beforeEach()について紹介していますが、事後処理に使われる

  • afterAll()
  • afterEach()

についても同じことが言えるため事後処理などで困っている方も同じ様に置き換えて考えていただければと思います。

詳しく解説します

テストの事前処理について

test.beforeAll()test.afterAll()はどちらもtest()が実行される前に実行されるもので、テストに必要な事前処理などを行うために使います。
例えば、

  • ユーザ画面が表示されるかどうかをテストしたい

こういった時、事前にログインをする必要がある際にtest.beforeAll()やtest.beforeEach()内にログイン処理を書くことが多いです。

test.beforeAll()test.beforeEach()の違い

test.beforeAll()test.beforeEach()を使いこなす必要が出てくるのは、1つのテストファイル内に複数のtest()が必要となってきた時です。
例えば、

test.beforeAll(async () => {
    console.log('beforeAll')
})
test.beforeEach(async () => {
    console.log('beforeEach')
})

// 1つのファイル内にtest()を2つ書く
test('hogehoge1', async () => {
    console.log('テスト1')
})
test('hogehoge2', async () => {
    console.log('テスト2')
})

test.afterEach(async () => {
    console.log('afterEach')
})
test.afterAll(async () => {
    console.log('afterAll')
})

これを実行すると、

beforeAll
beforeEach
テスト1
afterEach
beforeEach
テスト2
afterEach
afterAll

この様に表示されます。期待通りですよね。

playwrightはデフォルト設定では、1つのファイル内は順次実行の設定のため、実際に走るworkerの数としては1つとなるため期待通りの挙動をします。

しかし

test.beforeAll(async () => {
    console.log('beforeAll')
})
test.beforeEach(async () => {
    console.log('beforeEach')
})

+ test.describe.configure({ mode: 'parallel' })

// 1つのファイル内にtest()を2つ書く
test('hogehoge1', async () => {
    console.log('テスト1')
})
test('hogehoge2', async () => {
    console.log('テスト2')
})

test.afterEach(async () => {
    console.log('afterEach')
})
test.afterAll(async () => {
    console.log('afterAll')
})

上記のファイルに

test.describe.configure({ mode: 'parallel' })

を追加して並列実行してみると、、

beforeAll
beforeEach
テスト1
afterEach
afterAll
beforeAll
beforeEach
テスト2
afterEach
afterAll

この様にbeforeAllが毎回呼ばれてしまいます。

理由としては、並列実行した際は複数のテストに対して複数のworkerプロセスが動くためです。

こちらに軽く説明があるのでご覧いただければと思います。

結論

1つのファイル内でbeforeAll()を1回だけ実行したい場合は
並列実行ではなく、順次実行で実行する様にしましょう。

参考文献

17
3
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
17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?