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
4.9k
ロケーターを学んでテスト自動化上級者を目指そう
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
630
ノーコードE2Eテストで実現する高速開発
nozomiito
0
540
MagicPodで実現するE2Eテスト自動化
nozomiito
0
2.1k
MagicPod開発におけるテスト自動化とCI
nozomiito
0
620
最近のMagicPodまとめ
nozomiito
0
510
テスト自動化スタートアップがエバンジェリストを募集するワケ
nozomiito
0
230
MagicPodが取り組むテスト自動化最前線
nozomiito
0
380
テスト自動化で起業した10年とテスト自動化普及の歴史を振り返る
nozomiito
4
2.1k
テスト自動化で起業した10年とテスト自動化普及の歴史を振り返る
nozomiito
8
5k
Other Decks in Technology
See All in Technology
電子辞書にステータスバーを実装する
puhitaku
0
110
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
5
47k
入門 バックアップ
ryuichi1208
18
6.8k
Oracle Database 23ai 新機能#4 Application Continuity
oracle4engineer
PRO
0
120
怖くないオフライン機能開発 〜基本的な技術で実現する現場向けオフライン機能 / Developing offline functions without fear ~ Offline functions for the field realized with basic technology
kaminashi
1
110
【㈱アイモバイル】エンジニア向け会社説明資料
imobile
0
470
軽いノリで"自動化"に取り組んではいけないという話
tetsuyaooooo
1
550
tenntennはなんでnewmoにnew社したの? - YAPC::Hakodate 2024
tenntenn
PRO
0
290
入社半年(合計1年)でGoogle Cloud 認定を全冠した秘訣🤫
risatube
1
230
YAPC::Hakodateの映像記録を支える技術
godan
4
290
Webセキュリティのあるきかた
akiym
32
10k
【shownet.conf_】ShowNet 2024 ~ Inter * Network ~
shownet
PRO
0
530
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
459
33k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Thoughts on Productivity
jonyablonski
67
4.2k
GraphQLとの向き合い方2022年版
quramy
43
13k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
228
52k
Git: the NoSQL Database
bkeepers
PRO
425
64k
Creatively Recalculating Your Daily Design Routine
revolveconf
217
12k
What's new in Ruby 2.0
geeforr
341
31k
Learning to Love Humans: Emotional Interface Design
aarron
272
40k
Embracing the Ebb and Flow
colly
84
4.4k
Six Lessons from altMBA
skipperchong
26
3.4k
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!