<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>ISOROOT Tech Blog</title><link>http://techblog.isoroot.jp/</link><description></description><lastBuildDate>Thu, 20 Oct 2016 12:00:00 +0900</lastBuildDate><item><title>今すぐ実践すべきモバイルアプリの注意すべきテスト観点</title><link>http://techblog.isoroot.jp/mobile_test_items.html</link><description>&lt;p&gt;こんにちは！現場では、主にAndroidの開発をしている今井です！&lt;/br&gt;
今回は、弊社で実践しているモバイルアプリのテスト手法に関してご紹介をします。&lt;/p&gt;
&lt;h1&gt;テストをする上でもっとも重要なこと&lt;/h1&gt;
&lt;p&gt;以前の記事で、
テストにおいて一番重要な部分は、&lt;strong&gt;要求仕様書、設計書から試験項目を起こして実施&lt;/strong&gt;と書きました。
&lt;/br&gt;
&lt;/br&gt;
なぜこのフェーズが一番重要かというと、&lt;strong&gt;アプリが仕様通り動くことを担保するのは試験項目書&lt;/strong&gt;だからです。
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;試験を行う前にはコードレビューといった工程を通過することで、アプリの不具合などを減らしていきますが、
試験項目書はアプリをリリースする前の最後の砦になります。
&lt;/br&gt;
&lt;/br&gt;
そこで試験項目書にはバグの検出率が求められますが、どういったことに気をつければいいのでしょうか？
&lt;/br&gt;&lt;/p&gt;
&lt;h1&gt;モバイルアプリのテストで気をつけるべき観点&lt;/h1&gt;
&lt;p&gt;アプリによって発生するバグも様々ですが、モバイルアプリには良く起きるバグにいくつかパターンがあります。
&lt;/br&gt;
&lt;/br&gt;
そういったパターンを試験項目が押さえておくことでバグの検出率が高まると思います。
&lt;/br&gt;
&lt;/br&gt;
ここでいくつか紹介させていただきます。
&lt;/br&gt;&lt;/p&gt;
&lt;h3&gt;画面遷移のパターンは網羅できてるか？&lt;/h3&gt;
&lt;p&gt;状態が復元されるかどうかというは、例えばスクロールできる画面の場合、
画面Aをスクロール -&amp;gt; 画面Bに遷移 -&amp;gt; 画面Aに戻るという操作をしたときに、
画面Aに戻ってきたときに元のスクロール位置に戻っているといったことです。
&lt;/br&gt;
&lt;/br&gt;
また、表示していたデータが元のまま表示されることも重要です。
&lt;/br&gt;
&lt;/br&gt;
アプリによっては、画面が表示されるたびにデータの更新が必要なものもあると思いますが、
その場合を除き、気をつけておくべきです。
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="transition.png" src="/images/transition.png" /&gt;&lt;/p&gt;
&lt;h3&gt;通信エラーのパターンは網羅できてるか？&lt;/h3&gt;
&lt;p&gt;通信エラー時の挙動にも気をつけなくてはなりません。
通信エラーと一口に言っても、ネットワークが悪い場合、
サーバーが悪い場合などいくつかパターンがあります。
&lt;/br&gt;
&lt;/br&gt;
違うエラーにはそれぞれにあったメッセージや、エラー時の挙動を起こす必要があります。
&lt;/br&gt;
&lt;/br&gt;
特に&lt;strong&gt;ステータスコードごとの挙動&lt;/strong&gt;には注意を払う必要があります。
&lt;/br&gt;
&lt;/br&gt;
こういった場合を細かくチェックすることもバグを減らす重要な観点になります。
&lt;/br&gt;&lt;/p&gt;
&lt;h3&gt;データがある場合、ない場合の表示&lt;/h3&gt;
&lt;p&gt;意外に見落としがちなことですが、表示すべきデータがない場合(エンプティステート)の表示を確認する必要があります。
&lt;/br&gt;
&lt;/br&gt;
表示すべきものがある前提で画面は作られがちです。
&lt;/br&gt;
&lt;/br&gt;
そのため、エンプティステートの場合、表示しなくてはいけないメッセージが抜け落ちていたりする場合があります。
&lt;/br&gt;
&lt;/br&gt;
例えば、ユーザーを表示する画面でデータが一件もない場合、「登録されているユーザーは0件です。」
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;といった具合です。
&lt;/br&gt;&lt;/p&gt;
&lt;h3&gt;サポート対象の端末にインストールできるか&lt;/h3&gt;
&lt;p&gt;この問題はAndroidでよく発生します。
&lt;/br&gt;
&lt;/br&gt;
Androidは非常に多くの端末で採用されているため、アプリが対象にする端末にインストールできること、
動作することを担保する必要があります。
&lt;/br&gt;
&lt;/br&gt;
しかし、インストール対象の端末を全て手に入れるのは困難なため、
ストアに公開した後にインストールできない端末が発覚する場合があります。
&lt;/br&gt;
&lt;/br&gt;
Androidであれば、manifestファイルの定義を確認するなど、そういった観点も必要になります。
&lt;/br&gt;&lt;/p&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;p&gt;いかがでしたでしょうか。
&lt;/br&gt;
&lt;/br&gt;
今回は、試験項目を作成する上で気をつけるべき観点をいくつか紹介させていただきました。
&lt;/br&gt;
&lt;/br&gt;
それぞれの観点は試験を作成する上でも重要ですが、仕様を定める段階でも気をつけておくといいです。
&lt;/br&gt;
&lt;/br&gt;
仕様が明確であればあるほど、「この時はこうなる」ということがはっきりするため試験項目の精度も高まります。
&lt;/br&gt;
&lt;/br&gt;
試験の精度を高め、品質の高いアプリを作っていきましょう。&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">imai.k</dc:creator><pubDate>Thu, 20 Oct 2016 12:00:00 +0900</pubDate><guid isPermaLink="false">tag:techblog.isoroot.jp,2016-10-20:mobile_test_items.html</guid></item><item><title>今すぐ実践すべきモバイルアプリの開発フロー改善</title><link>http://techblog.isoroot.jp/mobile_test_flow.html</link><description>&lt;p&gt;こんにちは！現場では、主にAndroidの開発をしている今井です！&lt;/br&gt;
今回は、弊社で実践しているモバイルアプリの開発フローに関してご紹介をします。&lt;/p&gt;
&lt;p&gt;日々進化するモバイル端末に対して、モバイルアプリ開発で以下のような悩みを抱えてませんか？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iOS/AndroidなどOS、端末が複数ある&lt;/li&gt;
&lt;li&gt;OSも、開発するアプリもアップデートが頻繁でテストが大変&lt;/li&gt;
&lt;li&gt;アプリの設計が悪く、バグがたくさん！&lt;/li&gt;
&lt;li&gt;などなど&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/br&gt;
こういった課題に関して、弊社が&lt;strong&gt;モバイルアプリ開発&lt;/strong&gt;で実践しているノウハウを数回に分けてご紹介していきます。
&lt;/br&gt;&lt;/p&gt;
&lt;h1&gt;開発のフローはどんな形？&lt;/h1&gt;
&lt;p&gt;全体的なフローは、
&lt;/br&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;コードを書く・レビューするを繰り返す（開発）&lt;/li&gt;
&lt;li&gt;テスト用のバイナリをデプロイする&lt;/li&gt;
&lt;li&gt;試験項目を作成し、テストを行う&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;です。
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;上記のフローのうち、テストにおいて一番重要な部分は、&lt;strong&gt;要求仕様書、設計書から試験項目を起こして実施&lt;/strong&gt;です。
&lt;/br&gt;
&lt;/br&gt;
何とも素朴かもしれませんが、&lt;strong&gt;これが基本&lt;/strong&gt;なのです。
&lt;/br&gt;
&lt;/br&gt;
プロジェクトによっては自動テストを導入したりしますが、試験項目書の作成は必須ですね。&lt;/p&gt;
&lt;h1&gt;バージョン管理はGitを使うこと！&lt;/h1&gt;
&lt;p&gt;&lt;img src="/images/gitlab.png" width="50%"&gt;&lt;/p&gt;
&lt;p&gt;開発中のバージョン管理システムは主に&lt;a href="https://about.gitlab.com/"&gt;GitLab&lt;/a&gt;を使用しています。&lt;/br&gt;
Gitを使った開発では、どんな風にブランチを運用するかが重要です。
&lt;/br&gt;
&lt;/br&gt;
弊社では、GitLabとGit Flow(&lt;a href="http://nvie.com/posts/a-successful-git-branching-model/"&gt;a successgull git branching model&lt;/a&gt;)を部分的に取り入れたフローで運用しています。
&lt;/br&gt;&lt;/p&gt;
&lt;h3&gt;コードレビュー&lt;/h3&gt;
&lt;p&gt;実際の開発では、GitLabのMerge Requestという仕組みにより開発者同士がコードレビューを行っています。
&lt;/br&gt;
&lt;/br&gt;
開発時は専用のブランチを作成し、開発が完了したら、本流と合流してもらうように、Merge Requestを出します。
&lt;/br&gt;
&lt;/br&gt;
コードレビューの結果、問題なければ本流にMergeされるのですが、ここで、必ず意識していることがあります。それは、
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;テストコードが書かれていること&lt;/strong&gt;です。
&lt;/br&gt;&lt;/p&gt;
&lt;h3&gt;テストコードを作ること！&lt;/h3&gt;
&lt;p&gt;「テストがないコードは古い」とまで言われる昨今、
テストコードは可能な限り記述するようにしています。
&lt;/br&gt;
&lt;/br&gt;
テストコードがあることによって、機能・メソッド一つ一つの信頼度が上がり、
人力の試験だけでは補えない部分までカバーすることができます。
&lt;/br&gt;
&lt;/br&gt;
テストコードを書くことは、開発者のスキル向上にも直接つながりますしね！&lt;/p&gt;
&lt;p&gt;また、品質の担保は最終的には人力頼みとなりますが、
開発中からできる限り見落としや考慮漏れを排除するために、
テストコードを書かないとMargeしないなど、
ルールを設けるようにして運用しています。
&lt;/br&gt;&lt;/p&gt;
&lt;h1&gt;テストアプリのデプロイはDeployGateを使うべし！&lt;/h1&gt;
&lt;p&gt;&lt;/br&gt;
&lt;strong&gt;まだケーブルを使って転送してませんか？&lt;/strong&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;開発が終わり、テスト用のバイナリを端末にデプロイするのですが、
弊社では、バイナリをインストールする手段として、
&lt;/br&gt;
&lt;/br&gt;
&lt;a href="https://deploygate.com"&gt;DeployGate&lt;/a&gt;を使用しています。
&lt;/br&gt;
&lt;/br&gt;
DeployGateは、アプリインストールを効率化するツールで、
こちらも開発環境に依存したバグ等を防ぐとともに、
実機にインストールするためのオーバーヘッドを下げることで、
試験の効率化を図っています。
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;また、テスト用のバイナリ作成は必ずCIツールで生成されたものを用いるようにしています。
&lt;/br&gt;
&lt;/br&gt;
これは、開発環境に依存した不具合などを防止するために有効な手段となっています。&lt;/p&gt;
&lt;h1&gt;試験項目を作成する際に注意すべき点を洗い出すべし！&lt;/h1&gt;
&lt;p&gt;さて、テスト対象のアプリが用意され、試験できる準備が整いましたが、
肝心の試験項目はどういったことに気をつけて作成するべきなのでしょうか。
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;アプリの世界観や要求にもよりますが、以下の点に気をつけると、不具合が発生しづらくなるかと思います。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;画面が再表示されたとき、状態が復元されるかどうか&lt;/li&gt;
&lt;li&gt;通信エラー時の挙動に気をつける&lt;/li&gt;
&lt;li&gt;データがない時(エンプティステート)の表示は問題ないか&lt;/li&gt;
&lt;li&gt;サポート対象の端末にインストールできるかどうか&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;モバイルアプリのテストは、アプリの状態だけでなく、端末の状態や外的要因（ネットワーク等）にも気を配る必要があります。
&lt;/br&gt;
&lt;/br&gt;
また、OSバージョンの違いなどにも注意しないといけないため、できるだけモバイルアプリに最適化されたテスト項目が準備されなくてはいけません。
&lt;/br&gt;
&lt;/br&gt;
テスト観点に関して、次回以降にさらに詳しく紹介させていこうと思います。&lt;/p&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;p&gt;いかがでしたでしょうか。
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;モバイルアプリ開発において、様々なOS・端末への対応は必須事項ですが、
だからこそバグの混入を防ぐことは困難です。
&lt;/br&gt;
&lt;/br&gt;&lt;/p&gt;
&lt;p&gt;テストコードの準備や、試験項目の精度を高めるなど、
何重にも保険をかけることで品質の高いアプリ開発を行っていきたいものですね。&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">imai.k</dc:creator><pubDate>Mon, 10 Oct 2016 12:00:00 +0900</pubDate><guid isPermaLink="false">tag:techblog.isoroot.jp,2016-10-10:mobile_test_flow.html</guid></item><item><title>ブラウザテストの便利ツール「BrowserStack」の知っておくべき5つのポイント</title><link>http://techblog.isoroot.jp/browserstack.html</link><description>&lt;p&gt;&lt;img alt="BrowserStack.jpg" src="/images/browserstack.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
こんにちは、kureyです。
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;みなさんブラウザテストをする際の環境はどのように用意していますか？&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;利用するデバイス×OSのバージョン×ブラウザ&lt;/strong&gt;の数だけテストの実行環境を用意してテストする…。
考えるだけでめんどくさいし、コストもかかるのが容易に想像できますね。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;そんな時は世の中にあるWebサービスを使ってこの問題を解決しちゃいましょう。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;今回取り上げるのは&lt;strong&gt;BrowserStack&lt;/strong&gt;というWebサービスです。&lt;/p&gt;
&lt;p&gt;このサービスを利用する事でどんな事ができるのか、そして他のサービスとどのような違いがあるのかをご紹介します。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;1. BrowserStackってどんなサービス？使うと何が嬉しいの？&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;BrowserStackというサービスがどういうものかを一言でいうと各種OS、各種ブラウザをあなたがお使いのブラウザ上から操作をできるようにしてくれるサービスです。
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;このサービスの一番の魅力は&lt;strong&gt;ブラウザテストするために必要な環境を準備する事が不要&lt;/strong&gt;になることです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;2. どのぐらいの環境が用意されてるの？&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;BrowserStackにはとても豊富な環境が用意されています。（詳しくは&lt;a href="https://www.browserstack.com/list-of-browsers-and-platforms?product=live"&gt;コチラ&lt;/a&gt;）
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Windows XPからWindows 10まで、MacはOS X Snow Leopard(v10.6)からOS X El Capitan(v10.11)までをサポートし、ブラウザはIE、Safari、Chrome、Firefox、Operaなど主要ブラウザはほぼ網羅しています。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;3. ブラウザ毎の表示確認ぐらいなら他サービスで良くね？&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;ブラウザのスクリーンショットだけを確認したいだけであれば「modern.IE&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1" rel="footnote"&gt;1&lt;/a&gt;&lt;/sup&gt;」や「BROWSER SHOTS」など確認したいWebページのURLを入れるだけで確認ができるWebサービスが存在します。
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;もちろんBrowserStackにも「Screenshots」というものがあり、他サービスと同様にWebページのURLを入力し、スクリーンショットを取りたいOSとブラウザを選択することでお手軽に表示確認をすることができます。
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;…だが、BrowserStackには更に&lt;strong&gt;Live&lt;/strong&gt;という機能が存在し、あなたのブラウザ上から全く別のOS、まったく別のブラウザを&lt;strong&gt;リアルタイム&lt;/strong&gt;で操作することができ、より細かな動作確認ができるのです。
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;例えば動的なページに対して何か操作を行った結果が問題ないかを確認したい場合などに効果を発揮します。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;4. もちろん自動実行も備えてます。&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;ScreenshotsやLiveという機能で表示確認や操作を毎回手動でテストするのはやはりコストがかかってしまいます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;そこで登場するのがBrowserStackのもう一つの機能&lt;strong&gt;Automate&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;これはSeleniumなどのテストコードを実行する事でBrowserStack上で用意されているブラウザのテストを自動で行うことができます。
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Jenkinsと組み合わせて毎日定期実行することで継続インテグレーションを実現することができます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;また、AWS Device Farmも2015年11月にWebアプリケーションテストに対応し、同じようにテストコードからブラウザのテストを自動実行できるようになったため、スマートフォンのブラウザテストはAWS Device Farm、PCのブラウザテストはBrowserStackといった使い分けができます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;5. 有料サービスであること&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;最後はデメリットになります。&lt;/p&gt;
&lt;p&gt;BrowserStackはとても魅力的なサービスではありますが、いいサービスには対価が伴います。&lt;/p&gt;
&lt;p&gt;そうです、お金ですね。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;プラン&lt;/th&gt;
&lt;th&gt;料金&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live&lt;/td&gt;
&lt;td&gt;$29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automate&lt;/td&gt;
&lt;td&gt;$59&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AutomatePro&lt;/td&gt;
&lt;td&gt;$99&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;※上記は１ユーザ１セッションの場合の値段のため、複数人で同時に利用する場合には更に値段が高くなります。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;BrowserStackは月額プランとなっており、あまりお気軽に試してみようというには若干高い金額となっておりますが、他サービスのAWS Device Farmと比べると多少安価&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2" rel="footnote"&gt;2&lt;/a&gt;&lt;/sup&gt;な値段設定となっている。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;いかがでしたでしょうか。
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Web開発者にとってクロスブラウザの確認はほぼ必須となっており、確認するための環境作りなどで手間を割かれてしまうのはとても勿体ない事であり、その時間をもっと開発に使える事ができればより良いサービスを生み出す事ができるでしょう。
&lt;br&gt;&lt;/p&gt;
&lt;p&gt;BrowserStackはそんな手間を解消してくれるとても魅力的なサービスであるため、まずはFreeTrialで試してみるのはいかがでしょうか。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;modern.IEはBrowserStackを使ってスクリーンショットをとっている。&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;AWS Device Farmの料金設定は$0.17/分、$250/1デバイススロット(iOS/Android毎に契約可能な月額プラン)&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">kurey</dc:creator><pubDate>Mon, 26 Sep 2016 12:00:00 +0900</pubDate><guid isPermaLink="false">tag:techblog.isoroot.jp,2016-09-26:browserstack.html</guid></item><item><title>タブレットが壊れる！？アプリUIの改善でタブレットの寿命を延ばすの巻</title><link>http://techblog.isoroot.jp/user_case_1_tablet_broken.html</link><description>&lt;h4&gt;スマートデバイスの業務アプリをやってきて遭遇したあんなことやこんなこと。&lt;/h4&gt;
&lt;p&gt;&lt;font color="blue"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;当社では、様々なお客様の業務の現場へ、モバイルデバイスを活用したアプリやシステムをご提供してきました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;その中で実際に起きた色々な事例と、その対策アプローチをご紹介します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;スワイプしすぎでタブレットの画面が削れてきた！&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;写真はイメージです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="写真はイメージです。" src="/images/device_broken_2.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;画面を移動したり、アイテムを移動させたり。タッチパネル画面を指でなぞるようにして操作する、”スワイプ”。スマホやタブレットを使う人にとってはごく一般的な操作方法です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当社のSmartGEMBA 巡回点検アプリを半年ほどご利用頂いたあるお客様から、ご相談がありました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;「&lt;font color="red"&gt;&lt;strong&gt;見てください。タブレットの画面が、削れて穴が開きそうです&lt;/strong&gt;&lt;/font&gt;」&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;感圧型タッチパネル x ハードタイプのタッチペン x 毎日数千回のスワイプ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;このアプリのUIには左右にスワイプする操作が頻繁に登場します。でもそれだけでは画面が削れたりなんて普通はしません。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;実はこのお客様、利用している端末がちょっと珍しい「感圧式」タッチパネルの業務用タブレットでした。&lt;code&gt;(感圧式タッチパネルの端末は、手袋などをしていても、ぐっと画面を押すことで操作できるため、SmartGEMBAをご利用頂くような、現場の運用では利用候補に挙がります。一般的には静電方式タッチパネルですが、仕事で使う手袋では反応してくれないのです。)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;さらに、ハードタイプのタッチペンとを併用して、毎日画面を左右に数千回スワイプしていることが分かりました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;これだけ酷使すれば、確かに画面が削れて来ても不思議ではありません。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;ソフトウェアからの対策アプローチ。スワイプ無しで操作可能にＵＩ変更。&lt;/h2&gt;
&lt;p&gt;&lt;img alt="ソフトウェアからの対策アプローチ。スワイプ無しで操作可能にＵＩ変更" src="/images/device_broken_before_after.png" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;結果的には、アプリのUIを変更することで解決しました。スワイプ操作と同じ結果をもたらす、ボタンを新設したのです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;変更前のスワイプは、タッチしてそのまま左右に4cm程スライドさせます。変更後は画面にペン先で点で振れるだけで同じ結果を生むように変更しました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;これによってタッチペンと画面との摩擦が減り、画面破損への影響は無くなりました。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;教訓&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ソフト・ハード・使い方の組み合わせで、やってみて分かることがあります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;実際の利用現場でプレ運用、フィールドテストを経て、フィードバックを得ることが重要です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">anannori</dc:creator><pubDate>Fri, 26 Aug 2016 13:00:00 +0900</pubDate><guid isPermaLink="false">tag:techblog.isoroot.jp,2016-08-26:user_case_1_tablet_broken.html</guid></item><item><title>Selenium(Java)でブラウザテストをするときにやっておくべき３つのこと</title><link>http://techblog.isoroot.jp/selenium_java_test.html</link><description>&lt;p&gt;こんにちは、kureyです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;今回は私がSeleniumとJavaを使ってWebアプリケーションの画面テストをする際に気を付けたことを３つご紹介します。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;Seleniumとは？&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;Seleniumとは、ブラウザのテストで用いられるフレームワークです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;ブラウザに表示されているテキストなどの要素が正しく表示されているか？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ボタンをクリックすることで遷移する先のURLが正しいか？&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;などのサイト上の動作を様々な言語&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1" rel="footnote"&gt;1&lt;/a&gt;&lt;/sup&gt;で記述されたプログラムによりテストする事ができます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;これは世に出ている様々なブラウザ上で自分のサイトが正しく動作しているか、
定期的にテストするためによく使われます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;1. Seleniumでテストする範囲を決める&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;１つ目に気を付けるべき点はSeleniumで&lt;strong&gt;テストする範囲を決める&lt;/strong&gt;ことです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;最初から全ての画面の全ての操作をSeleniumで自動化しようとすると、
テストコードを書くコスト物凄くかかる上、メンテナンスも大変となります。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;私がSeleniumでテストを行った時は各画面で必ず存在するようなヘッダーやフッターの表示、
メニューなど共通の画面で利用できるもの、ブラウザリロードやブラウザバックした時の動作、
それぞれが想定通りの動作となっているかという点に観点を絞り、テストの範囲を最小限にしました。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;このように自動化する範囲を各画面で必ず行うような操作に限定する事でテストコードは汎用的にしやすく、
プログラムに落とし込むコストは大幅に削減でき、&lt;strong&gt;最小限のコストで最大限のパフォーマンス&lt;/strong&gt;を発揮する事ができます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;2. テストコードを書く上でルールを決める&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;２つ目はテストコードを書く上でも&lt;strong&gt;コーディングルールを決める&lt;/strong&gt;ことです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;複数人でテストを書く場合、ルールを決めておかなければそれぞれが好き勝手書いてしまい、
せっかくテストする範囲を限定したにも関わらず煩雑なテストコードが生まれてしまいます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;煩雑なテストコードとは、FirefoxのSelenium IDEを利用して画面上の操作をキャプチャし、
それをそのままテストコードとして利用する場合が該当します。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;FirefoxのSelenium IDE自体は画面上の操作を記録してテストコードを生成してくれるため、
テストコードを作る上ではとても早いですが、テストコードの再利用が出来ないことや、
画面変更が発生した際にSelenium IDEで操作を記録してテストコードを生成する必要が出てきてしまいます。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;通常のプログラム同様、ある一定のルールを用いて開発を進めないと
保守性の低いアプリケーションが完成しますよね？&lt;/p&gt;
&lt;p&gt;たかがテストコード、されどテストコード。&lt;/p&gt;
&lt;p&gt;アプリケーションの品質を高い保つためにはテストコードもクリーンにすることをオススメします。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;ページオブジェクトパターンというデザインパターン&lt;/h3&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;ここでご紹介するのは&lt;strong&gt;ページオブジェクトパターン&lt;/strong&gt;というデザインパターンです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;ページオブジェクトパターンとは、テストコードを記述する上でWebアプリケーション上の画面１つを
オブジェクトとして捉えるデザインパターンの１種です。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Seleniumの公式でも推奨されている保守性の高いテストコードの書き方となります。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;以下、公式に記載されているPageObjectの原則&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;div style="font-size:12px"&gt;・The public methods represent the services that the page offers（publicメソッドは、ページが提供するサービスを表す）&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div style="font-size:12px"&gt;・Try not to expose the the internals of the page （ページの内部を公開しないこと）&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div style="font-size:12px"&gt;・Generally don’t make assertions （原則としてassertionを行わないこと）&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div style="font-size:12px"&gt;・Methods return other PageObjects （メソッドは他のPageObjectsを返す）&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div style="font-size:12px"&gt;・Need not represent an entire page （ページ全体を表す必要はない）&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div style="font-size:12px"&gt;・Different results for the same action are modelled as different as different methods （同じアクションに対して異なる結果となる場合には異なるメソッドとしてモデル化する）&lt;/div&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;このデザインパターンで書かれたテストコードの利点は画面変更が発生した場合に&lt;strong&gt;テストコードの修正が最小限&lt;/strong&gt;で済むことにあります。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;3. テストすべき内容をインターフェースとして定義&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;３つ目は各画面で共通して必ずテストするものを&lt;strong&gt;インターフェースとして定義&lt;/strong&gt;することです。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;デザインパターンである程度テストコードの統一性は生まれますが、チェックすべきテストを書く・書かないはその人次第になってしまう事があります。&lt;/p&gt;
&lt;p&gt;私はそれを防ぐために必要なチェック項目をインターフェースとして定義する事でテストの漏れをできる限り少なくなるようにしました。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MyTestCaseInterface&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testCheckUrl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;          &lt;span class="c1"&gt;// URLのチェック&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testCheckPageTitle&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// ページタイトルのチェック&lt;/span&gt;
    &lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;サンプルコード&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;以下は参考までに私がテストを行ったときのパッケージ構成とテストコードのサンプルとなります。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;パッケージ構成&lt;/h3&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;jp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isoroot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;page&lt;/span&gt;        &lt;span class="c1"&gt;// ページオブジェクトクラス&lt;/span&gt;
&lt;span class="n"&gt;jp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isoroot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scenario&lt;/span&gt;    &lt;span class="c1"&gt;// シナリオクラス&lt;/span&gt;
&lt;span class="n"&gt;jp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isoroot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fixture&lt;/span&gt;     &lt;span class="c1"&gt;// データクラス&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;ページオブジェクトクラス&lt;/h3&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;画面１つ１つをクラスとして定義します。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
また各画面で共通の部分がある場合、ベースクラスを定義して各画面で継承させると良いでしょう。
ただし、なんでもかんでも共通化しようとしてベースクラスが肥大化しすぎないように注意が必要です！&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;以下はログインページとトップページのサンプルコードです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PageBase&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PageBase&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;_driver&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_driver&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;     * &amp;lt;title&amp;gt;要素のテキスト取得&lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getPageTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tagName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;getText&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;     * URL取得&lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getUrl&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrentUrl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginPage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;PageBase&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoginPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;_driver&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_driver&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;     * ログインページにURLアクセス&lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;HogePage&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ログインページ&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;     * ログインボタンクリック&lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;TopPage&lt;/span&gt; &lt;span class="nf"&gt;clickLogin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;_pass&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ログイン&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="err"&gt;入力フォーム&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;sendKeys&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ログインパスワード入力フォーム&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;sendKeys&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_pass&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ログインボタン&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TopPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TopPage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;PageBase&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TopPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;_driver&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_driver&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;     * トップページにURLアクセス&lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;TopPage&lt;/span&gt; &lt;span class="nf"&gt;access&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;トップページ&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;     * ログアウトボタンクリック&lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt; &lt;span class="nf"&gt;clickLogout&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ログアウトボタン&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LoginPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;シナリオクラス&lt;/h3&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;このクラスではページオブジェクトクラスを利用してテストするシナリオを定義します。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;以下はログインページのURLとページタイトルをチェックするサンプルコードです。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;LoginPageTest&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;MyOperationTestCaseInterface&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LoginPageTest&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChromeDriver&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testCheckUrl&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;LoginPage&lt;/span&gt; &lt;span class="n"&gt;_login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_login&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUrl&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;ログインページ&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testCheckPageTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;LoginPage&lt;/span&gt; &lt;span class="n"&gt;_login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_login&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPageTitle&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ログインページ&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;補足：WebDriverの取得もFactoryクラスを作って切り替えられるようにするとより汎用的になります。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;最後に&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;今回はWebアプリケーションの画面テストをする際に注意すべきこととして&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;テスト自動化の範囲&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;テストコードの記述ルール(デザインパターン)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;テストケースの抽象化(インターフェース定義)することによるテスト漏れの防止&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;をご紹介しました。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;テストコードを書くのはとてもコストがかかりますが、Seleniumのようなテストツールを上手く活用する事でテストにかける時間を少なくし、
産性を最大限に引き出す事ができるきっかけの一つとなりますので、ぜひ活用してみてはいかがでしょうか。&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Selenium WebDriverはC#、Java、Perl、PHP、Python、Ruby、Node.jsに対応。&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">kurey</dc:creator><pubDate>Mon, 15 Aug 2016 12:00:00 +0900</pubDate><guid isPermaLink="false">tag:techblog.isoroot.jp,2016-08-15:selenium_java_test.html</guid></item></channel></rss>