分12はじめにはじめまして。(⁠株)ミクシィの加藤和良です。技術部に所属しています。技術部は,日記やコミュニティといった特定のサービスに紐づかない,mixi全体を裏から支える部署です。「⁠支える」ための方法は,実際のサービスの一部として動作する共通基盤から,開発効率を上げるために社内で動作しているものまで,多岐にわたります。mixiでは,ここ数年で自動テストの導入が急速に進みました。図1は,mixiのソースツリーにおけるコードと,そのテストコードの毎月1日のバイト数をグラフにしたものです。2008年の頭には少なかったテストが急速に増え,今年の5月にはコード量をも追い越しているのがわかります。携帯電話向けmixiである「mixiモバイル」の開始が2004年,mixiニュースが2006年ですから,2008年当時のmixiも,それなりに大きなアプリケーションであったと言えます。今回は,そのような比較的大きく,歴史あるコードの中に,どうやって自動テストを浸透させていったのか,ある一例をお話していきます。ソースコードとテストコードのバイト数比較データベースとの依存を切り離すmixiでは,ほぼすべての開発者がSSH経由でデータセンターのLinuxマシン上に接続しています。マシンは複数のVMに切り分けられ,それぞれ別の開発者が使用します。個々の開発者は,mixiのフロントエンドにあたる部分だけをそのVM上で起動し,MySQLのようなデータベース,memcached,画像配信系をはじめとするサブシステムについては,ほぼすべての開発者が同じものを共有しています。mixi全体に自動テストを導入する際に,最初に障壁となったのがデータベースでした。一般に,テストを書きやすいコードには次のような性質があります。結果を左右する入力をどこから与えるべきかが明確である結果がどこに出力されるかが明確であるそれ以外の副作用を持たないしかし,2008年ごろのmixiのコードには,これらを備えていないものが多くあり,とりわけデータベースは,テストに対する暗黙の入力であり,出力先になってしまうことがしばしばありました。誰かが友人関係を解消したり,日記を削除したり,といった行動によってテストが失敗してしまうようでは,テストが失敗することは日常茶飯事になり,テストを書く利点が減ってしまいます。テスト自体はうまく動作していても,副作用として,開発環境上の誰かの日記が増えたり,どこかのコミュニティのトピックが消えたり,ということも時折起こっていました。これらの問題を解決するべく,2008年12月ごろにMixi::Test::Fixturesという新しいライブラリが実装されました。Mixi::Test::Fixturesは,RailsやDjangoにある「fixture」のしくみを模したライブラリで,具体的には次のように動作します。テストの実行直前に一時的なデータベースを作成し,各種コードからの接続先をそちらに向ける指定されたYAMLからデータベースに値を挿入するテストを実行するテストの実行直後に,最初に作成したデータベースを削除する当時のmixiでは,SQLのかなりの部分が手作業で書かれていて,O/RマッパはおろかSQL::AbstractやSequelに類するクエリ生成ライブラリも存在していませんでした。そのため,SQL文のかなりの部分がMySQLでしか動かず,また変換するにもフックポイントがありません。結果として,一時的なデータベースにもSQLiteのようなプロセス内で動作する軽量な実装を避け,MySQLをそのまま使っています。Mixi::Test::Fixturesは,その後も継続的に改良が加えられています。今では,memcachedやメールの送信,外部へのHTTPアクセスなども実際の処理が走らないように変更できます。これらは,SQLが使えるようなRDBMSと比べるととても単純なため,Perlで書かれたプロセス内で動作する実装を作り,指定されればそれに差し替えるようになっています。テストをすべて実行するfixtureの導入によって,新しいテストは書きやすく,気軽に実行できるようになりました。一方でソースツリー全体を見渡すと,それ以前に書かれた,実行にいくつかの準備が必要だったり,共有のデータベースを書き換えてしまうようなテストも多く存在していました。コードを変更したあとには,できる限り多くのテストを実行し,変更の正しさを確かめるべきです。実行しにくいテストを取り除き,「⁠テストが失敗することは問題である」と自信をもって主張できる環境を早急に作るうえで,これらのテストの存在は邪魔になっていました。一方で,これらの中には,事前の準備が必要なことを差し引いても,それなりに有用なものも多くありました。そこで,これらをひと思いに削除することはあきらめ,「⁠ブラックリスト」を作ることにしました。ブラックリストは,問題のあるテストの集合です。実際には,ソースツリー内にあるテストのうち,問題のあるものを列挙したリストをYAML形式のファイルとして作成しました。問題が解決したら,リストからそのテストを削除していきます。同時に,ブラックリストを使って「実行可能な(ホワイトな)テスト」を列挙するコマンドも作成しました。始めからホワイトリストを作らなかったのには理由があります。ホワイトリストを作成する場合,1誰でもいつでも実行できるテストを作成した人は,それをリポジトリに追加すると同時に,ホワイトリストにも変更を加える2前準備が必要だったり,自分以外に実行されては困るテストを書いた人は,それを単にリポジトリに追加するという作業が個々の開発者に要求されます。開発者としてより望ましい行動は1です。望ましい行動のほうが手間がかかるというのは,正しいしくみとは言えないでしょう。図2は,導入から現在に至るまでのブラックリストの行数です。340台から一気に減少したあとは,細かな増減を繰り返しながら200台近辺で落ち着いています。テスト全体の件数は増えているので,ソースツリー全体に占める割合は下がり続けているものの,数として下げ止まってしまったのは今後の課題です。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。コードの安全性・安定性を高める開発サイクル~テスト管理の効率を上げ,脆弱性診断を自動で行う~本連載では,連載「業務を改善する情報共有の仕掛け」を受けつつ,安全性・安定性を加えた開発サイクルについて考えていきます。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。