Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ロケーターを学んでテスト自動化上級者を目指そう
Search
Nozomi Ito
March 15, 2023
Technology
1
5.3k
ロケーターを学んでテスト自動化上級者を目指そう
2023.3.9に開催された「JaSST'23 Tokyo」の資料です。
https://www.jasst.jp/symposium/jasst23tokyo/details.html#D4-1
Nozomi Ito
March 15, 2023
Tweet
Share
More Decks by Nozomi Ito
See All by Nozomi Ito
ノーコードに学ぶE2Eテスト自動化ベストプラクティス
nozomiito
0
710
ノーコードE2Eテストで実現する高速開発
nozomiito
0
560
MagicPodで実現するE2Eテスト自動化
nozomiito
0
2.4k
MagicPod開発におけるテスト自動化とCI
nozomiito
0
640
最近のMagicPodまとめ
nozomiito
0
520
テスト自動化スタートアップがエバンジェリストを募集するワケ
nozomiito
0
230
MagicPodが取り組むテスト自動化最前線
nozomiito
0
400
テスト自動化で起業した10年とテスト自動化普及の歴史を振り返る
nozomiito
4
2.1k
テスト自動化で起業した10年とテスト自動化普及の歴史を振り返る
nozomiito
8
5.1k
Other Decks in Technology
See All in Technology
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
OCI Security サービス 概要
oracle4engineer
PRO
0
6.5k
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
8
870
エンジニア人生の拡張性を高める 「探索型キャリア設計」の提案
tenshoku_draft
1
130
Engineer Career Talk
lycorp_recruit_jp
0
190
DynamoDB でスロットリングが発生したとき_大盛りver/when_throttling_occurs_in_dynamodb_long
emiki
1
430
Security-JAWS【第35回】勉強会クラウドにおけるマルウェアやコンテンツ改ざんへの対策
4su_para
0
180
Oracle Cloud Infrastructureデータベース・クラウド:各バージョンのサポート期間
oracle4engineer
PRO
28
13k
Python(PYNQ)がテーマのAMD主催のFPGAコンテストに参加してきた
iotengineer22
0
500
Why App Signing Matters for Your Android Apps - Android Bangkok Conference 2024
akexorcist
0
130
Lexical Analysis
shigashiyama
1
150
『Firebase Dynamic Links終了に備える』 FlutterアプリでのAdjust導入とDeeplink最適化
techiro
0
130
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
4 Signs Your Business is Dying
shpigford
180
21k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
How to Think Like a Performance Engineer
csswizardry
20
1.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Speed Design
sergeychernyshev
25
620
Product Roadmaps are Hard
iamctodd
PRO
49
11k
[RailsConf 2023] Rails as a piece of cake
palkan
52
4.9k
KATA
mclloyd
29
14k
Building Your Own Lightsaber
phodgson
103
6.1k
A better future with KSS
kneath
238
17k
Transcript
ロケーターを学んで テスト⾃動化上級者を⽬指そう MagicPod CEO 伊藤望 JaSST’23 Tokyo
About me • 伊藤 望 (Ito Nozomi) • 株式会社MagicPod CEO
• ⾃動テストツール歴:約13年 • Twitter:@ito_nozomi • 著書
MagicPod • Web & モバイルアプリのE2Eテスト⾃動化SasS • ノーコードで簡単にテスト作成 • 柔軟性とメンテナンス性が強み (magicpod.com)
ユーザーさんのブログ記事‧発表 MagicPodでE2Eテストを実装した話 みてねのE2E⾃動テスト導⼊戦略 アプリのテストに MagicPodを導⼊している話 【インターンレポート】⾃動テストを 実装したら衝撃を受けた学⽣の話 Ubieのアプリ開発を⽀える MagicPodを使った⾃動テスト テスト⾃動化初⼼者がノーコードツール
「MagicPod」でテスト⾃動化に挑戦してみた
Agenda 1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5.
ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表
1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準
6. XPath & CSSセレクター早⾒表
「ロケーター」って? • UI⾃動テストツールにはロケーターの概念がある • セレクターとも⾔う • コード型ツールの場合、理解必須 • ノーコード型ツールも裏で使っている -
理解すると、よりツールを使いこなせる 1. ロケーター概要 ※ 例外もあります
1. ロケーター概要 Webページの各画⾯要素(=画⾯項⽬)には、 エンジニアが裏でシステムIDを付けている
1. ロケーター概要 userArea passwdArea signIn Webページの各画⾯要素(=画⾯項⽬)には、 エンジニアが裏でシステムIDを付けている
1. ロケーター概要 passwdArea signIn UI⾃動テストツールは、 このシステムIDで操作対象を認識する テスト⼿順(=スクリプト) テキスト⼊⼒(userArea, nozomi.ito) テキスト⼊⼒(passwdArea,
pass01) クリック(signIn) userArea
1. ロケーター概要 ??? ??? システムIDがなかったり、 あってもツールで認識できない時は? テスト⼿順 テキスト⼊⼒(???, nozomi.ito) テキスト⼊⼒(???,
pass01) クリック(???) ???
1. ロケーター概要 ??? ??? input[1] (上から1番⽬の⼊⼒エリアの意味) のような、 別の指定⽅法を使う テキスト⼊⼒(input[1], nozomi.ito)
テキスト⼊⼒(input[2], pass01) クリック(button[1]) ??? テスト⼿順
「ロケーター」とは userArea input[1] のように、 テスト内で操作対象の画⾯要素を指定する部分 1. ロケーター概要 テキスト⼊⼒(userArea, nozomi.ito) テキスト⼊⼒(passwdArea,
pass01) クリック(signIn) テキスト⼊⼒(input[1], nozomi.ito) テキスト⼊⼒(input[2], pass01) クリック(button[1])
ロケーターの⽂法の例 1. ロケーター概要 ※ 細かい⽂法はツールによって異なる ※ MagicPodはSeleniumに近い⽂法 id=signIn システムIDがsignInの画⾯要素 xpath=//input[1]
上から1番⽬の⼊⼒エリア xpath=//button[text()=ʻ検索’] テキストが「検索」のボタン
要素のロケーターを調べるには? 1. ロケーター概要 ①Chrome上で要素を右クリックして「検証」
要素のロケーターを調べるには? 1. ロケーター概要 ②システムIDを発⾒!
1. ロケーター概要 • Webページの内部はHTMLで表される • ロケーターの理解にはHTMLの理解が不可⽋ HTML
1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準
6. XPath & CSSセレクター早⾒表
Webページの内部はHTML 2. HTML概要 <html> <body> <form> <input name="keyword" placeholder="キーワード"> <button
id="search">検索</button> </form> </body> </html>
<html> <body> <form> <input name="keyword" placeholder="キーワード"> <button id="search">検索</button> </form> </body>
</html> HTMLの構造 2. HTML概要 「開始タグ」と「終了タグ」 のペアが1つの要素
<html> <body> <form> <input name="keyword" placeholder="キーワード"> <button id="search">検索</button> </form> </body>
</html> HTMLの構造 2. HTML概要 「開始タグ」のみの 要素もある
<html> <body> <form> <input name="keyword" placeholder="キーワード"> <button id="search">検索</button> </form> </body>
</html> HTMLの構造 2. HTML概要 「タグ名」で要素の種類が分かる • input:各種⼊⼒エリア • button:ボタン
<html> <body> <form> <input name="keyword" placeholder="キーワード"> <button id="search">検索</button> </form> </body>
</html> HTMLの構造 2. HTML概要 テキストは開始と終了タグに 囲まれる
HTMLの構造 2. HTML概要 <html> <body> <form> <input name="keyword" placeholder="キーワード"> <button
id="search">検索</button> </form> </body> </html> 「属性」で要素の各種情報を指定 • システムID、システム名 • 初期表⽰テキスト(placeholder) • …
<html> <body> <form> <input name="keyword" placeholder="キーワード"> <button id="search">検索</button> </form> </body>
</html> HTMLの構造 2. HTML概要 ⼊れ⼦の要素は 親⼦関係を表す
1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準
6. XPath & CSSセレクター早⾒表
HTMLも分かったところで、 よく使うロケーター⽂法を解説 3. ロケーター⽂法解説
3. ロケーター⽂法解説 よく使うロケーターその1 - id <html> <body> <form> <input name="keyword"
placeholder="キーワード"> <button id="search">検索</button> </form> </body> </html> id=search システムIDがsearchの要素 = id属性がsearhの要素
3. ロケーター⽂法解説 よく使うロケーターその2 - name <html> <body> <form> <input name="keyword"
placeholder="キーワード"> <button id="search">検索</button> </form> </body> </html> name=keyword システム名がkeywordの要素 = name属性がkeywordの要素
3. ロケーター⽂法解説 idとnameは何が違うのか? • プログラム上の役割が違う • どちらも要素を⼀意に特定するのに使える • 両⽅ある時はnameの⽅が変更されにくい
3. ロケーター⽂法解説 よく使うロケーターその3 - XPath <html> <body> <form> <input name="keyword"
placeholder="キーワード"> <button id="search">検索</button> </form> </body> </html> xpath=//input[1] 上から1番⽬の⼊⼒エリア = 上から1番⽬のinputタグの要素
3. ロケーター⽂法解説 よく使うロケーターその3 - XPath <html> <body> <form> <input name="keyword"
placeholder="キーワード"> <button id="search">検索</button> </form> </body> </html> xpath= //input[@name=ʻkeyword’] name属性がkeywordのinput要素
3. ロケーター⽂法解説 よく使うロケーターその3 - XPath <html> <body> <form> <input name="keyword"
placeholder="キーワード"> <button id="search">検索</button> </form> </body> </html> テキストが「検索」のbutton要素 (属性ではないので@textと書けない) xpath= //button[text()=ʻ検索’]
3. ロケーター⽂法解説 よく使うロケーターその3 - XPath <html> <body> <form id="main"> <button>戻る</button>
<button>次へ</button> </form> </body> </html> id属性がmainのform要素の下にある中で2番⽬のbutton要素 xpath= //form[@id=ʻmain’]/button[2]
3. ロケーター⽂法解説 よく使うロケーターその3 - XPath <html> <body> <form id="main"> <span>
<button>戻る</button> </span> <span> <button>次へ</button> </span> </form> </body> </html> xpath= //form[@id=ʻmain’]/span[2]/button[1]
3. ロケーター⽂法解説 よく使うロケーターその4 - CSSセレクター • 表現⼒はXPathとだいたい同じ • 開発者はこちらのが好き •
詳細は今⽇は割愛
1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準
6. XPath & CSSセレクター早⾒表
UI⾃動テストでよく⾒る 「要素が⾒つからない」エラーの 解決にチャレンジ! 4. ロケーター実践トラブルシューティング
初級編 4. ロケーター実践トラブルシューティング
4. ロケーター実践トラブルシューティング ‒ 初級編 クリック(id=OKButton) 昨⽇まで動いていたテスト
4. ロケーター実践トラブルシューティング ‒ 初級編 「id=OKButton」の要素が⾒つかりません エラー エラー時の画⾯ いつものように実⾏ クリック(id=OKButton)
4. ロケーター実践トラブルシューティング ‒ 初級編 OKボタン あるやん..
4. ロケーター実践トラブルシューティング ‒ 初級編 HTMLでOKButtonがあるか確認 要素を右クリックして「検証」 <html> <body> <form> <button
id="okButton"> OK </button> </form> </body> </html> HTMLを確認
4. ロケーター実践トラブルシューティング ‒ 初級編 OKButtonちゃんとありそうだが.. <html> <body> <form> <button id="okButton">
OK </button> </form> </body> </html>
4. ロケーター実践トラブルシューティング ‒ 初級編 OKButtonちゃんとありそうだが.. <html> <body> <form> <button id="okButton">
OK </button> </form> </body> </html> よく⾒るとok が⼩⽂字!
4. ロケーター実践トラブルシューティング ‒ 初級編 原因 エンジニアがボタンのidを変更した テスト⼿順も変更 修正 クリック(id=OKButton) クリック(id=okButton)
ちなみに 4. ロケーター実践トラブルシューティング ‒ 初級編
クリック(id=OKButton) クリック(id=okButton) MagicPodなら このくらいは⾃動で修復します 4. ロケーター実践トラブルシューティング ‒ 初級編
上級編 4. ロケーター実践トラブルシューティング
4. ロケーター実践トラブルシューティング ‒ 上級編 クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]) 昨⽇まで動いていたテスト
4. ロケーター実践トラブルシューティング ‒ 上級編 「xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]」 の要素が⾒つかりません エラー エラー時の画⾯ いつものように実⾏ クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1])
4. ロケーター実践トラブルシューティング ‒ 上級編 ちょっと何⾔って るか分かんない..
4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈 <html> <body> <div id="main"> <div>
<div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> エラー時のHTML
4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈 <html> <body> <div id="main"> <div>
<div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> エラー時のHTML //div[@id=ʻmain’]
4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈 <html> <body> <div id="main"> <div>
<div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> エラー時のHTML //div[@id=ʻmain’] //div[@id=ʻmain’]/div[1]
4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈 <html> <body> <div id="main"> <div>
<div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> エラー時のHTML //div[@id=ʻmain’] //div[@id=ʻmain’]/div[1] //div[@id=ʻmain’]/div[1]/div[1]
4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈 <html> <body> <div id="main"> <div>
<div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> エラー時のHTML //div[@id=ʻmain’] //div[@id=ʻmain’]/div[1] //div[@id=ʻmain’]/div[1]/div[1] //div[@id=ʻmain’]/div[1]/div[1]/a[1] ??
4. ロケーター実践トラブルシューティング ‒ 上級編 たしかに⾒つからないが.. そもそも何を操作したかったのか..
4. ロケーター実践トラブルシューティング ‒ 上級編 テストを作った時のHTMLを⾒てみる <html> <body> <div id="main"> <div>
<div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> テスト作成時のHTML
4. ロケーター実践トラブルシューティング ‒ 上級編 テストを作った時のHTMLを⾒てみる <html> <body> <div id="main"> <div>
<div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> テスト作成時のHTML //div[@id=ʻmain’]/div[1]/div[1]/a[1] あった!
4. ロケーター実践トラブルシューティング ‒ 上級編 画⾯構成に変更がされていた模様 <html> <body> <div id="main"> <div>
<div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> テスト作成時のHTML <html> <body> <div id="main"> <div> <div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> エラー時のHTML
4. ロケーター実践トラブルシューティング ‒ 上級編 画⾯構成に変更がされていた模様 <html> <body> <div id="main"> <div>
<div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> テスト作成時のHTML <html> <body> <div id="main"> <div> <div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> エラー時のHTML クリック したかったもの
4. ロケーター実践トラブルシューティング ‒ 上級編 変更後の新画⾯でのロケーターは? <html> <body> <div id="main"> <div>
<div> <span>テスト⾃動化なら</span> </div> <div> <a href="https://magicpod.com">MagicPod</a> </div> </div> </div> </body> </html> エラー時のHTML //div[@id=ʻmain’]/div[1]/div[2]/a[1] //a[text()=ʻMagicPod’] or
4. ロケーター実践トラブルシューティング ‒ 上級編 原因 エンジニアが画⾯構成を変更した テスト⼿順も変更 修正 クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]) クリック(xpath=//div[@id=ʻmain’]/div[1]/div[2]/a[1])
ちなみに 4. ロケーター実践トラブルシューティング ‒ 上級編
MagicPodなら これも⾃動で修復します 4. ロケーター実践トラブルシューティング ‒ 上級編 ※ 修復し損ねるケースもあります クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]) クリック(xpath=//a[text()=ʻMagicPod’])
1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準
6. XPath & CSSセレクター早⾒表
5. ロケーターの使い分け基準 ロケーターはどれを使うのがいいのか? <html> <body> <form id="main"> <button>戻る</button> <button>次へ</button> </form>
</body> </html> xpath=//button[text()=ʻ戻る’] xpath=//button[1] xpath= //form[@id=ʻmain’]/button[1] 全部同じ要素!
5. ロケーターの使い分け基準 メンテナンス性が⾼い = 画⾯の変更が⼊っても影響がない 良いロケーター =
5. ロケーターの使い分け基準 各種ロケーターのメンテナンス性 を考えてみる
5. ロケーターの使い分け基準 システムID、システム名 • 開発者が変更することは少なめ • ReactJSを使った最近のサイトでは、 idは無かったりランダムだったりで使いにくいこと多し … <input
name="keyword"> <button id="search">検索</button> …
5. ロケーターの使い分け基準 テキスト ‒ 良いテキスト • テストデータと関係ない画⾯表⽰テキストは、 変更されることは少なめ • 多⾔語対応のテストをしたい場合は使えない
… <input name="keyword"> <button id="search">検索</button> …
5. ロケーターの使い分け基準 テキスト ‒ 悪いテキスト • テストデータのテキストを ロケーターにベタ書きすると変更に弱くなる • テストケースの共通化の妨げにも
… <div id=”total“>7,000円</button> …
5. ロケーターの使い分け基準 data-testid属性 • テスト専⽤につけられた、要素を⼀意に識別する属性 • 開発者は極⼒変更しないようにしてくれる(はず) • 無い時は開発チームに依頼してみましょう …
<button data-testid="search">検索</button> …
5. ロケーターの使い分け基準 class属性 • 要素の⽬的‧デザインなどを表す種別 • 多くの場合、要素を⼀意に識別するものではない … <button class=”normal">検索</button>
…
5. ロケーターの使い分け基準 上からの順番 変更に弱いので、できるだけ避けた⽅がよい … <button>検索</button> … xpath=//button[1]
5. ロケーターの使い分け基準 要素のパス … <div id="main"> <div>MagicPod</div> </div> … xpath=//div[@id=ʻmain’]/div[1]
変更に弱いので、できるだけ避けた⽅がよい
5. ロケーターの使い分け基準 各テストツールは 何を推奨しているか?
5. ロケーターの使い分け基準 Selenium https://www.selenium.dev/documentation/test_practices/encouraged/locators • idを推奨 • ReactJSの無い頃のドキュメントなので、 時代に合っていない気が
5. ロケーターの使い分け基準 Cypress https://docs.cypress.io/guides/references/best-practices#Selecting-Elements • data-testid的アプローチを推奨 • id、name、テキストはケースバイケース
5. ロケーターの使い分け基準 Playwright https://playwright.bootcss.com/python/docs/selectors#best-practices • UIがあまり変わらない場合は、 テキストなどユーザーに⾒えているもの推奨 • そうでなければdata-testid推奨 •
多⾔語テストが少ない英語圏の発想な気が
5. ロケーターの使い分け基準 個⼈的おすすめ まずはdata-testid属性 無理ならidかnameか良いテキスト
1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準
6. XPath & CSSセレクター早⾒表
6. XPath & CSSセレクター早⾒表 XPath CSSセレクター id属性がokのbutton要素 //button[@id=ʻok’] あまり使われません id属性がokの要素
//*[@id=ʻok’] #ok name属性がuserのinput要素 //input[@name=ʻuser’] input[name=ʻuser’] name属性がradio かつvalue属性がonのinput要素 //input[@name=ʻradio’][@value=ʻon’] input[name=ʻradio’][value=ʻon’] data-testid属性がokのbutton要素 //button[@data-testid=ʻok’] button[data-testid=ʻok’] テキストがOKのbutton要素 //button[text()=ʻOK’] ⾮対応 テキストがOKを含むbutton要素 //button[contains(text(),’OK’)] ⾮対応 class属性logoを持つ要素 CSSセレクターの利⽤がお勧め .logo class属性logoを持つdiv要素 CSSセレクターの利⽤がお勧め div.logo class属性logoとmainを持つdiv要素 CSSセレクターの利⽤がお勧め div.logo.main
XPath CSSセレクター 上から2番⽬のinput要素 //input[2] ⾮対応 id属性がmainの要素直下のdiv要素 //*[@id=ʻmain’]/div #main > div
id属性がmainの要素の下にある div要素 //*[@id=ʻmain’]//div #main div id属性がmainの要素の直下にある div要素のうち上から2番⽬のもの //*[@id=ʻmain’]/div[2] #main > div:nth-of-type(2) id属性がmainの要素直下のdiv要素の さらに直下のinput要素 //*[@id=ʻmain’]/div/input #main > div > input id属性がokのbutton要素の親要素 //button[@id=ʻok’]/.. ⾮対応 id属性がmainの要素と同階層で、 それよりも後ろにあるdiv要素 //*[@id=ʻmain’]/following-sibling::div #main ~ div id属性がmainの要素と同階層で、 それよりも前にあるdiv要素 //*[@id=ʻmain’]/preceding-sibling::div ⾮対応 ※ 「⾮対応」の⼀部はPlaywrightなら可能 6. XPath & CSSセレクター早⾒表
今⽇お話できなかったこと • CSSセレクターの詳細 • モバイルアプリ(Appium)のロケーター • 相対ロケーター(Relative Locator) • 良いロケーターが本当に無い場合
MagicPodならロケーターは ⾃動計算&⾃動修復! @MagicPodJP
イベント告知
Thank you!