社内でテスト駆動開発をどうやって始めるか
思い立った背景
今の会社ではxUnitテストをしておらず、このままだとコードのメンテナンスが大変になってしまうので
Unitテストを今年から導入していきたい。
いくつかのプロジェクトで、開発途中の状態からテストを追加したり、保守フェーズの時にテストを追加したりしてきた経験の中で、
こうしたほうが良いのではないかと思ったことをまとめてみようと思った。
※ 私がテスト駆動開発(TDD)をちゃんとしたことが無く、書籍や動画で見た内容と上の経験からこの様に実施していこうという内容になるので、このやり方が正しいというわけではないです。
実際にどうするかを詳しく知りたい場合は、下の様な本を読むことをお勧めします。
プロジェクトで実施しようとしたときによくある話
Unitテストをしたことが無いメンバー達に、「やりたいんだけど」と話をすると
きっと下のような話が上がると思う。
プロジェクトマネージャとか営業から
- テストを書けばシステムの品質が上がるんでしょ。
- 一回書けば、テストをしなくてもよくなるんでしょ。
- テストコードを書くための予算をとれない。
ディベロッパーから
- テストコードを書いている時間かない。
- テストがしっかりと網羅されているかわからない。
- どこまでをテストすればよいか不明。
これらはどれも正しいけれども、間違ってもいます。
これは「Unitテストでどこまでの事をテストするか」という事がチームで共有されていないことが原因。
Unitテストでは、
のどれを行うのか。という認識を共有する必要があると思います。
ディベロッパーは動作検証と思っていたが、営業は受け入れテストをしてあると思って、
「自動化させているのでテストはすぐ終わるんですわ。」
って話をしてしまい、ディベロッパーが苦しむ。
なんてこともあるかもしれないのです。
テスト初心者はどこから始めていくか
プロジェクトマネージャやプロジェクトリーダーは、受け入れテストをしたがると思うが、 それをしようとすると、
- 当初の計画になかった作業(テスト用にDBを作ったり)が発生する。
- テストが複雑なものになりがちなので、テストコードを書くのに時間が必要。
になってしまい、前述の不毛な言い争いが始まってしまう。
なので、動作検証のテストを実施するところから始めるのが良いと思う。
テストについて話しているPodCastでも、動作検証のテストを自動化させているような感じに聞こえるので、
ここからやってくのが常套手段なんじゃないかな。
”どのクラスのテストをしていくか”だけど、ドメイン駆動な感じの実装ではなく、MVCな感じで実装がされていると思うので
Mの部分でやっている事や共通で使用する便利クラスに対して実装していくのがいいかと思われる。
例えば、ModelとかServiceとかUtilityとかがメソッドが分かれていてしやすいのではないかと思います。
テスト駆動開発の進め方
和田卓人さんの動画が非常にわかりやすいので、こちらを見てください。
※ 少し長いので2倍速でみてもいいかも。
テストをどこまで書けばいいのか
和田さんがゲストで出演したPodCast - ajitofm 13: Test Driven Developmentで話題に上がっていたのですが、
「不安に思った所をテストすればいいんだよ」
と言っていました。
なるほどです。
最低限の動作検証のテストは行い、自分が「このパターンの時、思った通りに動くか不安」と思ったらそのテストも追加しろというわけ。
分かりやすい。
そんなルールだと個人差が出るじゃないかと思うかもしれないが、どんなにルールを作っても個人差が出るので同じ事。
経営陣とディベロッパーが言っていた内容について
品質が上がるのか問題
「動作検証では品質の向上や担保ができないんじゃないか?」と聞かれるかもしれません。
開発初回では、メンバーがちゃんと動作検証を行うような人がそろっている場合は、実質変わらないかもしれません。
その後に、仕様の追加などで変更があった時やリファクタリングをしようとしたに、
「以前作った箇所は動きが変わっていない」
ということが担保できるので、後々で品質保証ができる。
質の向上に関しては、フィーチャを作成しているときにテスト(どのように動作させたいか)を考えながら作らざるをえなくなるので、
質が自然と上がると思われます。
テストコードのレビューが最初は必要になるかもしれませんが。
テストコードを書いている時間がない問題
フィーチャを実装する時に絶対に動作検証を行っていると思います。
それは画面から動かすのか、メソッドを呼び出しているのかは場合によると思いますが、
その時間がテストコードを書く時間になるだけなので、そんなに時間は変わらないかと思います。
単体テストはするのか問題
現段階ではテストは動作検証しかしていないので、単体テストはしていない状態ですのでするべきかと思います。
単体テストも自動化させる場合は、テスト項目を洗い出してユニットテストとは別で管理するのがいいかと思います。
きっとテスト漏れが起きると思います。
個人的には単体テストは目視での確認など下ほうが良いと思っています。レイアウトの確認などもあると思うので。
テストをやりやすくするために
テスト駆動で開発をするなら、テストがしやすくないと開発がしにくいということ。
なので、プロジェクトで「どのクラスがどんな役割を担うのか」ということをチームで共有することが大切になる。
その為の良い設計がドメイン駆動開発(DDD)であり、チームがスクラムであることかと考えています。
現実問題として、スクラムを組める環境じゃなかったり、メンバー全員にDDDについて簡単にでもわかってもらうには時間がかかると思うので、
「いつでも、なんでも、どこでも、発言ができて、それに対してチームからリアクションがある」チーム作りをしておくことが大事。
それでもやらないとか言われる時
やらない理由を探す人によって邪魔をされる時は、
自分一人でいいから先に軽くやっちゃって、それに共感してくれるメンバー(フォロアー)を作り、「やっちゃおう」という雰囲気を作ってしまえば、
いつの間にか定着すると思います。
最後に
同じような確認を何回もして時間を浪費していたあの頃とはおさらばできることを信じて、社内の開発に浸透させていこうと思います。
ちょっと強引にでもw
Backlogでpull requestがあった時に、自動で静的解析ツールが走る様にしてみた。
※ 一応これでも動くのですが、あまり良い実装じゃないので参考程度にしてください。
はじめに
会社でチケットベースでの開発 + Git が定着してきて多少なりにモダンな状態になったが、 作業者ごとにレベル差があってレビューの時間が結構かかるのが問題だった。 コーディング規約に沿っているかとか、簡単なバグは静的解析ツールに任せればレビューで見る箇所が減るのでは。 という事で、Jenkinsを使ってCIをする事に。 いつもはphpだけど、今回はjavaで。
やる事
- AWSにJenkinsをインストール
- Backlogでpull requestがあった時、Jenkinsが色々チェックする。
- エラーがあった時、JenkinsからSlackへ通知
とりあえず、これらが出来ればいいかなと。
AWSにJenkinsを準備する
AWSにJenkinsをインストール
- AWSのEC2を適当に作成します。(Amazon Linuxを使用しました)
- セキュリティグループで8080ポートにアクセスできるようにインバウンドに追加します。
- Backlogのwebhookが取れるように下もインバウンドに追加します。
カスタム TCP ルール TCP 8080 - 9999 54.238.59.48/32
sudo yum -y install java-1.8.0-openjdk-devel # インストールが行われる # java1.8をデフォルトにする $ sudo alternatives --config java 2 プログラムがあり 'java' を提供します。 選択 コマンド ----------------------------------------------- *+ 1 /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java 2 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.25-0.b18.4.amzn1.x86_64/jre/bin/java Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
- java --verson で1.8であることを確認する。
$ java -version openjdk version "1.8.0_25" OpenJDK Runtime Environment (build 1.8.0_25-b18) OpenJDK 64-Bit Server VM (build 25.25-b02, mixed mode)
- jenkinsをインストールする。
# Jenkinsをダウンロード sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo # パッケージ署名チェック用のキーをインポートする sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key # jenkinsのインストール sudo yum install jenkins
- jenkinsを起動する
sudo service jenkins start
起動されたら、http://public DNS:8080 にアクセスしてjenkinsの画面が立ち上がるのを確認する。
推奨プラグインはインストールしてもらう。
- jenkinsの起動設定をする
sudo chkconfig jenkins on
静的解析に必要なプラグインをJenkinsに入れる。
- Gradle plugin - gradleを使うため
- FindBugs Plug-in - バグ解析用
- PMD Plugin - コードのチェック
- checkstyle - コーディング規約チェック
- Violations plugin - 静的レポートの集計表示
- JaCoCo plugin - コードカバレッジの算出
- Task Scanner Plug-in - TODOの収集
- Jenkins Backlog Plugin - backlogのgitにアクセス
これらをインストールしていく。
ちゃんと動かせなかったので
JenkinsとGradleの知識が薄すぎて、上手い事実行する方法がわからず、 考える前に試したいので、Jenkinsでsudo でgradleを実行できるようにします。
sudoをjenkinsに付与
# こんな感じで設定する sudo visudo # Defaults !visiblepw Defaults visiblepw root ALL=(ALL:ALL) ALL jenkins ALL=(ALL) NOPASSWD:ALL # 再起動 $ service jenkins restart
gradleをインストールする
こんな感じでインストールする。(パスは適当なところを使用してください。)
cd ~ wget -N https://services.gradle.org/distributions/gradle-2.0-all.zip unzip gradle-2.0-all.zip -d ~/gradle ln -sfn ~/gradle/gradle-2.0 ~/gradle/latest printf "export GRADLE_HOME=~/gradle/latest\nexport PATH=\$PATH:\$GRADLE_HOME/bin" > /etc/profile.d/gradle.sh
Jenkinsの準備はこれで終了
これで、取りあえずJenkinsの準備ができた。 次は、backlogのwebhookをとれるようにして、静的解析が行われるようにする。エラーがあればslackに通知をやっていく。
参考サイト
ソースレビューにJetBrainsのUpsourceを使ってみる - PhpStormとの連携
全てをIDEで完結させる。
前回、Upsourceのインストールと実行をしたので 次はPhpStormからレビューの操作が出来るようにしてみる。
プラグインのインストール
- PhpStormのSettingを開く。
- pluginsを選択して検索にupsourceと入れるとプラグインが表示されるのでインストールする。※画面はインストール済みなのでボタンがアンインストールになっています。
- インストールが終わると、Setting -> Tools -> Upsourceが追加されるので、それを選択する。
- Server URLに前回設定したサーバーのURLをポート付きで設定する。
エディタ上からレビューが見れるか確認する
- 設定が終わったら、Upsourceでコメントを入れたソースを開くと左側に吹き出しアイコンが表示されるようになります。※アイコンを表示するのに少し時間がかかります。
- アイコンをクリックすると、右にレビューの内容が表示されます。
- 対応終了のチェックやコメントへの返信なども出来ます。
- PhpStormの下にあるReviewsを選択して検索をすると、
- レビューでコメントがある一覧が表示できます。
- コメントをクリックすると、そのコメントがある場所に移動できます。
レビューのステータスを変更する
PhpStorm上からReviewのOK/NGの設定も行えるみたい。
- Reviewsを開いて検索して、イイネとうーんのアイコンがあるので、それらを押すと
- こんな感じに
- こんな感じにアイコンが表示され。
- Upsourceにもアイコンが表示されてレビューの状態が分かる。
使ってみて
PhpStormで開発のほとんどの作業が出来るようになるので、案件とかで使っていこうと思います。
ソースレビューにJetBrainsのUpsourceを使ってみる - 準備
Upsourceって何につかうの?
VOYAGE GROUPさんがやられているPodcastでJetBrains製品の特集会(?)でそのアプリの存在を知りました。
どんなツールかというと、GitHubとかでPull Requestした時にコードにコメントとか入れるあの機能を SVNとかGitとかでも使えるようになるアプリです。
初めに聞いた時は、GitHubとかのPR機能を使えば別に要らないんじゃないの?と思っていましたが、
Upsourceを使うと、
- PhpStormがしてくれる静的解析を行ってくれる。
- phpDocを見る事が出来る。
- コードジャンプが出来る。
- PhpStormと連携して、IDE上でレビューのやり取りが出来る。
これらの事が出来るみたいです。
ちなみに、PhpStormはこちら www.jetbrains.com
PRのレビュー機能だとテキストでしかコードを見れないので、
- 変更したソースで使用しているメソッドってこれで使い方あってる?
- この変数定義はどんな感じだったかな?
とか、レビューがとても楽になりそうな予感。PhpStormとの連携も気になる。 しかも、10ユーザーまでは無料で使えるそうです。ヤバい!
という事で試してみました。(Windowsで)
まずはダウンロード
ともあれ、公式サイトでダウンロード www.jetbrains.com
- 公式サイトにアクセス。
- プラットフォームに合わせた物をダウンロード。
- ZIPを任意のディレクトリに解凍します。
- binの中に移動してこれらのファイルがある事を確認。
- デフォルトでは80ポートを使用してサーバーが上がってしまうので、設定を変更します。
- ターミナルを起動してbinディレクトリに移動。
- コマンドを実行
bash bash upsource.sh configure --listen-port 11111 --base-url http://localhost:11111
- 設定の変更が終わったら、立ち上げ。
bash bash upsource.sh start
- ブラウザが立ち上がって初期化が始まります。ちょっと時間がかかります。
- 起動が成功すると、こんな画面が表示されます。次にProjectsを押して、プロジェクトを登録していきます。。
- プロジェクトの一覧が出るんですが、最初なので空っぽですね。Create projectを押して登録します。
- ぐわっといっぱい出てきますが、このタブでは緑の枠の所を設定するだけです。
- 次にCode Intelligenceのタブをクリックして Enableにします。JavaScritpとかPHPとか各々の環境に合わせて設定してください。
- Advancedタブを選んで、デフォルトにするブランチ名を入れておくと便利かもしれません。
- 登録が終わると、先ほどのVCSのコミットツリーが表示されます。今回はfix/sampe_testをpushしてPRを送りました。
- ブランチにマウスを合わせるとReview changesが出るので、その中のCreate reviewをクリックするとレビューが作られます
- GitHubみたいな感じでコードにレビューを書いていきます。Reviewrsにレビュアーを設定などもここでします。
- 変数やメソッドをクリックするとphpDocを見る事が出来ます。
- コメントを入れるとこんな感じになります。
- コメントにタグを付ける事も出来ます。バグとかコーディング規約違反とか
サーバーの停止
サーバーを止めたい時はstopを実行
bash
bash upsource.sh stop
レビュー環境の構築はこれで完了
これでレビュー環境の構築は終わり。 ダウンロードとか起動に少し時間がかかるだけで、立ち上げること自体は簡単にできてしまいました。
次はIDEとの連携をさせようと思います。
Travis-CIを試してみた
TDDに恋い焦がれて
プログラムを書いてる途中でも安心したいんです。
実務でテスト駆動で開発をしたいと思い、その環境をどんなものにしようかと思いJenkinsを使って試してみたのですが、 自由度は高くて良かったのですが、その代わりに色々と設定があり いずれは他の人にやって貰うためには少し敷居が高すぎだったので、
いまさら感はありますが、巷で話題のTravis-CIを触ってみました。 googleで調べると色々とやり方が書いてあったような、無いような気がしましたが、 とりあえず、シンプルな感じで動かしてみました。
実際にしたこと
これだけでした。 composerのコマンドを叩かないといけないところでちょっと躓きましたが、簡単です。 知ってればすぐ環境できますね。
www.slideshare.net
いずれは
- developブランチにマージがあった場合は、テスト + 開発にデプロイ
- masterブランチにマージがあった場合は、テスト + ステージングにデプロイ
- masterブランチにタグ付けがあった場合はテスト + 本番にデプロイ
という仕組みにしていきたい。
しかし、問題が
会社がヌーラボさんのbacklogを使用しているので、Travis-CIが使えないという罠・・・。 色々とサービス連携するために、Githubに移行してもらいたいな。
別の物
phpstorm、upsource、youtrack、teamcityとJet Brains製品で固めたい欲求もあり。 teamcityをちょっと試してみようかと思います。
これらを使うと、phpstormだけでほとんど完結してしまうので、社内で広めたい。
スクラムガイド2016を読んでみました 2
実際に何するの?
前回は、大体の登場人物を把握したので、日々何をすべきかってのを纏めてみる。
スクラムを全然知らない人がスクラムガイドをよんでこうだろうなぁって思った内容なので、 間違いがあるかと思いますが、ご了承くださいませ。
まずプロジェクト始まった時にするところから
- PO(お客さんとプロジェクトリーダー)が必要な機能や仕様を洗い出して、何かに登録する。細かく。
- POがその工数を見積もる。その後、メンバーで工数を見積もる。
- ざっくりみんなでガント化する。
- チーム内で、毎日する事、手順、単語、成果物に対する考えとかを共有する。
- スクラムとウォーターフォールの違いを説明する。
一発受注で「ハイ作って」契約だと、こんな感じでやるのが良いのかなと思いました(ので投稿してるときにやってみてます。)
簡単そうですが
ウォーターフォールとか、普通の学生 -> サラリーマンの流れの人の場合、
- 指示を受けてしか作業を出来ない。
- 指示を受けたことの作業しかしない。
の人が多いため、「メンバーで工数を見積もる」すらまともにできませんでした。最初。 なので、こんな感じにしました。
- 最初はこっちで見積もりとガントを作ってしまいます。
- そのあと、見てもらって大丈夫そうか返答をもらいます。
- 1時間毎に目標を立てて、50分間作業、10分振り返り(何で遅れたか or はやかったか)。
- 次に活かそうね!
後で出てくる「スプリント」を決める際の特訓にもなりますね。
あとは、指示待ちが多いので、「なんか詰まってない?」、「それをどうしたいの?」という方向で聞く。 意思を聞く。
多分、はじめは返事が返ってこないと思うし、向こうにお前が決めるもんだろうってイライラされると思うけど、聞く。 仕様については教えるけど、実装方法については自主性を付けてもらわないと困る、だからしかたない。
煙たがられてもいい
そのうち、自分が選択した方法で進めるという事に意味を感じてもらえると思う。
定例を決めて行こう
- スプリントという単位をチームで決める。(ソフト開発なら1週~2週?)
- そのスプリントでどこまでを実装するかをメンバーが決める(POは妥当性だけを確認すればいいかと)
- スプリントが終わったら、コミットできたこと、出来なかったことをみんなで出して、何でそうなったか、対策はあるか?とかを話し合う。
- 次のスプリントのコミットを考える。
簡単そうですが、これがまた思っているようにできない
その週にどこまでを実装できるかを決める。
困りポイント
- 希望でしかない
- 残業前提である
どうしてもガントを守ろうという流れになるので、阻止したい。 最初の見積もり時にこのスケジュールで定時でOKってしたはずなので、19時には帰る流れで出してもらう。
多分、これが現実的にはメンバーからこの条件で出してもらうの難しい(嫌がる)し、昔ながらの上長には怒られると思う。
なもんで、上長には遅れたらスケジュールを延ばせるてもらうとか、そういう手はずをプロジェクト始まる時点で整えておく必要があるかと思います。 自分だけで裏でこっそり球を持っててもいいです。延ばせるようにしておく。
もしくは、即座に後れをキャッチして報告する。今後の見通し込みで。今後このように遅れるので、調整をしてくださいと。
まぁ、頭の固い人相手だと、苦労しますが、出来ないものはできないし、そもそも後でおんなじような報告しないといけないんだし、先にしておいたほうが楽ですよね。多分・・・。
振り返り
困りまポイント
- そもそもの、原因を追究しないで話が終わってしまう。
- 一方的な報告だけになって意味が無い。
そもそもの、原因を追究しないで話が終わってしまう。
前者は、取りあえず「何に」かを追求するしかない。(何で?だとただの知識不足って事になってしまう)
- その詰まりは、俺もしたよ。
- おれ、そのライブラリ作ったけど・・・。まだpushはしてないけどな!
見ないな話が出たりするようになります。きっと。 この時も、その人が「遅れを責められている」みたいに感じるみたいです。
自分でやるっていった範囲が出来なかったので、そう思うのはしかたないですね。 次のスプリントの際に「自分でやるっていった範囲」が身の丈に合う様にセットしてもらうしかないです。それのせいで遅れが出るとしても。
他の人に、「進んでいたらキャッチアップして助けてあげて」と声をかけましょう。 まぁ、最初はいい顔はあまりしませんがw
一方的な報告だけになって意味が無い。
最初に、みんなにやりたい報告に仕方を言いましょう。 そして、意見を聞く時に個人あてで振ってみましょう。 たぶん、うまくいかないですが orz
振っても意見が出ない時に、俺はこう思うんだけど、どうです?って聞くといいかも。
これらの困りポイントが出る原因が
「リーダーから指示がきて、それをやる」 という、命令系統ができてるって認識があるから起きるんだと思います。
フラットにやるんだよ。って伝えるの難しい。
スクラムの運用の手順は
やる内容は簡単なんです。 その中身のクオリティをあげるのが難しいというか、 形骸化してしまっている内容を、しっかりとした目的をもってやるというのが大事。
その為には、
個々にチームの一人であるという認識を持ってもらう必要がある
と思いました。実践してみて。
「集まり」ではなく「チーム」。
次は、もう少し大きいスパンでの振り返りと、まとめとか
スクラムガイド2016を読んでみました
スクラムを基礎から学んでみたいそう思った。
なんでスクラムを?
- 今行っている会社では、SESや請負開発を主にしているのですが、 相手企業がアジャイル的な開発を進めている場合はそれっぽいことができるのですが、 こちらも、相手企業も体系的にスクラムなどを学んでいるわけではなく、それっぽいものをやっていだけなので、 結局のところ力業で進めてる。
- 相手企業に説明する力がないので、向こうの手法に準ずるしかない
- そもそも自社がウォーターフォール開発してる・・・(ツライ)
って状況が嫌だ!
という漠然とした理由とともに、、、
いつもの
という、単純に興味持っただけだったりもします。 いや、取り入れれるものならやってみたいので取り入れますよ。
でも、いきなり重たいのをやりたくないから、ガイドを読んでさらっと学んでみよう。
Scramに出てくる人
ざっと、4種類の人がでてきて、 それぞれを現実世界に照らし合わせると、
こんな感じ。
「スクラムに詳しい人」なんていねーよ
ガイドを読んだうえで、こんな感じかなぁってのを上げてみますが、 間違っている部分があるかもしれません。 LTみたいな感じで暖かく見てください。
ステークホルダーの役割
- お客様
- 偉い
- 成果物をチェックする
- フィードバックをする
成果物チェックは受け入れテストを実施してもらうということで、よくあるけど フィードバックがほしいってことを言わないといけないですね。
スクラムマスター
たぶん、この人が最初いないとスクラムをやっていくの難しい。
プロダクトオーナー
- 成果物(プロダクト)の責任者
- WBS(必要な全作業)を洗い出してチケット化
- チームの作業が楽になる事は全部する
- 雑用係・・・
たぶん、雑用する人。でも要。 開発とかは本当はしないのがいい立ち位置なんかなぁって思う。
チームメンバー
- スプリントの目標を立てる
- 実際の作業をする
- プロダクトに対して仕様を満たす責任を持つ
開発者であり、仕様決定者という感じかな。
おさらい
プロジェクトでよくある、
設計者 -> 開発者 -> テスター
って流れではない
ってことをみんなで認識合わせがいりますね。
設計も開発もテストもチームメンバーの1人1人がおこなう
って所が、よくあるの開発現場と一番違う気がする。
具体的には何をするの?
スプリントとかデイリーミーティングとか振り返りとか、色々あるみたいですがそれは次回に。