Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

xUnitハンズオン第4回テキスト

402 views

Published on

職場で開催したハンズオンの資料。

Published in: Software
  • Be the first to comment

  • Be the first to like this

xUnitハンズオン第4回テキスト

  1. 1. xUnitハンズオン xUnitフレームワークを通じた プログラミング&テスト・スキルUP
  2. 2. 第4回(最終回)
  3. 3. 今回やること • 今回(最終回)は、実際の保守開発の中でUTを「どう活用」 するかを考えてみる。 • TDDという開発スタイルの紹介 • CIツールによる自動テスト体制構築の手順説明
  4. 4. テストするタイミング
  5. 5. テストするタイミング A) コーディングのあとで • インターフェースもクラスもその実装も、すべてコーディングしたあとで テストする。 • はじめにコードとドキュメンテーションありき。 • ウォーターフォールモデル。 B) コーディング(実装)のまえに • インターフェースとクラスのスタブを用意したら、実装をコーディングす る前にテストを書く(TDD)。 • はじめにテスト(=API仕様の表明〔assertion〕)ありき。 ① インターフェースとクラスのスタブを用意する ② テストを書く ③ テストを実行実行する(対象コードがスタブなので、必ず失敗する) ④ 実装を書く ⑤ テストを実行する(仕様通り実装されていれば成功する) ⑥ 仕様変更が発生したら①に戻る • 当たり前だが工数は増える。ある研究によれば15〜25%増える。かわりに 障害(バグ)を40〜90%抑える※1。 ※1 出典は@IT「いまさら聞けないTDD/BDD超入門(1):テスト駆動開発/振る舞い駆動開発を始めるため の基礎知識」(http://www.atmarkit.co.jp/ait/articles/1403/05/news035.html)
  6. 6. テスト実行の形態
  7. 7. テスト実行の形態 A) 手動で実行 • これまで学んできた方法。 • コンソールもしくはIDEから実行する。 B) 自動で実行 • 今回学ぶ方法。 • CIツールから実行する。 • タイミング: a. 定期的に実行(ex. ナイトリービルドの一環として実行) b. コミットをトリガーにして実行 c. 手動実行するビルド&デプロイのバッチ処理のなかで実行
  8. 8. 自動実行で利用できるツール • 各種のCIツール or タスクオートメーション化ツール • Jenkins • Travis CI • その他いろいろ(あるらしいです)
  9. 9. ところでCIって・・・ • CI=Continuous Integration(継続的統合) • 継続的に(できるかぎり頻繁なサイクルで)ビルド、テスト、 各種メトリクスの算出やそれに基づくレポーティングを行うこ とで、コードの品質を一定水準に保つとともに、開発生産性を 向上させようという考え方・実践(*-ism)※1。 ※1 CIの解説については右のURLなどを参照のこと:https://devops.com/continuous-integration-vs- delivery-vs-deployment-whats-difference/
  10. 10. Jenkins • Javaエコシステムの中から誕 生したCIツール。 • Jenkins≠タスクオートメー ション化ツール。 • CIだけでなくCD(後述)を も射程に入れたツール。 • v2.0(2016年4月)で Pipeline機能がデフォルトで サポートされ、ちょっとした お祭り騒ぎ(後述)。 ↑ジェンキンスおじさん
  11. 11. Travis CI • GitHubと連携して機能するCI ツール(Webアプリケーショ ン)。 • GitHub上のリポジトリへの コミットを検知して自動的に ビルド&テストする。 ※1 GitHub上にホスティングしているVisual StudioソリューションをTravis CIを使ってテストする方法につい ては、右のブログ記事を参照のこと:http://m12i.hatenablog.com/entry/2016/12/28/103745 ↑トラヴィスおじさん
  12. 12. Screwdriver • Yahoo!が開発したCI/CDツー ル※1。 • コアコンポーネントが2017年 1月にOSSとして公開された ※2。 • まだ情報流通量は非常に少な いがYahoo!のサービスを支え てきたツールとして、機能面 で期待できる。今後に期待。 ※1 公式サイトは右のURL:http://screwdriver.cd/ ※2 InfoQの紹介記事:https://www.infoq.com/jp/news/2017/01/yahoo-screwdriver 追記
  13. 13. Jenkinsの例
  14. 14. 作業の前説明 • 以降の説明=作業では、Jenkins v2.xのPipeline機能を使って、 NUnitで作成したテストを実行する方法を示し=実践します。 • えーと、そのまえに「Pipeline」って何ですか? • 「Pipes and Filters Pattern」ではない。※1 • 「Continuous Delivery Pipeline」(CDP)の「Pipeline」。 • えーと(2)、そのまえに「CD」って何ですか?※2 • CIを拡張した概念。 • 製品の本番環境デプロイをも射程に入れたオートメーション化により、 品質の保証、生産性の向上、そしてスピーディなサービスインを目指 す考え方・実践(*-ism)。 ※1 こちらの例としてはUNIXで導入されたパイプやASP.NETのOwin、Node.jsのStreamなどが該当。 ※2 CDもしくはCDPについての解説は右のURLなどを参照のこと:https://devops.com/continuous-delivery- pipeline/ 「化石燃料や水道などと同じく、ソフトウェア(やその新機能)も淀 みない流れのように、速やかに・恒常的に顧客のもとに送り届けられ るべきだ」ということらしい。
  15. 15. Continuous Delivery Pipelineの例 図:パイプライン・フロー(Jenkinsのリファレンスより引用)※1 ※1 原典は右のURL:https://jenkins.io/doc/book/pipeline/
  16. 16. Pipeline機能とは? A) CDを実現する基盤を提供してくれる • ワークスペースの用意、SCMからのコードのチェックアウト、ビルド、 テスト、メトリクス収集、パッケージング、デプロイといったステッ プを自動化してパイプラインを構築する基盤を提供。 • でも、これだけなら従来からできた(フリースタイルジョブを使って 画面から各ステップを担当するジョブを登録すればよかった)。 B) CDをスクリプトで記述できるようにしてくれる • Groovyで実装されたDSLを使って、各ステップをスクリプトで(≠画 面で)定義することが出来る。 • そしてこれこそが重要なところ。 • cf. Gradle、Sbt、Gulp
  17. 17. 余談 皆が不親切? or 私が遅れすぎ? • Web上の日本語記事のほとんどが「Pipeline機能はCDを実現す るためのものであること」や「画面でなくコードで記述するの が重要であること」という、「そもそもの前提となる事項」に ついてまったく言及していない。 • ことほどさように「CD/CIなんて業界的には当たり前」という ことかもしれないが…。。
  18. 18. メリデメ(とりあえず思いつく限り) メリット • CDのパイプラインをスクリ プトで柔軟に・複雑に定義で きる。 • スクリプトなのでパイプライ ンの定義そのものを容易に バージョン管理できる。 デメリット • Groovyの知識が必要(少なく とも初歩な知識は必要)。 • 設定項目や設定すべき値が不 明瞭(ドキュメント不足)。 まあそれを皆で助け合い改善してい くのがOSSってものですけどね!
  19. 19. あらためて Jenkinsの例
  20. 20. 作業の大まかな流れ # 手順 1 JDKインストール 2 環境変数設定 3 Tomcatインストール 4 NUnitとNuGetとGitインストール 5 Jenkinsインストール 6 Pipeline作成
  21. 21. 1. JDKインストール ※すでにJDKがインストールされている場合はこの手順は不要。 ① Oracle公式サイトからOSおよびCPUアーキに合ったJDKイ ンストーラ(≧v7。推奨はv8)をダウンロード。 URL: http://www.oracle.com/technetwork/java/javase/downloa ds/jdk8-downloads-2133151.html ② インストーラを実行してJDKをインストール。
  22. 22. 2. 環境変数設定 ※すでに環境変数が設定されている場合、ハンズオンのあいだ だけ別のものに変えてもらうことになる。ただし②については Catalina.propertiesや後ほどTomcat起動を行うコマンドプロン プト(あるいはターミナル)で設定するのでもよい。 ① 環境変数JAVA_HOMEを登録。値は先程インストールした JDKのbin/があるディレクトリのパス(bin/のパスではなく その親ディレクトリのパス) ② 環境変数JENKINS_HOMEを登録。値は書き込み権限のある 任意のパス。例えば私の作業時(macOS)は /Users/(username)/Devel/jenkins_home 。
  23. 23. 3. Tomcatインストール ※すでにTomcatが稼働している場合、ハンズオンのあいだは停 止させておいてください。 ① TomcatのCoreのtar.gzをダウンロード(今回はv8.5.x)。 URL:http://tomcat.apache.org/download-80.cgi ② アーカイブを任意のパスに展開(書き込み権限があればどこ でもよい)。 ③ コマンドプロンプト(UNIX系OSではターミナル)で、展開 後のディレクトリの配下のbin/ディレクトリに移動。 ④ startup.bat(UNIX系OSでは*.sh)を実行する。
  24. 24. 3. Tomcatインストール • ブラウザでhttp://localhost:8080にアクセスし、Tomcatの管 理用ページが表示されることを確認する。
  25. 25. 4. NUnitとNuGetとGitインストール ※すでにインストールされパスが通っている場合はそれを利用するの でもよい。 ① NUnit Consoleのzipをダウンロードする。今回はv3.5。 URL:https://www.nunit.org/index.php?p=download ② zipアーカイブを任意のパスに展開する。 ③ NuGet公式サイトにアクセス。 URL:https://www.nuget.org/ ④ [Install NuGet]下の[All downloads]リンクをクリック。 ⑤ バージョン3.4系の最新版exeをダウンロードする。 ⑥ exeを任意のパスに配置する。 ⑦ Gitの公式サイトにアクセス URL:https://git-scm.com/downloads ⑧ OSおよびCPUアーキに合ったインストーラをダウンロード。 ⑨ すべてデフォルト設定でダウンロードする。 macOSでは不要。 Xamarin Studioがインストー ル済みなら不要。
  26. 26. 5. Jenkinsインストール 初期設定まで • 公式サイトからwarファイルをダウンロード。今回はv2.31.x。
  27. 27. 5. Jenkinsインストール 初期設定まで • Tomcatのアーカイブ展開後のディレクトリ配下のwebapps/に jenkins.warをドロップ。 • warが展開されディレクトリが作成されるのを待つ。
  28. 28. 5. Jenkinsインストール 初期設定まで • ブラウザで http://localhost:8080/jenkin s にアクセス。 • 初期パスワードの入力を求め られるので、指定されたパス に作成されたファイルに記述 されている文字列を入力。 • [Continue]クリック。
  29. 29. 5. Jenkinsインストール 初期設定まで • インストール方式を質問され るので、(今回は)[Install suggested plugins]をク リック。 • プラグイン・インストールの 進捗を示す画面が表示される ので完了まで待機する。
  30. 30. 5. Jenkinsインストール 初期設定まで • 管理ユーザの作成画面が表示 されるので、右図のように入 力する。 • [Save and finish]をクリッ ク。 • 「Jenkins is ready!」という メッセージが表示されること を確認。 ※言うまでもないことですが、 本番利用に際してこんなお粗 末な設定はしないでください。 ユーザ名 admin パスワード admin フルネーム admin メールアドレス admin@example.com
  31. 31. 5. Jenkinsインストール パイプライン作成まで • トップページ左側メニューで[Jenkinsの管理]をクリック。 • 遷移先のページの一覧から[プラグインの管理](もしくは [プラグインマネージャー])をクリック。 • 遷移先のページで[利用可能]タブを選択。 • 右上のフィルター欄に「NUnit」と入力。 • 一覧に表示された「NUnit Plugin」のチェックボックスをON。 • [ダウンロードして再起動後にインストール]をクリック。 • 処理完了を待つ。 Windowsでは手動で再起動 Tomcatごとやっちゃってく ださい
  32. 32. 5. Jenkinsインストール パイプライン作成まで • トップページ左側メニューで[新規ジョブ作成]をクリック。 • 遷移先ページの[Enter an item name]欄に 「MyFirstPipeline」と入力 • その欄の下の一覧で[Pipeline]を選択。 • ページ最下部の[OK]をクリック(ここでジョブの設定画面 に遷移する)。
  33. 33. 5. Jenkinsインストール パイプライン作成まで • [古いビルドの破棄]チェックボックスをON。 • [ビルドの保存最大数]に5(くらい。任意)と入力。 • [Pipeline]セクションの[Script]欄にスクリプトを記述し ていく(次スライド以降参照)。 • ページ最下部の[保存]をクリックして設定を終える。
  34. 34. 5. Jenkinsインストール パイプラインのスクリプト DSL構文の基本構造は以下の通り: node { stage(<stage-name>) { <step-name> <step-params> <step-name> <step-params> <step-name> <step-params> } stage(<stage-name>) { <step-name> <step-params> <step-name> <step-params> <step-name> <step-params> } }
  35. 35. ターミノロジー • ステップとは? • ある単一のタスク。例えば、shステップを使ってshell上でmakeコマ ンドを実行するなら sh 'make'と記述する。 • Pipeline機能に対するアドインは一般にこのステップのバリエーショ ンを増やしてくれるものが多い。 • ノードとは? • ステージをグルーピングするもの。 • ノードが実行されると: • Pipelineごとに固有のワークスペース(ディレクトリ)が作成される • そのディレクトリがカレントディレクトリに設定される • ノードに含まれる各ステップが順番にJenkinsのタスクキューに登録される • ステージとは? • 1〜N個のタスクをグルーピングして名前をつけるためのもの。 • 名前はPipeline実行結果の表示に反映される。 ※1 あまり…というか「ぜんぜん」詳しくないが公式の解説ページは右のURL: https://jenkins.io/doc/book/pipeline/ および https://jenkins.io/doc/book/pipeline/jenkinsfile/
  36. 36. どんどん書いていきましょう・・・ ① node { ... } ② ブレース括弧の中に: 1. def msbuildExecutable = '/path/to/msbuild.exe' 2. def nugetExecutable = '/path/to/nuget.exe' 3. def nunit3ConsoleExecutable = '/path/to/nunit3-console.exe' 4. def gitRepositoryUrl = 'https://github.com/exmaple/example.git' 5. def slnName = 'Example.Solution' 6. def testProjName = 'Test.Example.Project'
  37. 37. Clean/Checkoutステップ ① stage('Clean') {...} ② ブレース括弧の中に: • deleteDir() ③ stage('Checkout') {...} ④ ブレース括弧の中に: • git gitRepositoryUrl //←gitRepositoryUrlは先程定義した変数
  38. 38. Buildステップ ① stage('Build') {...} ② ブレース括弧の中に: 1. sh ""${nugetExecutable}" restore ${slnName}.sln" 2. sh ""${msbuildExecutable}" ${slnName}.sln /p:Configuration=Debug /p:Platform="Any CPU"" UNIX系OSではsh、Windows OSではbat。以下同様に適宜 読み替えてほしい。
  39. 39. Testステップ ① stage('Test') { ... } ② ブレース括弧の中に: 1. try { ... } catch(e) { } finally { ... } 2. tryのブレース括弧の中に※1: • sh "mono "${nunit3ConsoleExecutable}" " + "${testProjName}/bin/Debug/${testProjName}.dll " + '"--result=TestResult.xml;format=nunit2" ' 3. finallyのブレース括弧の中に: • step([$class: 'NUnitPublisher', testResultsPattern: 'TestResult.xml', debug: false, keepJUnitReports: true, skipJUnitArchiver:false, failIfNoResults: true]) Windows OSでは不要。 ※1 NUnitプラグインは「NUnitテストを実行するためのプラグイン」ではなく「NUnitテストコンソールが出 力したレポートのXMLをJUnitの同様のXMLの形式に変換して、その結果をJenkinsに渡す(発行する)ためのプ ラグイン」なのだそうである。違和感のある挙動だがそういうことなのだからしかたない。。
  40. 40. スクリプトの完成図①
  41. 41. スクリプトの完成図②
  42. 42. ビルド実行と結果確認 クリックしてビルド実行 Pipelineを構成するStageごとに、実行 結果と所要時間が履歴表示される。 テスト結果の履歴(推移グラフ)が表 示される。
  43. 43. 紹介できなかったこと • STやパフォーマンステスト • デプロイ • コミットをトリガーとするテスト • 定期的なテスト • メール通知 • ツールやツールのパラメータに関するパラメータ化 • 複数ノードで構成されるパイプライン • 条件分岐や並列実行を伴うパイプライン • などなど
  44. 44. さいごに
  45. 45. さいごに • 実はB___の過去の環境構築手順にはNUnitのインストール手順 が含まれていた。 • しかしソリューション構成やモジュール実装の具合を見れば、 AC社自身実際には使用できていなかったらしい。 • 以来、「なんちゃってUT」(=いきなりIT)をみんなで漫然 とこなしてきた。 • それで「得られた」ものは? • テストケースを人手で実行しエビデンス作成するための工数の無駄 • 改修のたびUT仕様書を事実上いちから再作成する工数の無駄(仮に流 用しても前任者が何をやったのかさっぱりわからない) • 人手で確認できる粒度にするためのテスト密度の抑制(品質ダウン) • なによりも「ようするに誰も本当のUTはやっていない」という事実 • 調査しようにもさっぱり読み解けないスパゲティコード • 怖くて手を付けられないブラックボックス • などなど(なかなか大した生産性ではありませんか?)
  46. 46. さいごに • 当面は・・・/個人のレベルでは • UTを通じたコーディングスキルUP • 個人的なテストスキルUP • 〃 製造コード品質UP • 将来的には・・・ • 改修のたび不具合を生ぜしめるようなモジュールを焦点とするUT • およびそのUTコードを利用したCI体制構築 • そのまた将来的には・・・ • どんなモジュールであれUT • それらのUTコードを利用した全面的なCI体制構築

×