infragistics web day 2017 - 継続的な開発を支える テスト自動化技術

Post on 21-Jan-2018

232 Views

Category:

Software

8 Downloads

Preview:

Click to see full reader

TRANSCRIPT

継続的な開発を支えるテスト自動化技術

Dawn Huczek1

自己紹介

・石川達也

・(株)Codeer 代表取締役

・Microsoft MVP

・ささいなことですが(ブログ)

・OSSFriendlySelenium拡張LambdicSql

Visual Studio and Development Technologies

http://ishikawa-tatsuya.hatenablog.com/

https://www.nuget.org/profiles/ishikawa-tatsuya

趣味はギターとライブラリ作成

【Quick Shot】

メソッド単位で確認、デバッグできるVisualStudio拡張https://marketplace.visualstudio.com/items?itemName=ishikawa-tatsuya.Quickshot

【LambdicSql】

SQLをC#で表現するSqlBuilderhttps://github.com/Codeer-Software/LambdicSql

今はこんなのも作ってます。

ご興味あれば、是非ご利用ください。

Windowsアプリを意のままに操作するためのライブラリを作成!

弊社製品FriendlyはMicrosoft MVP Showcaseで2位になりました。http://blogs.msdn.com/b/mvpawardprogram/archive/2014/11/04/mvp-showcase-winners.aspx

IPAの「先進的な設計・検証技術の適用事例報告書 2015年度版」に掲載。http://www.ipa.go.jp/sec/reports/20151118.html

インフラジスティックス様のコントロールにも専用のドライバを作成https://www.nuget.org/packages/Friendly.XamControls/

CodeerではWebアプリ用のテスト自動化もSeleniumを使って支援いたします。

・テスト自動化の必要性

・テスト計画の必要性

・UIを使うテスト

アジェンダ

テスト自動化の必要性

継続的なリリース

リリース時のデグレードが気になりませんか?

常に増えていく機能に対して確認の工数は足りていますか?

1 1 1

2

1

3

1

4

1

5

1

6

2 2

3

2

3

4

2

3

4

5

2

3

4

5

6

開発が進むにつれ、機能は増加し続けます。一度はテストした機能ですがその後大丈夫でしょうか?

気にはなるけど、毎回やり直す工数はないですよ・・・

リリース前でも

1 1 1

2

1

3

1

4

1

5

1

6

2 2

3

2

3

4

2

3

4

5

2

3

4

5

6

この問題に対応するには

1

2

1

3

2

1

4

3

2

1

5

4

3

2

1

人間が実施するテストはいわば使い捨てですが、自動化しておくと、それは蓄積されていきます。そして何度でも実行可能です。

テスト自動化

しかありません!

3

積み上げていくのがポイントです。一気に作るのは大変です。

【テスト工数の削減】

何度も繰り返す必要があるので、当然工数を削減できる。手動なら一回実行するのに300人日は必要なテストをほぼ無料で毎日実行している。不具合修正サイクル時に特に威力を発揮している。

例1) 大規模プロジェクト

お客様の声

【開発工数の削減】

テスト自動化以前実装方法もコード的に最も効率が良いものがあってもリスクとテスト量を減らすことを優先させるために、トリッキーで工数が増えるものを選ぶ必要があった。しかし、自動化されたテストがあれば設計として最善の方法を選択しやすい。また、テストがあるため、プロジェクトの切れ目に大規模なリファクタリングを実施することができるようになり、さらに継続の開発速度を向上させている。

例2)派生開発プロジェクト

【素早いリリース】

開発速度は、自動テストがない時代より向上している。特に緊急リリースで効果を発揮している。以前なら5×5人日は手動のテストが必要だったケースでも自動テストと念のための半日程度の手動の確認でリリース可能な状態に。つまり、手動と比べて24人日は削減できたことになる。それ以上に、素早いリリースは製品を利用するお客様の満足度向上につながっている。

例3) 緊急リリース対応

例4) 3rdパーティ製品のバージョンアップ

某 I 社の製品を使っているのですが、バージョンアップの毎に3人月程度のテストを実施していました。それを自動化できたので、非常に楽になりました。

毎日テストが実行され続ける。そのメリットは膨大です。

・実装時の周辺確認コストの削減・不具合修正コストの削減・リファクタリングが可能になり、次回実装時の工数削減・開発環境更新もスムーズに・緊急リリース時にも余裕の対応・リスク削減により仕様検討時に大胆な判断も可能

良い循環が回り、商品としての競争力もアップ

開発保守のあらゆるフェーズに効果があります。

テスト計画の必要性

費用

効果

・テスト工数削減・コード改善・状態把握・リスク回避

・作製・運用・メンテ

ROIの高いテスト計画が必要です

ROIを上げるには?

人間によるテストと自動テストの違いを理解する

自動テストはプログラムされたことをそのまま実行するだけです。プログラムの必要性があります。指定した操作/確認しかしません。認識力は現時点では人間には現時点では敵いません。

AI使って何とかならないのですか?

なりません。

ランダムに実行させて問題のあるところ見つけてください。

無理っす。

↑最近よく言われる

↑なぜか期待している人が多い

自動テストの手法も複数ある

・内部ロジックのテスト(いわゆる単体テスト)

・UIを使うテスト

単体テスト(非推奨)、結合テスト、UIテスト、システムテスト

アプリを起動し、人間の操作に近い方法で処理を実行する

単体テスト、結合テストXUnitでプロダクトのAPIをテスト

自動化ツール買ってきたら、それでいいでしょう? よくないっす。

・WebAPIをテスト

統合テスト最近はここを充実させる場合も多い

Test Automation Pyramid

UI

Integration

Unit

基本はこれ

効果が最大になるように組み合わせることが重要

DB操作、ビジネスロジックを自動単体テスト

重要度の高い部分、探索的なテストはやっぱり人のテストも必要

重要なWebAPIは重点的に確認

判断の基準として、自動化の難易度も重要となります。

画面操作でもこのあたりはUI自動テストだけで十分

ポイント 自動テストは自動であるべき

・前後処理、確認も自動にする

・確実に動作するもののみにする信頼性が低いと使い物にならない

確認とか余計な工数が出るならおいそれと実行できないよ・・・

UIを使うテスト

エミュレート方式とAPI方式がある

人間の操作に近いことキーマウスをドライバレベルでエミュレート

Application Programming Interfaceプログラムから使われることを目的としている。確実、高速な動作。テスト自動化と相性が良い。最近流行り?のRPAもこちらを推奨。

エミュレート方式

万能ではあるが問題も多い

ここが困難

タイミング

App OS Test

重い処理

テストとしては

複数個処理を投げ込んだけど、どこまで進んでるかわからない

保守性の高い記述が難しい

例えば365個目までスクロールしてそれをクリックとかほんのちょっとの変化で使えなくなるよね?

API方式

プログラムから扱いやすいインターフェイスを公開。タイミング依存の問題が起こりにくいので、運用コストを下げることができる。反面、人間の操作とは完全には一致しない。

App OS

処理 基本的には同期がとれる

var item = list.GetItem(365);Item.Click();

保守性の高いテストが記述できる

WebではSeleniumがお勧めです。

・API方式(確実な動作)

・無料C#ではNugetから取得できます。

・情報が豊富OSSであるためコミュニティ活動が盛んです。

・マルチブラウザ対応ヘッドレスブラウザもあります。

・マルチ言語対応Java、C#、Python、Ruby、JavaScript

もはやデファクトスタンダード

Seleniumを使う上でのポイント

・要素の特定

・基本操作

・注意点

要素特定

テスタビリティ向上のためにIDをつけよう!

特定方法によって、作成工数、メンテナンス工数が変わると言っても過言ではない!

public static By Id(string idToFind);public static By Name(string nameToFind);

public static By ClassName(string classNameToFind);public static By CssSelector(string cssSelectorToFind);public static By LinkText(string linkTextToFind);public static By PartialLinkText(string partialLinkTextToFind);public static By TagName(string tagNameToFind);public static By XPath(string xpathToFind);

ページオブジェクト

要素特定処理、及びコードを知らないと書けない処理はPageObjectパターンを使って特定のクラスにまとめます。

public class RadioPage{

IWebDriver _driver;

public RadioPage(IWebDriver driver)=> _driver = driver;

public void GoToPage()=> _driver.Url = "https://www....";

public IWebElement SwitchWifi=> _driver.FindElements(By.TagName("igx-switch"))[0];

}

要素特定は属性で書く手法もある

セレニウムは全部APIです。Click、SendKeysが存在しますが、ブラウザ内部であくまで仮想的に実行するものです。

基本操作

Click

var firstName = frameDriver.FindElement(By.Name("firstName"));firstName.Clear();firstName.SendKeys("Tatsuya");

var button = frameDriver.FindElements(By.TagName("igx-switch"))[0];button.Click();

SendKeys

便利な操作

Action

var scrollDown = new Actions(driver).MoveToElement(scroll, 1, scroll.Size.Height - 1).Click().Build();

scrollDown.Perform();

//操作を合成 スクロールバーの下部に移動してクリック

new Actions(driver).DoubleClick(element).Build().Perform();

//単なるダブルクリックでもこれを使う必要がある

new Actions(driver).KeyDown(element, Keys.Alt).Click(element).KeyUp(element, Keys.Alt).

Build().Perform();

//ALTキー押しながらクリック

JavaScript実行

var js = driver as IJavaScriptExecutor;js.ExecuteScript("arguments[0].scrollIntoView(false);", element);

//要素を画面の可視領域に入れる//引数で渡したのものはargumentsという変数に入る

var target = js.ExecuteScript("return _target;") as IWebElement;

//ロケータで取りにくいDOM要素をJavaScriptで取得//object型で返るので、返すものの種類に応じてキャスト

データの受け渡しができるので便利

同期

最重要実装ポイントここを確実に抑えておかないと不安定なテストになり、運用コストが激増する

タイミングによっては失敗するとか不具合なのか、テストが悪いのかわからない・・・

e.Click();var e2 = driver.Find();

あれ?今日に限って、クリックの後にの要素取得に失敗する・・・

同期

・JavaScriptでの操作中は待ってくれる。ただし、ダイアログが表示されると待機が終了する。

・別URLへ遷移→念のため、次の画面で欲しい要素が出るまで待った方が無難。

・非同期処理→目的の状態になるまで明示的に待つこと。

<script type="text/javascript">function ExecuteButton() {

//ここは待ってるvar start = new Date();while (new Date().getTime() - start.getTime() < 5000);

//ダイアログは待たないalert("1");

}</script><input id="_button" type="button" value="Wait"onclick=“executeButton()" />

複数のブラウザに対応しているとは言え

ブラウザごとにクセがある。(IEが特に)その場合は、ページオブジェクトやドライバレイヤで吸収する。

public void ScrollDown(){

//この画面では、IEDriverServerが落ちる場合があるので、COMとSendKeysを駆使するif (driver is InternetExplorerDriver){

driver.IEActivate();System.Windows.Forms.SendKeys.SendWait("+ ");Enumerable.Range(0, 10).ToList().

ForEach(e => System.Windows.Forms.SendKeys.SendWait(" "));//これも拡張メソッド//このアプリではブラウザによってBusy終了の待ち方法が異なるdriver.AdjustBrowserWaitForBusyEnd();

}else{

//その他のブラウザはスクロールバークリックでOKvar scrollDown = new Actions(driver).

MoveToElement(scroll, 1, scroll.Size.Height - 1).Click().Build();scrollDown.Perform();

}}

まとめ

・高頻度なリリースが求められる現在では、テスト自動化は必須

・成果を出すためには、テスト計画、設計が必要

・WebのUIテストにはSeleniumがお勧め情報が豊富なので、プロジェクトに応じた言語でスキルを上げておこう。

top related