読者です 読者をやめる 読者になる 読者になる

継続開発のススメ [Python 温泉編]

とりあえず書き出してみました、これから色々修正します。
こうしたら良いと思う、こうしたら良かったの両方がごちゃごちゃっとなってますが、あくまで考え方なので銀の弾丸ではありません。

#bucho

Python 温泉で @torufurukawa と色々話しをしました、いい機会なのでまとめてみます。
自分が色々やっている中で、こうした方がいいと思いますという内容がほとんどです。

@torufurukawa がエントリあげてました、実践的な話しなのでオススメです。
Even More Addicted to Indentation: Python 温泉で開発プロセスの教えを乞う

銀の弾丸はない

開発手法にベストプラクティスはありません。環境、仕事内容、人によってそれぞれでしょう。
そのため、今回書かれていることが銀の弾丸になる事はありません。

開発手法は固定するモノではなく、常々変化するモノです。

沢山のご意見をお待ちしてます。

前提

@torufurukawa の環境

  • 受託開発ではないく、完全に自社開発
  • エンジニアはベストな人数より少ない
  • 使用する言語は Python のみ
  • ウェブ API 開発がメイン

ライブラリの選択

ライブラリの選択というのはどの言語を使っていても難しいモノだと思います。ただここで手を抜くと後々痛い思いをしますし、全てを自前で書こうとするのは余りに非効率です。

ライブラリの選定をしっかりやりましょう。ここではウェブアプリがベースなのでその点で話しを進めていきます。

自分がライブラリを選択する際に注意したいのは安定した開発が行われている、または枯れきっているのどちらかです。他にはテストやドキュメントがあるというのもありますが、まずは関わっている人が多い方が良いと考えています。

そして一つのフレームワークに特化する方が良いです。適材適所という話がありますがウェブはほとんどやることが同じです、内容が軽いモノと重いモノでわけるくらいでしょうか。

ライブラリの環境

ライブラリの選択が終わったら、社内のリポジトリにそれらのソースコードリポジトリを作りましょう。

最近のライブラリはほとんど github や bitbucket 等に公開されていることがほとんどです。それのミラーを社内に保持します。定期的にミラーからデータを取ってきましょう。

毎回外に取りに行くのも良いですが、それよりは社内のほうがスマートです。

ライブラリの更新

あくまで経験則なのですがライブラリは常に最新版に保っておくのが良いです。ライブラリが更新されたらできる限り追従しましょう。ただ更新するタイミングとしてはタグが打たれたタイミングで十分だと思います。

たまにタグを打たないライブラリがあったりします。その際は社内のミラー側に「勝手に」タグを打ちましょう。
プロジェクトで使うライブラリは全てタグが打たれたモノを使います。

ライブラリの更新に伴い、できる限りそのライブラリを使用しているプロジェクトのライブラリ依存も更新しておくべきです。

プロダクト A はライブラリ X のバージョン 1.2.0 プロダクト B はライブラリ X のバージョン 1.4.0 なんていうのはなくしていきます。全てのバージョンをそろえることでメンテナンスコストがかなり下がります。

あげる手間がかかると感じてしまいがちですが、必要になってあげるより一つあげるなら他も一気にあげた方がノウハウがたまったり、バグを見つけたりと色々経験できます。ある程度のプロダクトがあったとしても後で書くテスト等がしっかり書かれていればバージョンを上げるコストはかなり低いです。

ライブラリのドキュメント

公開されているライブラリであればドキュメントが書かれているのも多いので問題無いでしょう。

コストが高いのは自社非公開ライブラリのドキュメントです。公開していればある程度書いたりするのもいいでしょう。他の人が使うことで色々直してもらえたりしますし、もしかするとドキュメントを書いてくれる人がいるかもしれません。

ただし、非公開の場合は話しが別です。基本的には社員しか使わないため、ドキュメントをあまり書く可能性が低いです。

その場合は最低限の使い方だけ README 等に書いておいてあえて書かないというのも手です。またソースコードにコメントさえ書いてあれば困る事はあまりないでしょう。

もちろんきっちりしたライブラリに対するドキュメントがあるのが理想ではありますが、そう上手く行かない事の方が多いです。

自社ライブラリと公開ライブラリ

公開ライブラリで多機能なモノの場合は、自社ライブラリでラッピングしてしまうのもオススメです。たとえば 10 ある機能のウチ 1 の機能しか使わない場合は自社ライブラリ側でその機能をラッピングして、その部分だけ集中的にテストを書いてしまいます。

必要な機能だけ、自分たちのテストが書けるわけです。

欲を言えばその書いたテストを公開ライブラリ側にテストを書いてパッチを送るのもありですね。

開発環境は気軽に整えられるように

社内に全てのライブラリのリポジトリがあれば、あとはプロダクトのリポジトリを更新したら全て必要なライブラリ等が自動的に入るようにしましょう。開発環境を簡単に作れるというのは実はとても重要なファクターです。

これを目指すのがオススメです。git clone | hg clone して make だけたたけばあとは全部用意してくれるが理想ですね。

言語のバージョン

これだけは実はかなりハードルが高いですができる限り統一するのが理想ですが、難しいと思います。その場合は複数のバージョン環境を簡単に切り替えられるようにする事が大切です。

ここは開発環境を気軽に構築出来るというのに結びついてきますね。

コーディング規約を決める

できる限りコーディング規約を明確にすると開発しやすいですしメンテナンスも楽になります。
Python であれば pep8 や pylint などを使ってチェックするといいでしょう。

Google Python スタイルガイド
http://works.surgo.jp/translation/pyguide.html

ルールはルールです。趣味ではなく仕事で書いている以上、ルールはできる限り守りましょう。もしあまりにも会わない場合は理由を説明して理解を求めましょう。ただ拒否するのではなく提案をする事をオススメします。

単体テストと外部テスト

テストは安心を提供してくれますが、開発速度を妨げる負債でもあります。ただテストは必要です。

  • 単体テストはその機能を開発した人の為にその人が書くためにあります。
  • 外部テストは「仕様」と一致しているかどうかを確認するためにあります。

これら二つがあってやっとテストです。単体テストだけ書いてカヴァレッジが上がっていたとしても仕様通りには動く事は少ないですし、外部テストだけ書こうとすると仕様と明らかに違う事や、大きく転ぶ可能性があります。

どちらも重要ですが、書く人を変えるのがオススメです。単体テストはその機能の開発者、外部テストはその機能を開発していない人が書くべきです。

二つのテストを疎結合にすることで、仕様ミスや、実装ミスを見つけやすく出来ます。

CI の導入

継続的インテグレーションツールを導入しましょう。
つまるところ Jenkins や BuildBot です。最近は Travis とかもありますね。

ライブラリのテストやビルドは全て CI にやらせます。外部テストの実行等もです。ローカルでのテストより CI で行うテストを重要視します。

リポジトリ分割

外部テストのリポジトリは製品とは別にしましょう。リポジトリ自体事疎結合にしてしまいます。
感覚的な問題ではありますが、こうすることで無理にでも疎結合なテストを書く事になります。

チャットシステムの導入

Google Apps を導入しているのであれば Google Talk がオススメです。何より発言が GMail で検索できます。ただし複数人数でのグループチャットが出来ません。ただ Google App Engine を使う事で無理矢理複数人数でのチャットを実現することは可能です。

また CI でのエラーなどを XMPP 経由で教えてくれるようにすると良いと思います。

チームの分割

テストチームと開発チームを分けましょう。開発チームは仕様決めの打ち合わせを行う必要がありますが、テストチームは決まった仕様に対してテストを開発するだけなので打ち合わせに出る必要はありません。

チケットレビューと打ち合わせ

これはまだ、解決策はありません。ただチケットのレビューを週1回開発チームで行いましょう。打ち合わせの回数が多いから生産性が上がるわけでもありません。週1回の1時間と時間を決めます。

時間をオーバーしたら、それ以降は次回に持ち越しましょう。余りにも決まらない場合は1日全部仕様決めの日と割り切るのもいいかもしれません。

また打ち合わせをする際は話し合いをするのではなく「決める場」にすることが重要です。事前にある程度提案を用意しておき、問題無ければ決定。問題あればチケットで議論しましょう。

会話だと脱線する可能性が高いです。

また、必要無ければレビューや打ち合わせをしないというのも大事です。定期開催だからといって毎回定期的にやるのもいいものではありません。

1 プロジェクト 1 ファイル

社外に出さない仕様については1プロジェクト1ファイルにします。そのファイル自体はバージョン管理に突っ込みます。

どうせバージョン管理しているのだから積極的にファイルを変更しましょう。打ち合わせの際はそのファイルを印刷して全メンバーに配ります。

フローとしては、このファイルから課題や問題が出てくるので解決したい場合はチケットにします。チケットで議論した後、決まったこと修正されたことをこのファイルに記録していきます。

このファイルには「進行中」のものを書く必要は無く、まだ始まっていないモノと決まったモノだけを書くようにします。

そうすることでチケットが閉じて、始まってないモノがなくなったらあとは仕様を決める必要はありません。