大規模ソフトウェア開発とテストの経験について
DESCRIPTION
吉岡 弘隆、楽天株式会社 『TDD Boot Camp 大阪』 講演資料 25年以上のソフトウェア開発経験について、ソフトウェアのテスト、 日々の作業などを、実例を交えてお話します。TRANSCRIPT
1 楽天株式会社 DU,開発アーキテクチャ部 よしおかひろたか |June 2nd, 2012
よしおかひろたか
TDDBC@大阪
2
本日のメッセージ
開発者の皆さん、
テストを書こう
テストを書く=テストコード+入力データ+期待する出力データ
Excelでテストケースを作ることではない。
よしおか
3
アジェンダ
• 大規模ソフトウェア開発におけるディリービルド&リグレッションテスト
– 民族誌的なソフトウェア開発経験のお話
4
自己紹介
• 楽天、開発部、開発アーキテクチャ部、技術理事 よしおかひろたか
• 2009年8月入社
• カーネル読書会の主宰者、DEBUG HACKS共著 ISBN978-4-87311-404-0
• twitter @hyoshiok http://d.hatena.ne.jp/hyoshiok http://someday-join-us.blogspot.jp/
5
わたしの経験から
• 大規模ソフトウェア開発の現場の経験をお話する。
– ソフトウェア製品開発は受託開発とは相当異なる。
• 事例:
– Oracle8の開発現場
– DEC Rdbの日本語化、国際化
– 日本語COBOL
– Samba3.0国際化対応(オープンソースの場合)
6
Oracleの場合
• 開発環境
• 開発プロセス
• プログラマの日常
• リズム
• チェックアウト、チェックイン
• ディリービルド
• リグレッションテスト
• 学んだこと
7
Oracle 8の場合
• わたしが参加した時期、1995年~2000年
• Oracle8/8iあたりのころ
• 開発環境:Sun Workstation、SunOSからSolaris
• Clearcaseベースの開発環境。
– ファイルの仮想化。一人で複数のブランチを同時に持てる。
• 例えば、Oracle 7.3用、Oracle 8用、Oracle 8.1用。バグ修正、機能ごと、ちょっとした確認用などなど
• check-outしたものはcheck-inするまで他の人には見えない。
8
開発プロセス(Oracleの場合)
• 要求仕様作り(開発者) – 外部API、UIなどを決定する。
• 例:SQLのシンタックス、セマンティックスを定義する。
– リファレンスマニュアルのベースになる。
• 設計(開発者) – APIなどを決定したら、設計&実装になる。
• 実装(開発者) – コードを書く、テストを書く、テストをする
• ディリービルド&リグレッションテスト(自動)
– チェックインされた最新のコードをスクラッチからビルドして、リグレッションテストを実行。
• チェックインしたコードの概要と、テスト結果の概要が日々担当者にメールで送られる
• 常に動くコードが毎日ある。
• 安定化プロセス
– フィーチャーフリーズ(機能追加を凍結する)
– コードフリーズ(重大なバグフィックス以外のチェックインを認めない)
9
ソフトウェア製品開発のプログラマ
• 設計者が実装者でテストも書く
• 一つの機能については、すべて知っている。
• コーダーという人がいるわけではない。
10
プログラマの一日
• 朝会社に来る。
• コーヒーでも飲みながら、メールをチェックする。
– 担当のテストを確認する。
• 自分が昨日チェックインしたコードがリグレッションテストを壊していないか。
• 他の人のチェックインが、担当テストを壊していないか。
• 壊れている場合は、調査する。あるいは調査を依頼する。
• 仕掛の作業を行う。
– コードを書いたり、テストを流したり、あれやこれや。
– 全テストを流すと時間がかかるので、サブセットを流す
– コードが安定したら当該ブランチの最新版にマージする
• 自分の環境で動作確認ができたら、
– 同僚にレビュー依頼をして、コメントをもらう。特に問題がなさそうの場合、リリースマネージャーにチェックインの許可をもらう。
• 許可が出たら、チェックインする。
– 次の日はどきどきしながらリグレッションテストの結果を見る
• 休暇の前に確認しないでチェックインをするな、という不文律
– http://d.hatena.ne.jp/hyoshiok/20040516#p1
11
リズム
• チェックアウトして
• コードをいじって、テストを書いて、
• テストを実行して、OKになるまで繰り返して、
• 同僚にレビューしてもらって、
• リリースマネージャに許可をもらって、
• チェックイン
12
チェックアウト、チェックイン
• 複数のブランチを同時にいじっている
• バージョンがいくつか
• それぞれについて、バグフィックス、機能変更、機能追加、機能ごとに別々のブランチを切っておく。
• 最新のバージョンでバグフィックスしたものを昔のバージョンに適用することもある。(バックポート)
13
ディリービルド
• 毎日大量のチェックインがある。数十~
• 最新のソースからビルドする。
– コンパイルエラーが出るチェックインは無条件にロールバックされる。
– 複数のビルドマシンで分散ビルド
• 安定性に差こそあれ常に動くものがある。
– Oracle8の最初のビルドは前バージョン(Oracle 7.3)と同一。ここから始まる。
14
リグレッションテスト
• ディリービルドされた最新の実行イメージでリグレッションテスト(数千)を実行する – 10数台(?)のサーバーマシンで何時間もかかる。
– テストコード、入力データを与えて、期待する出力と実際の出力の差分を見る
– diff(差分)が出たらそれを目視確認する。期待する結果なのか、いなか。
– 新機能追加、バグフィックスの場合は対応するテストの追加、修正などを行う。
– リグレッションテストがあるので、既存の機能の予期しない影響がすぐにわかる。リグレッションの発見。
15
安定化プロセス
• あるクライテリアで、安定化プロセスに入る。
– 新機能の追加を凍結する(feature freeze)期間に入る
– バグ修正だけを行う
– リグレッションテストのdiffの数を減少させる
– テストの追加、実行だけをやって、製品の安定化を図る。
– あるクライテリアで、重大なバグ修正以外は一切変更を認めない(code freeze)期間に入る。
– バグ(不具合)はリリースノート等に記載し出荷する
16
学んだこと
• ディリービルドによって、常に動作が確認されているものがある。 – どの機能が実装されていて、どの機能が実装されていないかが一目でわかる
– 実装すべき機能のプライオリティが変更になったとしても、すぐに対処可能
– スケジュールが遅延した場合、どの機能を落とすかの判断が容易に可能。(どれが動いているかいないかを把握できているので)
– Oracle 8開発開始時には、オブジェクトリレーショナル機能が目玉とされていたが、競合が競争力がなくなって行ったので、その機能の多くは次バージョンへ。
• 大規模ソフトウェア開発において俊敏性を高めるベストプラクティスで、ソフトウェア製品開発では広く利用されている。(例:マイクロソフトのOS開発など)
• 闘うプログラマー http://books.rakuten.co.jp/rb/6130084/
17
DEC Rdbの日本語化、国際化
• ソフトウェアの日本語化プロセス
• ビルド環境って
• インターネット以前のソフトウェア開発
• 学んだこと
18
DEC Rdbの場合
• ソフトウェアの日本語化プロセス – 米国本社で開発されたソフトウェアを日本で日本語化した。(別のバイナリーになる) • 1980年代後半のころ
• 参加人員:日本側開発者3名~。US側は100名前後
• 開発環境の入手 – ソースコードの入手
– ビルドスクリプト
– テスト環境
• 開発環境構築 – VAX/VMS、OSの違い、コンパイラの違い、その他ツールの違いなどなどで一筋縄では行かない場合も
• 実際の開発 – ビルド&リグレッションテスト
19
ビルド環境
• 開発環境を日米で完璧に一致させることは難しい
– もちろん仮想化環境などはない。ツール、コンパイラ、OSのバージョン
• 社内ネットワークはあったが回線が細い
– 100MBをコピーするのに足掛け3日とか
• リグレッションテストの結果を確認するのが難しい。(開発環境が微妙に異なるので)
– 安定化させるのに2~3ヶ月かかることも。
20
インターネット以前のソフトウェア開発
• 大規模分散開発だったのだけど、 – 社内ネットワークの帯域は細かった
– コミュニケーションは、メール、電子掲示板(VAX Notes)
• 最終的には、本社に乗り込んで、ソースコードをマージした(1990年ごろ)
• DECはOS(VMS)、ハードウェア(VAX)、ミドルウェア(Rdb)、コンパイラ、ツール、その他すべて内製品。垂直統合型企業
• SQA (Software Quality Assurance)という部隊があった。 – OS/HW/ミドル:各レイヤーの互換性をリグレッションテストで確認
21
学んだこと
• 米国本社のエンジニアと一緒に働いた
• すごいエンジニアがいっぱいいた
• ソフトウェア国際化のあるべき姿についてとことん議論できた
• 大規模広域分散ソフトウェア開発のイメージが持てた
22
日本語COBOLの場合
• 非力なマシンでのソフトウェア開発
• コード管理システム、モジュール管理システム、テスト管理システムなどのお話
• バグ管理
• エンジニアのイロハを教えてもらった
• 学んだこと
23
プロジェクト概要
• 日本語COBOLの開発
– 1984年~
– 3人(自分は新卒プログラマ)
– 開発環境、VAX/VMS
– 言語:BLISS、SCAN(独自の言語)
• コード管理システム、モジュール管理システム、コンパイラ、テスト管理システム、バグ管理システム、すべて自社製
24
• 夜中の0時に、ビルドのバッチが動き出し、その後テストを実行する。
– チェックインしたファイルのdiffをメールするようにした。
– 見よう見まねで、makeファイルを書いた。
– テストスクリプトもテスト管理システムを利用して書いた。テスト結果もメールした。
• チェックインの数、発見したバグの数、修正したバグの数などをグラフにすると、週単位での進捗が見えた。(手書きw)
25
バグ管理
• テストプログラムは、自分以外が実装した分について書いた。(他人のコードをテストする)
• 発見したすべてのバグはバグデータベース(自作)に登録した。
– 110件くらいバグを発見したと思う。
– バグの分析などもした。3割くらいが未実装。
26
新人のしつけ(自分のこと)
• コードを書くとは?
– 「プログラム書きましたよ」
– 「あれー、どこにある?チェックインした?」
– 「チェックインしました」
– 「あれコンパイルできないぞ」
– 「コンパイルエラーとりました」
– 「ところでテストした?」
– 「していません(てへ)。」
– 「…(怒)」
27
エンジニアのイロハを教えてもらった
• マニュアルを読むこと
• テストを書くこと
• デバッグの仕方
• 質問の仕方
28
学んだこと
• 社内にはすごい人がいっぱいいる
• 自分もそうなりたい
• ソフトウェア開発プロセスのイロハ
• 大規模分散開発のイメージ(未来像)
• ソフトウェア国際化のイメージ(未来像)
29
Samba3.0国際化対応の場合
• オープンソースとコミュニティの対応
• 新参者がコミュニティに入るには
• プロジェクトの流れ
• オープンソースの都市伝説
• プログラマの日常
• リズム
• 学んだこと
30
Samba3.0国際化
• プロジェクト概要
– Samba2.xは日本人コミュニティが開発した日本語パッチがあったが、Samba3.0になって、内部コードがUnicodeになったため当該パッチが利用できなくなりShiftJIS関連の問題が発生した。
– Unicode対応、テストの追加など
– 2003年ごろ
– http://www.miraclelinux.com/technet/samba30/index.html
– http://d.hatena.ne.jp/hyoshiok/20041022
31
オープンソースとコミュニティ
• 高い技術力とdisciplineを持ったハッカーによって構成されている
– 企業の開発者は企業の利益拡大
– 企業の開発者とコミュニティのハッカーの利害が一致するとは限らない。しばしば相反する。
• パッチを送ったからといって受け入れられるとは限らない。
– 技術的な問題というより、しばしばコミュニケーションの問題だったりする
32
新参者がコミュニティに受け入れられるには
• 何の実績もない人が受け入れられるには
– 技術の問題ではなくコミュニケーションの問題と認識した
• Samba-jp(日本のコミュニティ)とSambaのコミュニティの関係。両方に受け入れられる必要がある。
– テストをどんどん作って、発見した問題をバグデータベースにどんどん登録した。チームのメンバーは個人名で登録。
– ついでにパッチなども投稿した。個人名で投稿。
– 直接会って話したり、メール、チャット、電話会議などで、プロジェクトの紹介などを行った。
– コミュニティにデビューするには、自分たちの技術力を理解してもらう必要がある。バグフィックスは最初の一歩。
– 大きなパッチをいきなり送るのではなく、小さいバグフィックスの積み重ねで、徐々に信頼を得ていく。
33
プロジェクトの流れ
• ディリービルド、リグレッションテストの開発環境を準備した。
• Sambaのテストフレームワークを利用し
– テストケースの作成
– テストコードの作成
– テストの実施
– 不具合をbugzillaに登録
– 修正パッチを投稿
• 機能追加、修正などのパッチを適宜投稿。本家にマージしてもらう。
• 英語のホームページ、ドキュメントなども用意した
• フェースツーフェースの会議、メール、チャット、電話など様々な方法をとった
34
オープンソースの都市伝説
• ハッカーは無法者?
– 極めて高い技術力とdiscipline(規律)を持つ
– コミュニティの価値を大切にする
– プロフェッショナルである
35
プログラマの日常
• やることリストの確認
• Bugzillaのチェック
• テストの追加
• パッチの作成
– リグレッションが起こっていないことを確認
– 新機能が実装されていることを確認
• コミュニティへ投稿
– メーリングリスト、電話、チャット、などなど
36
リズム
• 作成したテスト数が見える
• バグの数が既知
– 最初にテストがあるので、そのテストで発見した数が初期値になる
– Samba3.0は今ここにあるが国際化の機能がない。(バグの数=実装すべき機能)
• バグの数を減らしていくのがリズム
37
学んだこと
• OSSもテストファーストできた
• 何をやりたいかをテストで表現したWHAT
• テストを作ることによってオリジナル製品の挙動を深く理解した
• プロジェクトマネージャーとして、プロジェクトの進捗が、テストの進捗、残バグ数によって見える化されているので、安心。
38
ちょっとした思い
• プロフェッショナルって
• 変化を許容すること
• プログラマに必要な3つのチカラ
39
プロフェッショナルについて
• ソフトウェアは人が作る
– 自分がプロフェッショナルになるしかない…
– アスリートが毎日トレーニングしているようにわれわれはトレーニングをしているだろうか
40
変化を許容することについて
• 環境は変化する
• 自分は変化しているだろうか
• 成長しているだろうか
41
プログラマに必要な3つのチカラ
• ソースコードリーディング
• テスト
• デバッグ
• ワークショップや勉強会を開催していきたい~~~
42
経験則
• テストを書かない
プロフェッショナルはいない
(プログラマ的な意味で)
• テストのないコードは
レガシーコードだ。
• 読書会しましょう~
レガシーコード改善ガイド
保守開発のためのリファクタリング、翔泳社
http://books.rakuten.co.jp/rb/6121689/
43
• 公理1:すべてのプログラムは
テストをしなければいけない。
• では、どうテストをするか
– A:人がやる
– B:テストコードを書いて、それを実行する
– 正解:B
– 証明:自明。
44
テストを作ると
• システムの振る舞い(WHAT)を
記したことになる
– テストを作ることによって、システムの深い理解を得られる
– 安心感を得られる(心の平静を保てる)
45
テストがあると
• 変更の影響が即座にわかる
– 影響範囲がわからなくて、
塩漬けではなく、
どんどん積極的に変更できる
>変更容易性、アジリティ向上
– 安心である。(心の平静が保てる)
46
テストがあると
• 機能を確実に実装したことを
確認できる。
– 手作業による確認は、もれやミスが発生する。コストが高いし、なにより楽しくない。
– 機械が実行してくれるので、楽である。
– 安心である。 (心の平静が保てる)
47
テストがあると
• 変更容易性があがり、
運用コストが下がる
– OSやHWなどシステムを変更したときも、その影響がすぐにわかる
– 安心である。 (心の平静が保てる)
48
開発者の皆さん、
テストを書こう
テストを書いてプロフェッショナルになろう
世界へ行こう
ご参加
おまちしてます