🔰

未経験から始めた自動テストでブチ当たった壁

2024/02/16に公開2

はじめまして!私は文系大学出身で未経験からQAエンジニアを始めた者です!
社会人になってもう2年目になります...はやい(怖い)...。
今回はコードベースの自動テスト、playwrightに未経験エンジニアが挑戦した話をします!

今回のお話がおもしろかったらぜひこちらもみていただきたいです!
https://zenn.dev/sdb_blog/articles/001-integrating_playwright_with_circle_ci

はじめに

QAなら誰でも聞いたことのある「自動テスト」。「夢」ありますよね(?)
そんな自動テストにコードがほぼ読めないQAエンジニアが挑戦してみました!

今回触れたツールは「playwright」です。🎭

playwrightってなに?

  • 自動テストツール
  • E2E[1]テストフレームワークの1つ
  • C#,TypeScript,Pythonなどのプログラミング言語で利用できる(今回はTypeScript)
  • クロスブラウザ対応

やったこと

playwrightをインストール

まずはインストール。ターミナルを開いて以下のコマンドを打ちます

npm init playwright@latest

playwrightの機能でコード生成

playwrightには自分が行った操作をコードに起こしてくれる機能があります!

心の声「なんだ!!コードいらないし楽やないかい!!」

ということでターミナルで以下のコマンドを実行します!

npx playwright codegen

すると以下の2つの画面が立ち上がります

これらを実際にボタンポチポチしていくぅ!!

今回は...

手順
1.https://www.google.com/ のページに飛ぶ
2.検索バーでplaywright を検索する
3.playwright公式ページへ遷移する

というシナリオで操作しようと思います

実際に開かれたブラウザで試すとこんな感じでコード生成されます

コードだけ抽出するとこんな感じ

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('https://www.google.com/');
  await page.getByLabel('検索', { exact: true }).click();
  await page.getByLabel('検索', { exact: true }).fill('playwright');
  await page.getByRole('link', { name: 'Playwright: Fast and reliable end-to-end testing for modern ... Playwright https://playwright.dev' }).click();
});

生成されたコード(画像左側のウィンドウ)をコピーして、、、

任意のエディターに貼り付けて、、

ターミナルで

npx playwright test --ui

すると.....

💥こんな感じでうまくいかないです(爆発)💥

  • 検索バーに「playwright」と入力することはできた⭕️
  • その後に「検索ボタンを押す」ということができていない❌

原因

  • 要素特定がしっかりされていないため。
  • 今回はブラウザで特定のワードを調べさせるということをplaywrightでやらせてみたのですが、
  • 本来はWEBアプリケーションで要素特定をさせるためにdata-testidというものをボタン等に割り振る必要があります。
要素特定がいけていないとなにがだめ?

「なぜか押してくれた...」みたいなこともあった

下記参考
https://zenn.dev/subaru_hello/articles/d291a0960244ce

data-testid入れ込むには?

こんな感じでIDを割り振るみたい

 <div class="◯◯◯◯◯"
        data-testid="hogeBtn"
      >

テストコードはこう

await page.getBytestid("hogeBtn").click();

やってて大変なこと

ということで今現在は上記のようにtestidを仕込んだり、テストコードを書いたりというのを挑戦しています!

とはいいつつ、

心の声「HTMLで特定のボタンにid割り振るだけぢゃん!」

と思いながらいざ実際やってみると壁にぶち当たりました。

ということで勉強も並行して開始、Laravelくんのことがちょっと好きになってきました
(現在進行形)

おわりに

経験が浅いエンジニアの僕からするとplaywrightは目の前にあるコードを理解していけばある程度書けるだろうと考えていました。
実際に手を動かしてみると、もちろんそんなことはなく、

  • フレームワークの知識
  • ファイル構成の理解

も合わせて必要だなという風に感じました。(要勉強!!)

まだまだ覚えることは多い私ですが今とても"楽しみながら"知識を吸収できています!
私と同じ境遇で経験が浅い方や普段コードを書かないQAエンジニアの方も、まずは「playwright codegen」をするところから始めてみてほしいです!

これからも楽しむことを忘れずにたくさんのことを知れたら良いなと思っています!うお〜〜🐟!

脚注
  1. ソフトウェアのエンドユーザーが行う操作を模倣し、アプリケーション全体の動作をテストすること ↩︎

ソーシャルデータバンク テックブログ

Discussion

k1350k1350

私も(テスト目的ではなくブラウザ操作の自動化目的ですが)Playwrightを少し触っておりまして、記事の内容を興味深く拝見させていただきました。
一点、表現に気になった点がありコメントさせていただきます。

記事内で npx playwright codegen で生成した結果のコードを実行してもうまくいかず、原因が「要素特定がされていない」であるとして

本来はWEBアプリケーションで要素特定をさせるためにdata-testidというものをボタン等に割り振る必要があります。

と記述されている点についてです。
まず、ここには少し誤解があるように思います。

記事に示されたコードで「検索ボタンを押す」ができていなかった理由は、検索ボタンの要素特定ができていないからではなくて、そもそも検索ボタンを押下しようとしていないからだと思われます。
おそらく、検索バーに「playwright」と入力後、画面上の「Google 検索」ボタンを押す前にキーボードの Enter キーを叩いてしまった等で、playwright の対応範囲外で検索が実行されてしまい、検索ボタンを押下するステップが記録されなかったのだと思います。

確認のために、私も試しに手元で npx playwright codegen でコード生成してみました。
ブラウザ上の操作だけで検索を行うことに気を付けて操作し、下記のようなコードになりました。
(何をしているのかについてコメントだけ追加しています。)

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  // Google にアクセス
  await page.goto('https://www.google.com/');
  // 検索バーに「playwright」と入力
  await page.getByLabel('検索', { exact: true }).click();
  await page.getByLabel('検索', { exact: true }).fill('playwright');
  // 「Google 検索」ボタンをクリック
  await page.getByLabel('Google 検索').first().click();
  // 検索結果の画面で Playwright の公式サイトへのリンクをクリック
  await page.getByRole('link', { name: 'Playwright: Fast and reliable' }).click();
});

記事内のコードと比較しますと、検索ワード入力後、「Google 検索」というラベルがついた最初の要素をクリックするステップが追加されています。
このコードは npx playwright test --ui で正しく動作しました。

実は画面内には「Google 検索」というラベルがついた要素が複数存在していたため、first() を使って最初の要素をクリックするようにするなど、playwright の自動生成コードはどのボタンを押すか明確に判断できるように工夫されています。
ちなみに first() を消すと、playwright はどのボタンを押せばいいかわからないので実行時にエラーを吐きます。

上記の点を踏まえて

本来はWEBアプリケーションで要素特定をさせるためにdata-testidというものをボタン等に割り振る必要があります。

という点について、「必要がある」というのは少し表現が強すぎるように思います。
実際には data-testid を使わなくても要素を特定することが可能であることは多いです。
そのため「data-testid を使うと良いこともある」程度のマイルドな表現のほうが適切ではないかと思いました。

長いコメントになり失礼しました!

pulasQpulasQ

コメントありがとうございます!
確かに…まさにご指摘の通りだと思います…
記事の記載だと誤解招きますね🙇

実際にテスト自動化として運用する際に「壊れにくい自動化テスト」を作るためにdata-testidを割り振ることをしている。のが実際にやっていたことだったなぁ…と振り返ると思いました。

ご指摘コメントありがとうございました!
まだまだ勉強不足なのでこれからも精進します…!