自動テストチュートリアル

Playwright、Seleniumなどの自動テストツールを学ぼう

変更に強い要素の取得

🛡️ 壊れにくいテストを書くための考え方
見た目ではなく、意味で要素を捉える
📚 ここからは「テストを作成した後」の話
ここから最後のタブまでは、テストを作成した「後」の話をします。

ここまで何度もお伝えしてるように自動テストは「作って終わり」ではありません。むしろ、そこからがスタートであり、大変なところです。

アプリケーションの変更や時間の経過とともに、今日動いたテストが明日には失敗する、ということは日常的に起こります。

どうすればテストが**「壊れにくく」なり、「信頼され続ける」**のか、そのための品質と保守性を高める考え方とテクニックを学びます。

これは、単に「動くテスト」を書く段階から、保守性を考えた**「価値あるテスト」**を育てる段階へ進むための、非常に重要なステップです。


変更に強い要素の取得とは?

自動テストを運用し始めると、多くの人が直面する大きな壁があります。

「Webサイトの見た目を少し変えただけなのに、
たくさんのテストが壊れてしまった…

テストがすぐに壊れてしまう原因、そのほとんどは**要素の「指定方法」**にあります。

ここでは、なぜテストが壊れるのか、そしてどうすれば壊れにくい、変更に強いテストを書けるのかを学びます。


なぜテストは壊れるのか? 壊れやすい指定方法(アンチパターン)

家の住所に例えて考えてみましょう。友人に家を教えるとき、皆さまならどう伝えますか?


壊れやすい指定方法1:HTMLの構造に依存する(XPathなど)

🏠 例えるなら...
「駅を出て3番目の角を右に曲がり、そこから5軒目の、2階建ての家の、1階の右から2番目の窓」
⚠️ 問題点
途中に新しい家が建ったり、家が3階建てにリフォームされたりしたら、この道案内はもう使えません。

HTMLの構造に依存した指定方法は、これと全く同じです。レイアウトの変更でdivタグが1つ増えただけで、テストはすぐに壊れてしまいます。
await page.locator('div > div > div')

壊れやすい指定方法2:見た目(CSS)に依存する

🏠 例えるなら...
「赤い屋根で、青いドアの家」
⚠️ 問題点
デザイナーの気まぐれで、屋根が緑色に、ドアが茶色に塗り替えられたら、もう家を見つけられません。

CSSのクラス名(例: .btn-primary, .text-red)は、まさにこの「見た目」を定義するためのものです。サイトのリニューアルやデザイン変更で、最も頻繁に変わる部分であり、ここに依存するのは非常に危険です。
await page.locator('div.text-red')

変更に強い要素と変更に弱い要素

自動テストを安定して運用するためには、Webサイトのデザインが少し変わったくらいでは壊れない、「変更に強い」要素の指定方法を選ぶことが非常に重要です。

ここでは、どんな指定方法が「強い」のか、そしてどんな指定方法が「弱い」のか、その見分け方を学びましょう。

これはそのまま優先順位でもあります。

👑 最強:getBy〇〇系(Pick locatorが推奨)

Pick locatorが一番に提案してくる、getByRolegetByTextといった方法は、最も変更に強い、理想的な指定方法です。

💡 考え方
「『ログイン』と書かれたボタン」「『ユーザー名』というラベル」といった、ユーザーが見てわかる役割で要素を特定します。
✨ なぜ強い?
Webサイトのデザインが変わっても、ボタンの役割や、そこに書かれているテキストの意味は、めったに変わりません

🥈 強い:ユニークで意味のある id

idは、ページ内で一つしか使えない「個人名」のようなものです。

💡 考え方
id="login-button" のように、その要素の役割がひと目でわかる名前が付けられている場合、非常に信頼できます。
✨ なぜ強い?
idは、プログラムの動作に直接関わることが多いため、デザイン変更の影響を受けにくく、比較的変わりにくいからです。

変更に弱い指定方法 😥

変更に弱い指定方法の共通点は、見た目や、**HTMLの構造(場所)**に依存していることです。これらは、サイトの改修で非常によく変更される部分です。


❌ HTMLの構造に頼る

await page.locator('div > div > div')
なぜ弱い? 「3番目の箱の中の、2番目の箱の中にある…」という、場所で指定する方法です。途中に新しい箱が一つ追加されただけで、この指定はもう使えなくなってしまいます。

❌ 意味が不明、またはランダムな class名

await page.locator('div.list_01_hogehoge')
await page.locator('span.a-b-c-d')
なぜ弱い? classは、本来デザインを当てるためのものです。特に、_-で区切られた、意味の分からない文字列や、ランダムに見える数字が入っているclass名は、デザイナーやプログラムが自動で生成していることが多く、いつ変わってもおかしくありません。

❌ 色やフォントサイズといった「見た目そのもの」に頼る

await page.locator('span.text-red')
await page.locator('div.font-large')
なぜ弱い? Webサイトの「色」や「文字の大きさ」は、リニューアルやデザインの微調整で最も頻繁に変わる部分です。今日、警告メッセージが赤色でも、明日にはオレンジ色に変わるかもしれません。見た目そのものに依存したテストは、デザイナーが少し手を入れただけで、すぐに壊れてしまう最も脆い指定方法の一つです。

❌ 長すぎる文章で指定する

await page.getByText('利用規約をよくお読みの上、同意される場合はチェックを入れてください。')
なぜ弱い? もし、将来的に「利用規約」が「サービス規約」という言葉に変わったり、句読点が一つ変わったりしただけで、このテストは失敗してしまいます。

より短く、本質的なキーワード(例: getByText('利用規約'))で指定する方が、はるかに安全です。

まとめ:見た目ではなく、意味で捉える

変更に強いテストを書く秘訣
見た目や内部構造ではなく、ユーザーにとっての役割や意味で要素を捉えること

テストコードを書くとき、常に自問自答してみてください。

🤔 「この指定方法は、もしデザイナーが色を変えたら壊れるだろうか?」
🤔 「この指定方法は、もしエンジニアがHTMLの構造を変えたら壊れるだろうか?」
この視点を持つだけで、あなたの書くテストの寿命と信頼性は、劇的に向上するはずです。