Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LatteArtによるテストログの記録と それを用いたメンテナンス性の高い テストスクリプト生...

SHIFT EVOLVE
September 01, 2023

LatteArtによるテストログの記録と それを用いたメンテナンス性の高い テストスクリプト生成技術の紹介

2023/08/30(水)
三社三様!テスト自動化アプローチのあれこれ共有会
イベント登壇資料
切貫 弘之氏(NTT ソフトウェアイノベーションセンタ 准特別研究員)

SHIFT EVOLVE

September 01, 2023
Tweet

More Decks by SHIFT EVOLVE

Other Decks in Technology

Transcript

  1. 2 Copyright 2023 NTT CORPORATION 自己紹介 所属: NTT ソフトウェアイノベーションセンタ 名前:

    切貫 弘之 業務内容: ソフトウェアテストを主な対象として ソフトウェア開発支援技術の研究開発 最近はLLMのソフトウェア開発への応用も
  2. 3 Copyright 2023 NTT CORPORATION 発表の概要 従来 • 保守性の高いEnd-to-Endテストスクリプトを実装するのは大変 •

    Selenium IDE等のCapture & Replayツールを使うとテストスクリプトの保守性が低くなる • 自動テストとは別に探索的テストやユーザビリティテストを含む手動テストは必要 提案 • 自社で開発中のOSS(LatteArt)で手動テストを記録 • 記録したテストのログを用いることで、ページオブジェクトとテストケースを 含むテストスクリプトの雛形を自動生成 ▶ テスト自動化を意識せずとも、手動テストをやれば副次的に自動テストの準備もできる ソフトウェアテストを支援する技術創出の取り組みについて紹介
  3. 4 Copyright 2023 NTT CORPORATION End-to-Endテスト自動化のアプローチ Capture & Replay プログラミング

    ブラウザ上で行った操作をスクリプトとして記録し、 そのスクリプトを実行することで次回以降の動作検証を自動化 (例: Selenium IDE) Webブラウザを操作するライブラリを用いて、テスト手順をプログラムとして実装する (例: Selenium Webdriver, Cypress) プログラムの知識不要で、素早くテストスクリプトを作成できる テストスクリプト間でロケータや手順が重複してしまうため、保守性が低い ページオブジェクトパターン等を用いてテストスクリプトを構造化できるため、保守しやすい テスト自動化の知見のあるプログラマが工数をかけて実装する必要がある(つまらない)
  4. 5 Copyright 2023 NTT CORPORATION Capture & Replay vs. プログラミング

    Leotta, M., Clerissi, D., Ricca, F. and Tonella, P.: Capture-Replay vs. Programmable Web Testing: An Empirical Assessment during Test Case Evolution, 20th Working Conference on Reverse Engineering, pp. 272– 281 (2013) 6つ中5つのOSSでは3回以上リリースする場合、実装と保守の合計コストの面で ページオブジェクトを用いたプログラミングによる実装の方が優れていた 既存研究: 6つのOSSに対してCapture & Replayとプログラミングによる手法をそれぞれ 用いた場合のテストスクリプトの実装・保守コストを計測し比較
  5. 6 Copyright 2023 NTT CORPORATION class オーナー追加ページ { get firstname()

    { return $('#firstName'); } get lastname() { return $('#lastName'); } get address() { return $('#address'); } get city() { return $('#city'); } get telephone() { return $('#telephone'); } get addOwner() { return $('/HTML/BODY/DIV/DIV/FORM/DIV[2]/DIV/BUTTON'); } async addOwnerFunc({ firstname, lastname, address, city, telephone }) { await this.firstname.setValue(firstname); await this.lastname.setValue(lastname); await this.address.setValue(address); await this.city.setValue(city); await this.telephone.setValue(telephone); await this.addOwner.click(); return new オーナーページ(); } } ページオブジェクトパターン • テスト対象の各画面をオブジェクト指向プログラミングにおけるオブジェクトとして表現 • テストケースと各ページの構造を切り離すことでテストスクリプトの保守性を向上できる ページオブジェクト 要素 → アクセサ 機能 → メソッド 入力フォーム First Name Last Name Address City Telephone Add Owner リンク HOME FIND OWNERS VETERINARIANS ERROR ボタン 利用 要素 機能 HOMEに遷移 FIND OWNERSに遷移 VETERINARIANSに遷移 ERRORに遷移 オーナーを追加 コードでの表現
  6. 7 Copyright 2023 NTT CORPORATION テスト自動化の課題 ▶ 実装の容易さと保守の容易さを両立したい 手法 実装の容易さ

    保守の容易さ 代表ツール Capture & Replay ◦ ✕ Selenium IDE プログラミング ✕ ◦ Selenium Webdriver アプローチ: 手動テストを記録し、その情報を用いてテストスクリプトを生成する
  7. 8 Copyright 2023 NTT CORPORATION 手動テストを記録する • 自社で開発中のOSSを使う(https://github.com/latteart-org/latteart) • 主目的は、探索的テストを記録・可視化・管理し、テストの振り返り

    を容易にすることで知見を発散させず、テストをより良くすること • 蓄積したテストログをテスト自動化にも活用したい! 操作ごとに取得する情報 • ページ情報 • タイトル • URL • 操作情報 • 操作種類(input, click) • 入力値 • 操作対象 etc.
  8. 9 Copyright 2023 NTT CORPORATION 提案手法|ページオブジェクトの生成 (1/2) 画面ごとにページオブジェクトを生成する ▶ 画面はタイトルもしくはURLで区別(LatteArtの機能により正規表現も利用可能)

    get firstName() { return $('#firstName'); } アクセサ 識別子名はid, name, textから生成 ロケータ id, name, text, XPath の順に優先 テスターが1つの画面で行った一連の操作(操作列)を画面の機能の利用とみなし、メソッドとして生成する ▶ 画面の構造に依存せず、意味のある操作をメソッド化しやすい アクセサ(Web要素)の生成 メソッド(機能の利用)の生成
  9. 10 Copyright 2023 NTT CORPORATION 提案手法|ページオブジェクトの生成 (2/2) 操作列をすべてメソッド化すると、類似したメソッドが生成されてしまう ▶ 別の操作列に包含される操作列はメソッド化しない

    遷移先が同じ かつ 各操作の操作対象の列が部分列になっている 例: 𝑒1~4を操作対象のWeb要素とすると、 [𝑒1 , 𝑒2 , 𝑒3 , 𝑒4 ]という順番の操作が他にあれば、 [𝑒1 , 𝑒2 , 𝑒4 ]はその部分列なのでメソッド化しない addOwnerFunc(firstName, lastName, address, city, telephone) { this.firstName.setValue(firstName); this.lastName.setValue(lastName); ... this.addOwner.click(); return new オーナーページ(); } メソッド 遷移先ページオブジェクト 識別子名は最後に呼び出す アクセサ名や遷移先ページ を元に生成 メソッドチェーンでテストケースを記述できる アクセサ 操作内容 =
  10. 11 Copyright 2023 NTT CORPORATION 提案手法|テストケースの生成 (1/2) • ページオブジェクトで定義されたメソッドを組み合わせる •

    開発者がカスタマイズすることを前提として、テスト対象の主要なユースケース を含んだ汎用性の高いテストケースを生成したい テストログから復元した画面遷移図を探索し、 以下の条件を満たすテストケース群を生成 • テストケース群が画面遷移を網羅する • 1つのテストケースで同じ画面に2度訪れた場合、 それ以降の画面遷移を行わない • 他のテストケースで確認された画面遷移は 可能であれば省略する あるテストケースの画面遷移(全7ケース)
  11. 12 Copyright 2023 NTT CORPORATION 提案手法|テストケースの生成 (2/2) it('sample', async ()

    => { await new トップページ() .gotoオーナー検索ページ() .then((page) => page.gotoオーナー追加ページ()) .then((page) => page.addOwnerFunc({ firstname: '田中', lastname: '太郎', address: '千代田区', city: '東京', telephone: '1234567890' })) .then((page) => page.gotoペット追加ページ()) .then((page) => page.addPetFunc({ name: 'pochi', birthdate: '2023-08-02', type: 'dog' })); }); async addOwnerFunc({ firstname, lastname, address, city, telephone }) { await this.firstname.setValue(firstname); await this.lastname.setValue(lastname); await this.address.setValue(address); await this.city.setValue(city); await this.telephone.setValue(telephone); await this.addOwner.click(); return new オーナーページ(); } • 入力値はテスターが実際に入力 したものを利用 • 入力値を外部ファイルから入れ るデータ駆動テストにも対応 テストケース オーナー追加メソッド
  12. 14 Copyright 2023 NTT CORPORATION 制限事項 • 生成したテストスクリプトがそのまま実行できることを保証しない • テスターの操作をツギハギしてテストケースを構築している

    • テスト対象の内部状態を考慮していない • 手動テストで操作されていない要素はページオブジェクトに現れない • 自動テストで操作したくない要素もあるので一長一短 • アサーションは自動生成されない • 想定したページ遷移が行われたかを検証するアサーションは自動生成できそう • それ以上の高度なアサーション生成は今後の課題 • プログラムの知識は必要 • 今後保守していくことを考えて、プログラムの柔軟性の高さを重視 • 現状、WebdriverIOで実行できるJavaScript形式のテストスクリプトのみ対応
  13. 15 Copyright 2023 NTT CORPORATION より詳しく テストスクリプト生成機能はLatteArtに実装されているので、興味がある方はお試しください。 (バグはあります) 生成スクリプトをコピペするだけで実行できる環境も用意しています。 ▶

    https://github.com/latteart-org/test_script_runner テストスクリプト生成技術に関する論文: • 切貫 弘之, 丹野 治門: “手動テストのログを用いた有用な End-to-End テストスクリプトの自動生成”, ソフトウェアエンジニアリングシンポジウム 2020 • Hiroyuki Kirinuki and Haruto Tanno: “Automating End-to-End Web Testing via Manual Testing”, Journal of Information Processing, Vol. 30, pp. 294-306, 2022. テストの記録に用いたLatteArtに関する論文: Hiroyuki Kirinuki, Masaki Tajima, and Haruto Tanno: “LatteArt: A Platform for Captureing and Analyzing Exploratory Testing”, The 16th IEEE International Conference on Software Testing, Verification and Validation (ICST2023).
  14. 18 Copyright 2023 NTT CORPORATION 実装 driver.findElementMulti({ "id": "username_broken" },

    { "name": "username" }) • JavaScriptのProxy(リフレクション的なもの)を用いて関数の動作を変更 • findElement系関数のスタックトレースを取得し、呼び出し箇所を構文解析 • テスト実行中の画面から必要な情報を収集、修正結果ファイルを生成 • 修正履歴を記録することで、頑健性が高い順にロケータの優先度を決定 LoginTest.js, line:15, col: 22 -- 40 locator type: id locator value: username_broken 1つでもマッチすればOK 修正できる