osc京都 2015 lt 「テスト自動化の闇と向き合う」

Post on 18-Jan-2017

1.017 Views

Category:

Technology

6 Downloads

Preview:

Click to see full reader

TRANSCRIPT

テスト自動化の闇と向き合う新日鉄住金ソリューションズ

石川 真也

(Selenium歴 9ヶ月)

Copyright © 2015 NS Solutions Corporation, All rights reserved. 1

ブラウザテスト

Copyright © 2015 NS Solutions Corporation, All rights reserved. 2

Copyright © 2015 NS Solutions Corporation, All rights reserved. 3

Internet Explorer 7

Internet Explorer 8

Internet Explorer 9

Internet Explorer 10

Internet Explorer 11

Microsoft Edge

Firefox

Google Chrome

Safari

Safari(iOS)

Google Chrome(Android)

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

・アプリにアクセス・ログイン・カートに商品を追加・配送先を選択・支払い方法を選択・注文の確認・購入完了

自動化したい

テスト自動化

Copyright © 2015 NS Solutions Corporation, All rights reserved. 4

Copyright © 2015 NS Solutions Corporation, All rights reserved. 5

Selenium

Selenium-特徴

OSS(Apache2.0)

様々なブラウザに対応

豊富な言語バインディング Java, C#, Python, Ruby, JavaScript etc.

豊富な支援ツール Selenium grid:並列実行

Selenium IDE:画面操作の記録

Appium:iOS, Androidのテスト

Microsoft Edgeにも!

Copyright © 2015 NS Solutions Corporation, All rights reserved. 6

→間口の広さ

Selenium-コード例public class Example {

public static void main(String[] args) {

WebDriver driver = new HtmlUnitDriver();

driver.get("http://www.google.com");

WebElement element = driver.findElement(By.name("q"));

element.sendKeys("Cheese!");

element.submit();

System.out.println("Page title is: " + driver.getTitle());

driver.quit();

}

}

フォーム操作

ページリクエスト

値の取得

Copyright © 2015 NS Solutions Corporation, All rights reserved. 7

テスト自動化の闇

Copyright © 2015 NS Solutions Corporation, All rights reserved. 8

の闇スクリプト保守

Copyright © 2015 NS Solutions Corporation, All rights reserved. 9

Selenium IDEを使えば

ブラウザ操作を記録できて便利!

Copyright © 2015 NS Solutions Corporation, All rights reserved. 10

どんどんテストスクリプトを

作ろう!

Copyright © 2015 NS Solutions Corporation, All rights reserved. 11

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController

driver.findElement(By._id")).clear();

driver.findElement(By._id")).sendKeys("01");

driver.findElement(By.MenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle

Copyright © 2015 NS Solutions Corporation, All rights reserved. 12

「ここのフォームの配置

変えといたから」

Copyright © 2015 NS Solutions Corporation, All rights reserved. 13

えっ

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController

driver.findElement(By._id")).clear();

driver.findElement(By._id")).sendKeys("01");

driver.findElement(By.MenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle

Copyright © 2015 NS Solutions Corporation, All rights reserved. 14

Selenium IDEが吐くコードの例WebElement element = driver.findElement(

By.cssSelector("#content > table > tbody > tr:nth-child(4) > td:nth-child(2)“));

↑Idがcontentの要素の中の↑table要素の中の

↑tbody要素の中の↑4番めのtr要素の中の

↑2番めのtd要素

Copyright © 2015 NS Solutions Corporation, All rights reserved. 15

DOM要素の配置が変わると台無し

DOMツリー上の位置で操作する要素を特定

えっこれ全部修正ですか?

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

driver.get(baseUrl + "/myVideoRental/FrontController

driver.findElement(By._id")).clear();

driver.findElement(By._id")).sendKeys("01");

driver.findElement(By.MenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle

Copyright © 2015 NS Solutions Corporation, All rights reserved. 16

orz

Copyright © 2015 NS Solutions Corporation, All rights reserved. 17

スクリプト保守の闇と向き合う

• テストを意識した設計• 要素のクラス、id体系

• テストスクリプトで工夫• PageObjectパターン• ページごとの操作を抽象化

Copyright © 2015 NS Solutions Corporation, All rights reserved. 18

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

Copyright © 2015 NS Solutions Corporation, All rights reserved. 19

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

LoginPage.class

void login(user, passwd)void logout()boolean isLoggedIn()

PageObjectパターン

の闇「たまに失敗」

Copyright © 2015 NS Solutions Corporation, All rights reserved. 20

スクリプトも完成したし、今やこのテストは完全に

自動化された!

Copyright © 2015 NS Solutions Corporation, All rights reserved. 21

ほらね、ちゃんと動いてる!driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

Copyright © 2015 NS Solutions Corporation, All rights reserved. 22

あれ、このテスト…

たまに失敗してる…?driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

driver.findElement(By.id("DisplayMenuLogic")).click();

assertEquals("貸出・返却メニュー画面", driver.getTitle());

Copyright © 2015 NS Solutions Corporation, All rights reserved. 23

Copyright © 2015 NS Solutions Corporation, All rights reserved. 24

たまに失敗するのはなぜ?

• クリックしようとした要素が不可視状態だった

• ネットワークが遅くてタイムアウト

• ブラウザのキャッシュがのこっていた

• DBの状態がかわっていた

• 信仰心がたりない

• etc. etc. etc.

Copyright © 2015 NS Solutions Corporation, All rights reserved. 25

「このテストが失敗するのはよくあることだから大丈夫」

Copyright © 2015 NS Solutions Corporation, All rights reserved. 26

driver.get(baseUrl + "/myVideoRental/FrontController");

driver.findElement(By.name("shop_id")).clear();

driver.findElement(By.name("shop_id")).sendKeys("01");

(大丈夫じゃない)

orz

Copyright © 2015 NS Solutions Corporation, All rights reserved. 27

たまに失敗の闇と向き合う

• 同じ条件ならいつでも失敗 or いつでも成功するテストがよいテスト!

• 事前条件をそろえる• AP, DB, ブラウザ状態の初期化

• 適切にwaitする• PageObjectパターンとの組み合わせも◎

Copyright © 2015 NS Solutions Corporation, All rights reserved. 28

の闇ブラウザ依存

Copyright © 2015 NS Solutions Corporation, All rights reserved. 29

ページのレイアウト崩れが無いか

確認したい…

Copyright © 2015 NS Solutions Corporation, All rights reserved. 30

スクリーンショットを撮ろう!

Copyright © 2015 NS Solutions Corporation, All rights reserved. 31

File screenshotFile = ((Screenshot)driver).getScreenshotAs(file);

Copyright © 2015 NS Solutions Corporation, All rights reserved. 32

可視範囲のみ

いろんなバー映り込む

Copyright © 2015 NS Solutions Corporation, All rights reserved. 33

Internet Explorer Google Chrome Safari(iOS)

TakesScreenshot interfaceFor WebDriver extending TakesScreenshot, this makes a best effort depending on the browser to return the following in order of preference:

• Entire page

• Current window

• Visible portion of the current frame

• The screenshot of the entire display containing the browser

http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/TakesScreenshot.htmlCopyright © 2015 NS Solutions Corporation, All rights reserved. 34

TakesScreenshot interface(意訳)実装するときは下記の順でどれか返してくれればいいよ。ブラウザによってベストエフォートで実装してね。

• ページ全体

• 現在のウインドウ

• 現在のフレームの可視範囲

• ブラウザも含むディスプレイ全体

http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/TakesScreenshot.htmlCopyright © 2015 NS Solutions Corporation, All rights reserved. 35

orz

Copyright © 2015 NS Solutions Corporation, All rights reserved. 36

ブラウザ依存の闇と向き合う

世にある便利ツールを使おう!

(他力本願)

Copyright © 2015 NS Solutions Corporation, All rights reserved. 37

Seleniumベースのツール・サービス

• ラッパ /DSL• SeleniumのAPIを使いやすくしてくれたり、自然言語に近い形でテストを書けたりする

• クラウドサービス• 色々なブラウザの実行環境が使えたり、スクショや動画キャプチャ撮ってくれたりする

Copyright © 2015 NS Solutions Corporation, All rights reserved. 38

参考:Seleniumテストの自動化を推し進めるクラウドサービスまとめ

http://blog.htmlhifive.com/2014/12/09/selenium-cloud-services/

宣伝:弊社も作ってます

Pitalium

Copyright © 2015 NS Solutions Corporation, All rights reserved. 39

ピ タ リ ウ ム

by

OSS(Apache2.0)

Copyright © 2015 NS Solutions Corporation, All rights reserved. 40

IE

Safari

Chrome

Pitalium

テスト自動化の闇テスト自動化の闇と向き合う

Copyright © 2015 NS Solutions Corporation, All rights reserved. 41

テスト自動化の闇と向き合うには

• テストしやすい設計

• テストスクリプトに一手間

• 便利ツール・サービスを使う

Copyright © 2015 NS Solutions Corporation, All rights reserved. 42

そして深まる闇

闇トークしたい方

hifiveブースへお越しください!

Copyright © 2015 NS Solutions Corporation, All rights reserved. 43

・ NS Solutions、NS(ロゴ)、NSSOLは、新日鉄住金ソリューションズ株式会社の登録商標です。

・ hifive、hifive(ロゴ)は、新日鉄住金ソリューションズ株式会社の登録商標です。

・ Pitaliumは、新日鉄住金ソリューションズ株式会社の商標です。

・ Javaは、米国ORACLE Corp.の登録商標です。

・ HTML5 Logo by W3C

・ その他本文記載の会社名及び製品名は、それぞれ各社の商標又は登録商標です。

top related