SlideShare a Scribd company logo
1 of 50
Download to read offline
Selenideを使って上司のよくある
勘違いを回避するお話
株式会社セレス 中川陽平
自己紹介
中川陽平
1児の父
ウェブデザインやってる会社
⇒広告配信やってる会社
⇒ポイントサイトやってる会社
PHP、JSとかメイン
今こんなサービス担当してます
モッピーバイト
★ 今年の4月から担当
★ バイト探しのサイト
CareerGroove
★ 読み物系オウンドメディアも同時に
担当しています
CareerGroove
★ 「面白いバイト」で検索すると1番目
★ 「楽なバイト」で検索すると2番目
よくあるエピソード
外出していた上司から
電話がかかってきた。
上司😡
サイトのテキストが出てないよ!
すぐ直せ!今日中!ガミガミ!
🤦‍♂私
すみません!対応します!
私🤦‍♂💭メンバー共有
私🤦‍♂ 🚽とりあえずトイレ行こ🏃
あるメンバー🙋が上司に
電話📞で折り返し
メンバー🙅
これ○○のときに
移動させましたよね?
上司🙇
そうだった!ごめん!ほんとごめん!
私
😵
勘違いは回避できなかったんですけどね
今後は回避したいね
気づかない間にレイアウト崩れが
おきるかもしれないし
だったら
変化があったら
通知すればいいじゃないか
とりあえず作ってみた
使ったもの
★ Java
★ IntelliJ IDEA COMMUNITY
★ Selenide
★ aShot
○ ImageDiffer
★ メール(開発中はsmtp4dev)
★ Java、Selenideに詳しい社内のメンバー
こちらが出来上がった画像
★ 前回との差分の割合通知
★ MLに流してエビデンスを残す
こちらが出来上がった画像
UnitTestにも反映
変化があったとき 変化がなかったとき
技術的な点
Selenide とは?
ブラウザーを通してUIを操作する
テスト用のフレームワーク
DEMO
CSS Selector で要素を指定できる。
@Test
public void entry6164() {
entryFormPage.init("/entry/form.php?job_id=6164")
.inputName("テスト姓", "テスト名", "テストセイ", "テストメイ")
.selectSex("M")
.inputBirthDate("1990", "01", "02")
.inputTel("09099998888")
.inputMailAddress("mpjob-dev-ml@ceres-inc.jp")
.inputJob("大学生")
.inputAnswerFree("①金曜日の17時,②掃除代行と料理代行いずれも")
.inputContactDay("いつでも連絡OKです")
.inputNote("貴社はホワイトですか?")
.clickSubmitButton()
.checkErrorNotExist();
entryConfirmPage.clickSubmitButton().closeWindow();
}
public EntryFormPage inputName(String name_sei, String
name_mei, String kana_sei, String kana_mei) {
$("input[name=name_sei]").val(name_sei);
$("input[name=name_mei]").val(name_mei);
$("input[name=kana_sei]").val(kana_sei);
$("input[name=kana_mei]").val(kana_mei);
return this;
}
jQueryっぽくかけるので楽ちん
<div class="notMe">div class="notMe"</div>
<div class="myClass">div class="myClass"</div>
<span class="myClass">span class="myClass"</span>
<script>
$( ".myClass" ).css( "border", "3px solid red" );
</script>
Java で使えます。
Slenideの便利な点
★ Selenium のラッパーらしいんだけどSelenideの方
が圧倒的に楽
★ Seleniumだとページのロード完了を判定する必要
があるが、Selenideはない
★ jQueryライクにコードが簡潔に書ける
画像で差分をとるためにしたこと
画像差分をとるためにしたこと
★ 定期的に実行
★ 観測しておきたいページのスクリーンショットを取得
★ 前回のスクリーンショットと比較
★ 異なる割合(変化率)を抽出
★ メールで送信してエビデンス(証拠)を残す
定期的に実行
★ Jenkinsにお任せ(任せた)
スクリーンショットの取得
★ Selenideのスクリーンショット機能
■ ブラウザの表示領域しか残せない
★ aShotを利用
○ 自動的に画面をスクロールしてキャプチャしてく
れる
○ キャプチャしたくないものを隠すこともできる(らし
い、今のところうまくいってない)
スクリーンショット用のコード
String testName = "表画面PC都道府県x市区町村ページ";
String FileNamePrefix = "pc_pref_city_";
ResultPage resultPage = open("/tokyo/city_setagayaku/", ResultPage.class);
File currentImage = new File(pathToResources + FileNamePrefix + "ss_result_current.png");
File afterImage = new File(pathToResources + FileNamePrefix + "ss_result_after.png");
String diffFileName = pathToResources + FileNamePrefix + "ss_result_diff.png";
WebDriver driver = WebDriverRunner.getWebDriver();
WebElement headerArea = $("#headerarea");
JavascriptExecutor jsExec = (JavascriptExecutor) driver;
// ヘッダー画像取得
BufferedImage headerImage = new AShot()
.coordsProvider(new WebDriverCoordsProvider())
.takeScreenshot(driver, headerArea)
.getImage();
// ヘッダー非表示
jsExec.executeScript("arguments[0].style.visibility='hidden'", headerArea);
// スクロールしながら全体のスクリーンショットを取得
// https://jitpack.io/p/yandex-qatools/ashot
// http://naruoga.hatenablog.com/entry/2019/02/09/012608
Screenshot ssImage = new AShot()
.coordsProvider(new WebDriverCoordsProvider())
.shootingStrategy(ShootingStrategies.viewportPasting(1000))
.takeScreenshot(driver);
// ヘッダーを戻す
jsExec.executeScript("arguments[0].style.visibility=''", headerArea);
// ヘッダー画像を全体のスクリーンショットに張り付け
Graphics2D graphics = ssImage.getImage().createGraphics();
graphics.drawImage(headerImage, 0, 0, null);
graphics.dispose();
double diffRate = diff(ssImage, currentImage, afterImage, diffFileName, testName);
// 結果
Assert.assertTrue(0.0 == diffRate);
前回分のスクリーンショットと比較
前回分のスクリーンショットと比較
★ aShotに ImageDiffer というクラ
スがあるのでそれを利用
○ 画像の差分をとる機能
○ 変化があった部分は赤く表
示
差分取得用のコード
// diff 画像の作成
BufferedImage bufferCurrentImage = ImageIO.read(currentImage);
BufferedImage bufferAfterImage = ImageIO.read(afterImage);
ImageDiffer imageDiffer = new ImageDiffer();
ImageDiff imageDiff = imageDiffer.makeDiff(bufferCurrentImage, bufferAfterImage);
BufferedImage diffImage = imageDiff.getMarkedImage();
ImageIO.write(diffImage, "PNG", new File(diffFileName));
前回との変化の割合を算出
★ aShot の ImageDiffer は何ピクセル分の変化が
あったのかが取得できる
★ 画像のサイズのうち何ピクセル変わったのかわか
れば変化の割合がわかる
if (imageDiff.hasDiff()) {
diffRate = (double) imageDiff.getDiffSize() / (
imageDiff.getMarkedImage().getWidth() * imageDiff.getMarkedImage().getHeight());
}
メール送信
★ HTML メールを Java で作って送信
★ Windows で開発中は smtp4dev を利用
○ メールサーバー不要
○ 実際にメールが送信されることもない
○ 受け取ったメールの内容を確認できる
メール送信
★ マルチパートを使ってメール本文内に差分を表示し
たスクリーンショットを表示
★ 一目で何が変わったかを把握できるように。
★ 変化の割合もメールの件名、本文に含めて注意喚
起
最後に
結構簡単に差分付きエビデンスが残せるの
でおすすめです!

More Related Content

What's hot

hooks riverpod + state notifier + freezed でのドメイン駆動設計
hooks riverpod + state notifier + freezed でのドメイン駆動設計hooks riverpod + state notifier + freezed でのドメイン駆動設計
hooks riverpod + state notifier + freezed でのドメイン駆動設計Shinnosuke Tokuda
 
すぐに分かる!プロジェクト計画の作り方
すぐに分かる!プロジェクト計画の作り方すぐに分かる!プロジェクト計画の作り方
すぐに分かる!プロジェクト計画の作り方Eisuke Sugitani
 
モデリングもしないでアジャイルとは何事だ
モデリングもしないでアジャイルとは何事だモデリングもしないでアジャイルとは何事だ
モデリングもしないでアジャイルとは何事だIwao Harada
 
.NET 7期待の新機能
.NET 7期待の新機能.NET 7期待の新機能
.NET 7期待の新機能TomomitsuKusaba
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring増田 亨
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることShingo Fukui
 
コーディング入門以前
コーディング入門以前コーディング入門以前
コーディング入門以前Yutaka Kinjyo
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
GitHubにバグ報告して賞金$500を頂いた話
GitHubにバグ報告して賞金$500を頂いた話GitHubにバグ報告して賞金$500を頂いた話
GitHubにバグ報告して賞金$500を頂いた話Yoshio Hanawa
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
REST API のコツ
REST API のコツREST API のコツ
REST API のコツpospome
 
Test Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTest Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTakuto Wada
 
LTを支える技術(LLD'11 Winter)
LTを支える技術(LLD'11 Winter)LTを支える技術(LLD'11 Winter)
LTを支える技術(LLD'11 Winter)masayoshi takahashi
 
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeNA
 
どうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCIどうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCIKoichiro Sumi
 
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけらAtsushi Nakamura
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 

What's hot (20)

Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
 
hooks riverpod + state notifier + freezed でのドメイン駆動設計
hooks riverpod + state notifier + freezed でのドメイン駆動設計hooks riverpod + state notifier + freezed でのドメイン駆動設計
hooks riverpod + state notifier + freezed でのドメイン駆動設計
 
すぐに分かる!プロジェクト計画の作り方
すぐに分かる!プロジェクト計画の作り方すぐに分かる!プロジェクト計画の作り方
すぐに分かる!プロジェクト計画の作り方
 
モデリングもしないでアジャイルとは何事だ
モデリングもしないでアジャイルとは何事だモデリングもしないでアジャイルとは何事だ
モデリングもしないでアジャイルとは何事だ
 
.NET 7期待の新機能
.NET 7期待の新機能.NET 7期待の新機能
.NET 7期待の新機能
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ること
 
コーディング入門以前
コーディング入門以前コーディング入門以前
コーディング入門以前
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
GitHubにバグ報告して賞金$500を頂いた話
GitHubにバグ報告して賞金$500を頂いた話GitHubにバグ報告して賞金$500を頂いた話
GitHubにバグ報告して賞金$500を頂いた話
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
REST API のコツ
REST API のコツREST API のコツ
REST API のコツ
 
Serverless時代のJavaについて
Serverless時代のJavaについてServerless時代のJavaについて
Serverless時代のJavaについて
 
Test Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTest Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるか
 
LTを支える技術(LLD'11 Winter)
LTを支える技術(LLD'11 Winter)LTを支える技術(LLD'11 Winter)
LTを支える技術(LLD'11 Winter)
 
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
 
どうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCIどうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCI
 
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 

Similar to Selenideを使って上司のよくある勘違いを回避するお話

【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー
【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー
【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリーHiroki Matsumoto
 
アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)
アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)
アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)Kazuki Takahashi
 
第二回(キャリアは明るく楽しく行動する)5月17日
第二回(キャリアは明るく楽しく行動する)5月17日第二回(キャリアは明るく楽しく行動する)5月17日
第二回(キャリアは明るく楽しく行動する)5月17日Cozy Azuma
 
Dev lobe20090325v1.0
Dev lobe20090325v1.0Dev lobe20090325v1.0
Dev lobe20090325v1.0walnut210
 

Similar to Selenideを使って上司のよくある勘違いを回避するお話 (7)

見込み客が増える 儲かるブログの書き方講座
見込み客が増える 儲かるブログの書き方講座見込み客が増える 儲かるブログの書き方講座
見込み客が増える 儲かるブログの書き方講座
 
Wcan autumn 2015
Wcan autumn 2015Wcan autumn 2015
Wcan autumn 2015
 
【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー
【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー
【ブロガーズフェスティバル】20151018 今のノマド的節約術に至るまでのストーリー
 
アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)
アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)
アウトソーシング嫌いのベンチャーが2ヶ月間でオフショア開発でサービスをローンチしてみた(PL視点)
 
第二回(キャリアは明るく楽しく行動する)5月17日
第二回(キャリアは明るく楽しく行動する)5月17日第二回(キャリアは明るく楽しく行動する)5月17日
第二回(キャリアは明るく楽しく行動する)5月17日
 
Slide
SlideSlide
Slide
 
Dev lobe20090325v1.0
Dev lobe20090325v1.0Dev lobe20090325v1.0
Dev lobe20090325v1.0
 

More from ceres-inc

RustでWebAssembly
RustでWebAssemblyRustでWebAssembly
RustでWebAssemblyceres-inc
 
エンジニア力底辺のデザイナーが Vue.jsチャレンジ 
エンジニア力底辺のデザイナーが Vue.jsチャレンジ エンジニア力底辺のデザイナーが Vue.jsチャレンジ 
エンジニア力底辺のデザイナーが Vue.jsチャレンジ ceres-inc
 
単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~
単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~
単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~ceres-inc
 
初心者による初心者のための システム作りの流れ
初心者による初心者のための システム作りの流れ初心者による初心者のための システム作りの流れ
初心者による初心者のための システム作りの流れceres-inc
 
初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~
初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~
初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~ceres-inc
 
初心者による初心者のためのMySQLクエリチューニング
初心者による初心者のためのMySQLクエリチューニング初心者による初心者のためのMySQLクエリチューニング
初心者による初心者のためのMySQLクエリチューニングceres-inc
 

More from ceres-inc (6)

RustでWebAssembly
RustでWebAssemblyRustでWebAssembly
RustでWebAssembly
 
エンジニア力底辺のデザイナーが Vue.jsチャレンジ 
エンジニア力底辺のデザイナーが Vue.jsチャレンジ エンジニア力底辺のデザイナーが Vue.jsチャレンジ 
エンジニア力底辺のデザイナーが Vue.jsチャレンジ 
 
単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~
単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~
単体テストをやってみた~既存サービスに単体テストを追加するチャレンジ~
 
初心者による初心者のための システム作りの流れ
初心者による初心者のための システム作りの流れ初心者による初心者のための システム作りの流れ
初心者による初心者のための システム作りの流れ
 
初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~
初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~
初心者による初心者のためのRPA入門 ~Seleniumを使用したWebブラウザ操作の自動化~
 
初心者による初心者のためのMySQLクエリチューニング
初心者による初心者のためのMySQLクエリチューニング初心者による初心者のためのMySQLクエリチューニング
初心者による初心者のためのMySQLクエリチューニング
 

Selenideを使って上司のよくある勘違いを回避するお話