31
Pitalium を使って 回帰テストを実践した時の話 Naoya Kojima 2016/12/28

20161222 selenium adventcalender

Embed Size (px)

Citation preview

Pitalium を使って回帰テストを実践した時の話

Naoya Kojima

2016/12/28

話の流れ

はじめに

使用するツールを理解する為に採用したアプローチ

OOAD

ICONIX

Pitalium について理解を深める

目的から読み解くPitalium の機能

機能から読み解くPitalium のユースケース

ユースケースから読み解くPitalium の主要コンポーネント

Pitalium を利用する

実施するテスト目的の決定

テスト実施手順の決定

テスト実施手順のアーキテクチャ化

テスト実施手順のアーキテクチャ

まとめ

はじめに

本スライドについて

主に画像比較やマルチブラウザ上でのテスト実行機能を提供するテスト支援ツールPitalium を利用して、画像比較テストを追加した時の経験を整理したものです

使用するツールを理解する為に採用したアプローチ

Object-Oriented Analysis and Design

Abstract OOAD Structure

Requests

Application

Architecture

Components

Object Object Object Object

Analysis

Design

Object

Roles

Responsibilities

Task Info

has

Roles

The ICONIX

Practical Method of OOAD

Quote from 「Use Case Driven Object Modeling with UML Theory and Practice」Doug Rosenberg, others.

Abstraction of ICONIX

ICONIX自体はOOADよりも広い範囲をサポートする開発手法

静的+動的なワークフローが構成するイテレーティブなプロセス

1イテレーションでは、ユースケースまたはその論理的な集合に対して、要求分析〜単体テストをスコープとする実践的な手法

イテレーティブな為、agileプラクティスとの親和性が高い

UP(統一プロセス)よりも使用するUMLやドキュメントの種類が少なく、軽量である

他の手法との折衷案を採用してもよい(私見)

マイルストーンと確認ポイントが示されているので分かりやすい

The ICONIX

Practical Method of OOAD 2

Abstraction of ICONIX Process (One Iteration)

要求定義 機能要求 振る舞い要求ドメイン分析

ドメインモデリングレビュー

要求分析

予備設計

ロバストネス分析属性追加(ドメイン

モデルの更新)

コントローラオブ

ジェクトの識別レビュー

詳細設計 シーケンス図作成操作の追加(ドメイ

ンモデルの更新)シーケンス図の更新 レビュー

実装コーディング

ユニットテスト実施

統合テスト、テスト

シナリオの実施コードレビュー 各モデルの更新

To Next

Iteration

Pitalium について理解を深める

目的から読み解くPitalium の機能

目的(=ビジネス要求)

hifive Webサイトより

「Selenium WebDriver を利用したテストを各ブラウザで並列実行し、スクリーンショットを取得して想定結果と画像比較をする」

出展:https://www.htmlhifive.com/conts/web/view/pitalium/

目的達成に必要な機能

ビジネス要求から導いた機能要求

Selenium WebDriverを利用したテストを実行する必要がある

テスト実装者が指定するブラウザでテストを実行する必要がある

テストを並列実行する必要がある

スクリーンショットを取得し、実行結果として想定結果と比較する必要がある

テスト実行完了時に、テスト結果を報告する必要がある

機能から読み解くPitalium のユースケース

Selenium WebDriverを利用したテストを実行する必要がある

ユースケース

pitalium-1.1.1.jarは、JUnitのラッパーテストクラスPtlTestBase を提供する

テスト実装者は、selenium-java-2.53.1.jarを使ってラッパーテストクラスPtlTestBaseを継承したテストクラスを実装する

Javaスレッド@JVMは、テストクラスを実行する

テスト実装者が指定するブラウザでテストを実行する必要がある

ユースケース

pitalium-1.1.1.jarは、インスタンス化するWebDriverのcapabilityを指定するファイルとそれをロードするPtlCapabilitiesクラスを提供する

pitalium-1.1.1.jarは、PtlBlockJUnit4ClassRunnerWithParametersFactoryクラスを使ってカスタムStatementを実行するPtlBlockJUnit4ClassRunnerWithParametersカスタムランナーを生成する

テスト実装者は、capabilitiesファイルに実行するブラウザのcapabilityを記述する

Javaスレッド@JVMは、テストクラスを実行する

PtlBlockJUnit4ClassRunnerWithParametersランナーの生成時に、PtlCapabilitiesクラスを使ってcapabilityファイルをロードする

テストメソッド実行前に、AssertionViewメソッドルールを利用してcapability毎にWebDriverインスタンスを生成する

テストクラス実行後に、カスタムクラスルールParameterizedClassRuleでPtlWebDriverCloserを利用して、生成したWebDriverインスタンスをcapability 毎に削除する

テストを並列実行する必要がある

ユースケース

pitalium-1.1.1.jarは、ParameterizedThreadsカスタムランナーを提供する

ParameterizedThreadsクラスは、テストメソッド(マルチスレッドの場合はタスク)の実行順を制御するRunnerSchedulerインタフェースを実装するMultiThreadRunnerSchedulerクラスを提供する

テスト実装者は、capabilitiesファイルに並列実行したいブラウザのcapability を記述する

Javaスレッド@JVMは、テストクラスを実行する

ランナー生成時に、MultiThreadRunnerSchedulerクラス内でExecutorServiceを利用してRunnable なStatement タスク(=テストメソッド群)をマルチスレッド実行用のブロッキングキューに登録して、マルチスレッドで実行出来るようにする

スクリーンショットを取得し、実行結果として想定結果と比較する必要がある

ユースケース

pitalium-1.1.1.jarは、メソッドルールとしてAssertionViewクラスを提供する

テスト実装者は、AssertionViewクラスのverifyViewメソッドを利用してスクリーンショットの取得箇所をコーディングする

テスト実行者は、ExecModeを利用して、テストの実行を「想定結果の取得」、または「テストの実行」、を指定する

Javaスレッド@JVMは、テストクラスを実行する

テストメソッド実行前に、AssertionViewクラスを利用してWebDriverインスタンスを生成する

ExecMode#SET_EXPECTEDの場合

verifyViewメソッド実行時に、スクリーンショットを取得して想定結果として保存する

ExecMode#RUN_TESTの場合

verifyViewメソッド実行時に、スクリーンショットを取得してテスト結果として保存する

テスト結果と想定結果を比較する

テスト実行完了時に、テスト結果を報告する必要がある

ユースケース

pitalium-1.1.1.jarは、クラスルールとしてResultCollectorクラスを提供する

Javaスレッド@JVMは、テストクラスを実行する

テストクラスの実行時に、ResultCollectorクラスはTestResultManagerクラスを利用して、テストの状態(succeeded、failed、finished)に応じて、想定結果の更新、想定結果の更新のキャンセル、テスト結果の出力/テスト想定結果の出力を行う

ユースケースから読み解くPitalium

の主要コンポーネント「Pitalium のユースケース」から必要なコンポーネントを導出する

com.htmlhifive.pitalium.core

coreパッケージ

Pitaliumの機能を利用する為のAPIを公開しているコンポーネント

PtlTestBaseクラス

テスト実装者が、 Pitalium の提供する機能をテストクラスで利用する為の抽象テストクラス

ParameterizedThreadsクラス

テストメソッド並列実行役も担えるよう拡張されたParameterizedランナークラス

MultiThreadRunnerSchedulerクラス

ExecutorServiceを使い、テストメソッドを並列実行する役割を担うインナークラス

com.htmlhifive.pitalium.core.rules

rulesパッケージ

Pitaliumを利用した画像比較テストにまつわる処理を意図したタイミングで隠蔽して提供する為のコンポーネント

AssertionViewクラス

想定結果との画像比較に必要なAPI を公開するクラス。

Selenium コンポーネントのPtlWebDriverManagerを利用してWebDriverオブジェクトの生成も担う。

ResultCollectorクラス

テスト結果を収集/出力する責務を持つTestResultManagerを生成するクラス。

PtlWebDriverCloserクラス

WebDriverオブジェクトのセッションを終了するクラス。

com.htmlhifive.pitalium.core.result

resultパッケージ

テスト結果を記録するコンポーネント。実体はTestResultManagerクラス。

TestResultManagerクラス

テスト結果を収集/エクスポート する責務を持つクラス。

com.htmlhifive.pitalium.core.selenium

seleniumパッケージ

Selenium WebDriverの機能(WebDriver 、スクリーンショットの取得等)を拡張して提供するコンポーネント

PtlCapabilitiesクラス

JSONUtilsを使いcapabilities.jsonからcapabilityをロード、保持する責務を持つクラス。

com.htmlhifive.pitalium.junit

junitパッケージ

JUnitのParameterizedを利用してテストの実行内容を拡張するコンポーネント

PtlBlockJUnit4ClassRunnerWithParametersFactory

PtlBlockJUnit4ClassRunnerWithParametersを生成するクラス

ParameterizedランナーのUseParametersRunnerFactoryアノテーションのvalueに指定する

PtlBlockJUnit4ClassRunnerWithParameters

ParameterizedThreadsランナーによってパラメータ毎に実際にインスタンス化されるランナー。

Parameterizedランナーが実体化するBlockJUnit4ClassRunnerWithParametersランナーの拡張版。

BlockJUnit4ClassRunnerWithParametersのStatementを拡張してParameterizedClassRuleを実行可能とした。

Pitalium を理解するーまとめ

ユースケースから読み解くPitalium の主要コンポーネント

自動テストの詳細設計者、テスト実装者がPitalium を利用する上で抑えておくと良いコンポーネントです

こららはテスト実装者とテストコードとのインタフェース役を担い、そのロールを構成する責務はその他コンポーネントに委譲しています。

その他コンポーネントについて

Pitalium には、主要コンポーネントの他にも多くのコンポーネントがあります。

これらはオブジェクト指向で設計されており、個々が主要コンポーネントから責務を委譲される形で存在しています。

まとめ

Pitalium を使い、自動テストシステムを開発・拡張する際には、この二点を抑えておくと良いでしょう

Pitalium を利用するユースケーステストの自動化に利用する場合

実施するテスト目的の決定

Pitaliumを利用するテストシステム自体のテスト目的

ユースケーステストを実行する

テストの実行結果が想定する振る舞いと違いないかを検証する

実装例

JUnit4.X系のorg.junit.assertパッケージassertThatメソッドを使う

Pitalium を使う目的

テストシステムの設計で意図した機能を委譲する為に利用する

委譲する機能の例

テストを並列実行する

テスト実行前後の証跡を取得する

テスト失敗時の原因究明の手掛かりとしてスクリーンショットを取得する

画面レイアウトの回帰テストを実行する

直近でテストが成功した時の 画面に意図しない変更が加えられていないことを確認する

テスト実装手順の決定

複数存在するテストシステムの目的

ユースケースの検証

画面レイアウトの検証

テストの実装手順を決定する

テスト実装者が実装時に確実に上記目的を果たすテストを実装する構造にする為、テスト実装時には必ず次の手順を踏襲する

ユースケーステストの実行/検証ユースケーステスト実行前後の証

跡を取得取得した画面レイアウトの比較

テスト実装手順のアーキテクチャ化

テスト実装者が実装手順を意識しなくても済むようにする

アスペクト指向の採用

実装するテストメソッド内にPointCutを作成する

「ユースケーステスト実行前後の証跡取得」、「取得した画面レイアウトの比較」をAdviceとして実装する

Adviceが指定するJoinPointでWeaveされるようにする

テンプレートメソッドパターンの採用

PointCutを必ず実装させる為に、PointCutとするメソッドを差し込んだテンプレートメソッドを実装する

PtlTestBaseクラスを継承するテンプレートメソッドを実装するラッパー抽象クラスを実装する

ユースケーステストの実行/検証ユースケーステスト実行前後の証

跡を取得取得した画面レイアウトの比較

Advice化

テスト実装手順のアーキテクチャ

@Aspect Class TestImplProcess

@Pointcut("execution(public * WrapperPtlTestBase.abstructMethod(..)) && !within(TestImplProcess)")

abstructMethodExecute()

@Before("abstructMethodExecute()") beforeAbstructMethod()

@After("abstructMethodExecute()") afterAbstructMethod()

1. ユースケーステストの証跡取得

2. 取得した画面レイアウトの比較

Abstruct Class WrapperPtlTestBase extends PtlTestBase

@Test TestMethod()

1. abstructMethod()

JoinPoint

Advice

PointCut

テスト実装者はWrapperPtlTestBaseを継承したクラスでabstructMethod()内にユースケーステストを実装すると、意識せずに「証跡取得」、「画面比較」を実装できるようになる。

アーキテクチャ補足

Advice内でPitaliumのAssertViewクラスを利用して「ユースケーステストの証跡取得」、「取得した画面レイアウトの比較」を実装する。

abstructMethod()の実行前後にAdviceをWeaveするだけであり、ユースケーステストの実行前後でしか「ユースケーステストの証跡取得」、「取得した画面レイアウトの比較」ができない。より細かくスクリーンショットを取得する場合は、別途実現方法を検討する必要がある。

抽象テストメソッドを実装するアーキテクチャとした為、1テストメソッド=1テストクラスとなる。よって、1テストクラス=1ユースケースとしてテストコードを実装することを前提としている。

1ユースケーステストで様々なデータパターンでテストを実行する場合は、Parameterizedランナーを使用することを前提としている。

まとめ

本経験を通して学んだこと

適用シーンを明確にする為にも、ツールが想定するユースケースを理解するとよい

ツールありきにならない為にも、要求を明確にしてロールの委譲可否を明確にしておくとよい