Slide 1

Slide 1 text

ロケーターを学んで テスト⾃動化上級者を⽬指そう MagicPod CEO 伊藤望 JaSST’23 Tokyo

Slide 2

Slide 2 text

About me • 伊藤 望 (Ito Nozomi) • 株式会社MagicPod CEO • ⾃動テストツール歴:約13年 • Twitter:@ito_nozomi • 著書

Slide 3

Slide 3 text

MagicPod • Web & モバイルアプリのE2Eテスト⾃動化SasS • ノーコードで簡単にテスト作成 • 柔軟性とメンテナンス性が強み (magicpod.com)

Slide 4

Slide 4 text

ユーザーさんのブログ記事‧発表 MagicPodでE2Eテストを実装した話 みてねのE2E⾃動テスト導⼊戦略 アプリのテストに MagicPodを導⼊している話 【インターンレポート】⾃動テストを 実装したら衝撃を受けた学⽣の話 Ubieのアプリ開発を⽀える MagicPodを使った⾃動テスト テスト⾃動化初⼼者がノーコードツール 「MagicPod」でテスト⾃動化に挑戦してみた

Slide 5

Slide 5 text

Agenda 1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 6

Slide 6 text

1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 7

Slide 7 text

「ロケーター」って? • UI⾃動テストツールにはロケーターの概念がある • セレクターとも⾔う • コード型ツールの場合、理解必須 • ノーコード型ツールも裏で使っている - 理解すると、よりツールを使いこなせる 1. ロケーター概要 ※ 例外もあります

Slide 8

Slide 8 text

1. ロケーター概要 Webページの各画⾯要素(=画⾯項⽬)には、 エンジニアが裏でシステムIDを付けている

Slide 9

Slide 9 text

1. ロケーター概要 userArea passwdArea signIn Webページの各画⾯要素(=画⾯項⽬)には、 エンジニアが裏でシステムIDを付けている

Slide 10

Slide 10 text

1. ロケーター概要 passwdArea signIn UI⾃動テストツールは、 このシステムIDで操作対象を認識する テスト⼿順(=スクリプト) テキスト⼊⼒(userArea, nozomi.ito) テキスト⼊⼒(passwdArea, pass01) クリック(signIn) userArea

Slide 11

Slide 11 text

1. ロケーター概要 ??? ??? システムIDがなかったり、 あってもツールで認識できない時は? テスト⼿順 テキスト⼊⼒(???, nozomi.ito) テキスト⼊⼒(???, pass01) クリック(???) ???

Slide 12

Slide 12 text

1. ロケーター概要 ??? ??? input[1] (上から1番⽬の⼊⼒エリアの意味) のような、 別の指定⽅法を使う テキスト⼊⼒(input[1], nozomi.ito) テキスト⼊⼒(input[2], pass01) クリック(button[1]) ??? テスト⼿順

Slide 13

Slide 13 text

「ロケーター」とは userArea input[1] のように、 テスト内で操作対象の画⾯要素を指定する部分 1. ロケーター概要 テキスト⼊⼒(userArea, nozomi.ito) テキスト⼊⼒(passwdArea, pass01) クリック(signIn) テキスト⼊⼒(input[1], nozomi.ito) テキスト⼊⼒(input[2], pass01) クリック(button[1])

Slide 14

Slide 14 text

ロケーターの⽂法の例 1. ロケーター概要 ※ 細かい⽂法はツールによって異なる ※ MagicPodはSeleniumに近い⽂法 id=signIn システムIDがsignInの画⾯要素 xpath=//input[1] 上から1番⽬の⼊⼒エリア xpath=//button[text()=ʻ検索’] テキストが「検索」のボタン

Slide 15

Slide 15 text

要素のロケーターを調べるには? 1. ロケーター概要 ①Chrome上で要素を右クリックして「検証」

Slide 16

Slide 16 text

要素のロケーターを調べるには? 1. ロケーター概要 ②システムIDを発⾒!

Slide 17

Slide 17 text

1. ロケーター概要 • Webページの内部はHTMLで表される • ロケーターの理解にはHTMLの理解が不可⽋ HTML

Slide 18

Slide 18 text

1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 19

Slide 19 text

Webページの内部はHTML 2. HTML概要 検索

Slide 20

Slide 20 text

検索 HTMLの構造 2. HTML概要 「開始タグ」と「終了タグ」 のペアが1つの要素

Slide 21

Slide 21 text

検索 HTMLの構造 2. HTML概要 「開始タグ」のみの 要素もある

Slide 22

Slide 22 text

検索 HTMLの構造 2. HTML概要 「タグ名」で要素の種類が分かる • input:各種⼊⼒エリア • button:ボタン

Slide 23

Slide 23 text

検索 HTMLの構造 2. HTML概要 テキストは開始と終了タグに 囲まれる

Slide 24

Slide 24 text

HTMLの構造 2. HTML概要 検索 「属性」で要素の各種情報を指定 • システムID、システム名 • 初期表⽰テキスト(placeholder) • …

Slide 25

Slide 25 text

検索 HTMLの構造 2. HTML概要 ⼊れ⼦の要素は 親⼦関係を表す

Slide 26

Slide 26 text

1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 27

Slide 27 text

HTMLも分かったところで、 よく使うロケーター⽂法を解説 3. ロケーター⽂法解説

Slide 28

Slide 28 text

3. ロケーター⽂法解説 よく使うロケーターその1 - id 検索 id=search システムIDがsearchの要素 = id属性がsearhの要素

Slide 29

Slide 29 text

3. ロケーター⽂法解説 よく使うロケーターその2 - name 検索 name=keyword システム名がkeywordの要素 = name属性がkeywordの要素

Slide 30

Slide 30 text

3. ロケーター⽂法解説 idとnameは何が違うのか? • プログラム上の役割が違う • どちらも要素を⼀意に特定するのに使える • 両⽅ある時はnameの⽅が変更されにくい

Slide 31

Slide 31 text

3. ロケーター⽂法解説 よく使うロケーターその3 - XPath 検索 xpath=//input[1] 上から1番⽬の⼊⼒エリア = 上から1番⽬のinputタグの要素

Slide 32

Slide 32 text

3. ロケーター⽂法解説 よく使うロケーターその3 - XPath 検索 xpath= //input[@name=ʻkeyword’] name属性がkeywordのinput要素

Slide 33

Slide 33 text

3. ロケーター⽂法解説 よく使うロケーターその3 - XPath 検索 テキストが「検索」のbutton要素 (属性ではないので@textと書けない) xpath= //button[text()=ʻ検索’]

Slide 34

Slide 34 text

3. ロケーター⽂法解説 よく使うロケーターその3 - XPath 戻る 次へ id属性がmainのform要素の下にある中で2番⽬のbutton要素 xpath= //form[@id=ʻmain’]/button[2]

Slide 35

Slide 35 text

3. ロケーター⽂法解説 よく使うロケーターその3 - XPath 戻る 次へ xpath= //form[@id=ʻmain’]/span[2]/button[1]

Slide 36

Slide 36 text

3. ロケーター⽂法解説 よく使うロケーターその4 - CSSセレクター • 表現⼒はXPathとだいたい同じ • 開発者はこちらのが好き • 詳細は今⽇は割愛

Slide 37

Slide 37 text

1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 38

Slide 38 text

UI⾃動テストでよく⾒る 「要素が⾒つからない」エラーの 解決にチャレンジ! 4. ロケーター実践トラブルシューティング

Slide 39

Slide 39 text

初級編 4. ロケーター実践トラブルシューティング

Slide 40

Slide 40 text

4. ロケーター実践トラブルシューティング ‒ 初級編 クリック(id=OKButton) 昨⽇まで動いていたテスト

Slide 41

Slide 41 text

4. ロケーター実践トラブルシューティング ‒ 初級編 「id=OKButton」の要素が⾒つかりません エラー エラー時の画⾯ いつものように実⾏ クリック(id=OKButton)

Slide 42

Slide 42 text

4. ロケーター実践トラブルシューティング ‒ 初級編 OKボタン あるやん..

Slide 43

Slide 43 text

4. ロケーター実践トラブルシューティング ‒ 初級編 HTMLでOKButtonがあるか確認 要素を右クリックして「検証」 OK HTMLを確認

Slide 44

Slide 44 text

4. ロケーター実践トラブルシューティング ‒ 初級編 OKButtonちゃんとありそうだが.. OK

Slide 45

Slide 45 text

4. ロケーター実践トラブルシューティング ‒ 初級編 OKButtonちゃんとありそうだが.. OK よく⾒るとok が⼩⽂字!

Slide 46

Slide 46 text

4. ロケーター実践トラブルシューティング ‒ 初級編 原因 エンジニアがボタンのidを変更した テスト⼿順も変更 修正 クリック(id=OKButton) クリック(id=okButton)

Slide 47

Slide 47 text

ちなみに 4. ロケーター実践トラブルシューティング ‒ 初級編

Slide 48

Slide 48 text

クリック(id=OKButton) クリック(id=okButton) MagicPodなら このくらいは⾃動で修復します 4. ロケーター実践トラブルシューティング ‒ 初級編

Slide 49

Slide 49 text

上級編 4. ロケーター実践トラブルシューティング

Slide 50

Slide 50 text

4. ロケーター実践トラブルシューティング ‒ 上級編 クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]) 昨⽇まで動いていたテスト

Slide 51

Slide 51 text

4. ロケーター実践トラブルシューティング ‒ 上級編 「xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]」 の要素が⾒つかりません エラー エラー時の画⾯ いつものように実⾏ クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1])

Slide 52

Slide 52 text

4. ロケーター実践トラブルシューティング ‒ 上級編 ちょっと何⾔って るか分かんない..

Slide 53

Slide 53 text

4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈
テスト⾃動化なら
エラー時のHTML

Slide 54

Slide 54 text

4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈
テスト⾃動化なら
エラー時のHTML //div[@id=ʻmain’]

Slide 55

Slide 55 text

4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈
テスト⾃動化なら
エラー時のHTML //div[@id=ʻmain’] //div[@id=ʻmain’]/div[1]

Slide 56

Slide 56 text

4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈
テスト⾃動化なら
エラー時のHTML //div[@id=ʻmain’] //div[@id=ʻmain’]/div[1] //div[@id=ʻmain’]/div[1]/div[1]

Slide 57

Slide 57 text

4. ロケーター実践トラブルシューティング ‒ 上級編 まずは何⾔ってるのか解釈
テスト⾃動化なら
エラー時の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] ??

Slide 58

Slide 58 text

4. ロケーター実践トラブルシューティング ‒ 上級編 たしかに⾒つからないが.. そもそも何を操作したかったのか..

Slide 59

Slide 59 text

4. ロケーター実践トラブルシューティング ‒ 上級編 テストを作った時のHTMLを⾒てみる テスト作成時のHTML

Slide 60

Slide 60 text

4. ロケーター実践トラブルシューティング ‒ 上級編 テストを作った時のHTMLを⾒てみる テスト作成時のHTML //div[@id=ʻmain’]/div[1]/div[1]/a[1] あった!

Slide 61

Slide 61 text

4. ロケーター実践トラブルシューティング ‒ 上級編 画⾯構成に変更がされていた模様 テスト作成時のHTML
テスト⾃動化なら
MagicPod エラー時のHTML

Slide 62

Slide 62 text

4. ロケーター実践トラブルシューティング ‒ 上級編 画⾯構成に変更がされていた模様 テスト作成時のHTML
テスト⾃動化なら
MagicPod エラー時のHTML クリック したかったもの

Slide 63

Slide 63 text

4. ロケーター実践トラブルシューティング ‒ 上級編 変更後の新画⾯でのロケーターは?
テスト⾃動化なら
エラー時のHTML //div[@id=ʻmain’]/div[1]/div[2]/a[1] //a[text()=ʻMagicPod’] or

Slide 64

Slide 64 text

4. ロケーター実践トラブルシューティング ‒ 上級編 原因 エンジニアが画⾯構成を変更した テスト⼿順も変更 修正 クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]) クリック(xpath=//div[@id=ʻmain’]/div[1]/div[2]/a[1])

Slide 65

Slide 65 text

ちなみに 4. ロケーター実践トラブルシューティング ‒ 上級編

Slide 66

Slide 66 text

MagicPodなら これも⾃動で修復します 4. ロケーター実践トラブルシューティング ‒ 上級編 ※ 修復し損ねるケースもあります クリック(xpath=//div[@id=ʻmain’]/div[1]/div[1]/a[1]) クリック(xpath=//a[text()=ʻMagicPod’])

Slide 67

Slide 67 text

1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 68

Slide 68 text

5. ロケーターの使い分け基準 ロケーターはどれを使うのがいいのか? 戻る 次へ xpath=//button[text()=ʻ戻る’] xpath=//button[1] xpath= //form[@id=ʻmain’]/button[1] 全部同じ要素!

Slide 69

Slide 69 text

5. ロケーターの使い分け基準 メンテナンス性が⾼い = 画⾯の変更が⼊っても影響がない 良いロケーター =

Slide 70

Slide 70 text

5. ロケーターの使い分け基準 各種ロケーターのメンテナンス性 を考えてみる

Slide 71

Slide 71 text

5. ロケーターの使い分け基準 システムID、システム名 • 開発者が変更することは少なめ • ReactJSを使った最近のサイトでは、 idは無かったりランダムだったりで使いにくいこと多し … 検索 …

Slide 72

Slide 72 text

5. ロケーターの使い分け基準 テキスト ‒ 良いテキスト • テストデータと関係ない画⾯表⽰テキストは、 変更されることは少なめ • 多⾔語対応のテストをしたい場合は使えない … 検索 …

Slide 73

Slide 73 text

5. ロケーターの使い分け基準 テキスト ‒ 悪いテキスト • テストデータのテキストを ロケーターにベタ書きすると変更に弱くなる • テストケースの共通化の妨げにも …
7,000円 …

Slide 74

Slide 74 text

5. ロケーターの使い分け基準 data-testid属性 • テスト専⽤につけられた、要素を⼀意に識別する属性 • 開発者は極⼒変更しないようにしてくれる(はず) • 無い時は開発チームに依頼してみましょう … 検索 …

Slide 75

Slide 75 text

5. ロケーターの使い分け基準 class属性 • 要素の⽬的‧デザインなどを表す種別 • 多くの場合、要素を⼀意に識別するものではない … 検索 …

Slide 76

Slide 76 text

5. ロケーターの使い分け基準 上からの順番 変更に弱いので、できるだけ避けた⽅がよい … 検索 … xpath=//button[1]

Slide 77

Slide 77 text

5. ロケーターの使い分け基準 要素のパス …
MagicPod
… xpath=//div[@id=ʻmain’]/div[1] 変更に弱いので、できるだけ避けた⽅がよい

Slide 78

Slide 78 text

5. ロケーターの使い分け基準 各テストツールは 何を推奨しているか?

Slide 79

Slide 79 text

5. ロケーターの使い分け基準 Selenium https://www.selenium.dev/documentation/test_practices/encouraged/locators • idを推奨 • ReactJSの無い頃のドキュメントなので、 時代に合っていない気が

Slide 80

Slide 80 text

5. ロケーターの使い分け基準 Cypress https://docs.cypress.io/guides/references/best-practices#Selecting-Elements • data-testid的アプローチを推奨 • id、name、テキストはケースバイケース

Slide 81

Slide 81 text

5. ロケーターの使い分け基準 Playwright https://playwright.bootcss.com/python/docs/selectors#best-practices • UIがあまり変わらない場合は、 テキストなどユーザーに⾒えているもの推奨 • そうでなければdata-testid推奨 • 多⾔語テストが少ない英語圏の発想な気が

Slide 82

Slide 82 text

5. ロケーターの使い分け基準 個⼈的おすすめ まずはdata-testid属性 無理ならidかnameか良いテキスト

Slide 83

Slide 83 text

1. ロケーター概要 2. HTML概要 3. ロケーター⽂法解説 4. ロケーター実践トラブルシューティング 5. ロケーターの使い分け基準 6. XPath & CSSセレクター早⾒表

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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セレクター早⾒表

Slide 86

Slide 86 text

今⽇お話できなかったこと • CSSセレクターの詳細 • モバイルアプリ(Appium)のロケーター • 相対ロケーター(Relative Locator) • 良いロケーターが本当に無い場合

Slide 87

Slide 87 text

MagicPodならロケーターは ⾃動計算&⾃動修復! @MagicPodJP

Slide 88

Slide 88 text

イベント告知

Slide 89

Slide 89 text

Thank you!