メインページに戻る
Japan Blog

ToTT



Google のソフトウェアエンジニアはプログラムの動作を確認するためのテストプログラムも自分で書いています。効率的なソフトウェア開発にはテストプログラムが不可欠であると考えているからです。

テストプログラムの作成を効率化するために、Google ではちょっと変わった方法でノウハウを社内に広めています。その方法とは、個々のノウハウを紙一枚にまとめてトイレのあちこちに貼ること ( 建物の都合上、東京オフィスでは別の場所に貼っています ) 。Testing on the Toilet と社内では呼んでいます。用を足している間に読み終わるように簡潔にまとめてあります。

Testing on the Toiletのポスターを示す画像。

以下ではそのうちの一つである「 Guiceによるフラグの分離 」をご紹介します。

あるプログラムがコマンドラインフラグをスタティック変数に格納して使っているときに、どのようにテストプログラムを書いたらよいか、考えてみます。あるテストプログラムがフラグの値を変更すると、それ以降に実行されるテストが影響を受けます。これは、テストの分離という観点から望ましくありません。フラグの値を変更する全ての箇所に、値の保存と回復を行うコードを書く、というやり方もありますが、それでは間違いが起きやすく、コードも読みにくくなります。

Google がオープンソースソフトウェアとして公開している Guice (「 ジュース 」と読みます ) は Java 用の Dependency Injection フレームワークです。Guice を使えば、例えば以下のようにして、フラグの値をそれを使うオブジェクトに inject することができます。


public class MyClass {
private double rpcTimeout;

@Inject
public MyClass(@RpcTimeout double rpcTimeout) {
this.rpcTimeout = rpcTimeout;
}

// ... use rpcTimeout here ...
}


@Inject アノテーションにより、コンストラクタのパラメータとして値を inject することが指定されています。また、inject する値は、@RpcTimeout アノテーションで指定されています。


@Retention(RUNTIME)
@Target(PARAMETER)
@BindingAnnotation
public @interface RpcTimeout {}


フラグの定義は MyClass でなく Guice モジュールで行うようにします。


public class MyModule extends com.google.inject.AbstractModule {
public final double rpc_timeout =
コマンドラインフラグに従って値を設定する;

protected void configure() {
bindConstant().annotatedWith(RpcTimeout.class).to(rpc_timeout);
}
}


こうしておくと、プログラムの通常実行時には Guice はコマンドラインフラグの値に基づいて MyClass のインスタンスを生成します。一方、テストプログラムにおいては、コンストラクタに直接値を渡すことで好きな値を設定できます。

Guice を使ってできることは他にもあります。ぜひ Guice のページもあわせて御覧下さい。