ソフトウェアテストの設計は、ソフトウェアサービスの設計と同じ

今日、「エンジニアが如何にテストに取り組むか」みたいな話を聞きに行ったけど、最初から最後まで何か違和感があった。

勿論テストケースがコケると色々面倒だし、サービスが続けば続くほどテストケースがメンテできなくなってくるけど、
本来、テストケースでエラーが出たときは「テストケースでエラーが出たおかげで、本番リリース前にデグレードが見つかって助かった」と喜ぶべきだし、それを踏まえれば、テストケースのNGが増えてくるのはそれだけサービスが成長してる証として喜んでも良いのではないのだろうか。

そう、「サービスで不具合が起きる事を予防する」のがテストであり、何故それが必要であるかと言えば、「不具合が起きた時のリスク・コストを軽減する」ためだ。

上記を踏まえると「その機能に不具合が起きた時にどれぐらいのリスク・コストがかかるか把握してない」エンジニアがいくらテストを書いてもメンテナンスする価値のあるテストは書けないのではないだろうか。

テストを作る人間、テスト工程を管理する人間がビジネスを理解してなければ、ロクに使われてない機能のためにテストケースのカバレッジを100%にするとか、本番でのバグが検知できない意味のないテストコードとか、無駄なコストや負債が増えるだけではないだろうか。

逆に、エンジニアが「ビジネスモデル」を理解していれば「ほんとうに必要なテスト」というのが自ずと定まってくるはずだ。
「このプロジェクトは仕様が全然定まらないからテストは書けないんだよ」というのは自分が関わってるサービスを真に理解してないエンジニアの言い訳ではないか。

そしてエンジニア以外のサービスに関わってる人達もテストに向き合う方が良いはずだ。ソフトウェア開発は製品と製品の製造ラインを同時につくるものだから、製品のリリースだけに目を向けて、テストを含めた製造ラインを見なければサービスの真のコストは把握できない。

広告

昨日CAのインフラエンジニアの方とランチをして、すごく有意義な時間を過ごせた。

CAの仕事は半年弱受けていたが、その時に知り合いになった方ではなく、偶然twitterのフォロー/フォロワーだったのでこれを機会にランチでもしましょうと以前から決めていて、それを昨日実行してそこで初めて対面した。

その人のツイートはいつも技術系の話題ばかりだったので、会う前はナードな感じの人かと想像していたが、実際に会うと朗らかでありながら礼儀正しく、私服であっても、奇抜さやだらし無さもなくて、とても紳士的な印象だった。

実際に話した感想は「CAにこんな人がいるのかぁ」といった感じだった。

僕が今までに知り合ったCAの若手エンジニアが持っている「技術に関するどん欲さ」と、エンジニアとしてのキャリアの長さを感じさせる「仕事に対する冷徹さ」を併せ持ってる様な人で、単なる世間話以上の有意義な話ができた。

「初心を保ちながら経験を活かす」「目の前のタスクに夢中になりつつ、客観的に仕事を俯瞰する」こういう相反する事がバランスよくできれば、仕事で不安を覚える事も無いんだろうな。

PHPのTraitをやたらと使って感じたこと

以前、php5.4のプロジェクトに関わっていて、
そこのプロジェクトの方針でやたらとTraitを作っていたが、Traitの多用は「鬼門」だと正直思った。

class MyModel extends BaseModel 
{
    use User;
    use Photo;
    use Album;
    use Relation;
   //....
   //....
   
   public function getData($id) 
   {
        $tmp = $this->getFriendList($id);      //どのTraitに実装されているか
        return $this->getPhotoSet($tmp);       //調べるのが結構たいへん!
   }
}

NetBeansの場合はtraitのコード補完・関数ジャンプの機能があるからまだ楽だけど、
それでも実装があちこちに飛んでしまうのは階層の深い継承と同じストレスがあるし、
Traitの関数名を迂闊に変えるて、他のTraitの関数と名前が衝突してしてコンパイルエラーが起こるので、多重継承と同じストレスもある。

しかし、継承を使わずにプロパティにアクセス出来る実装を使いまわせるのは便利だった。

例えば、SPLにあるArrayAccessインターフェイスとかはTraitにしたほうが便利なのではないかと思う。

/**
 * ArrayAccessで典型的な処理をTraitで実装
 */
trait ArrayAccessHelper
{
    public function setProerty($offset, $value) 
     {
        if (!empty($offset)) {
            $this->$offset = $value;
        } 
    }
    public function proertyExists($offset) {
        return property_exists($this, $offset);
    }
    public function unsetProerty($offset) {
        unset($this->$offset);
    }
    public function getProerty($offset) {
        return property_exists($this, $offset) ? $this->$offset : null;
    }
}

/**
 * 上記をArrayAccessインターフェイスと合わせて使う
 */
class ArrayObj implements arrayaccess 
{
    use ArrayAccessHelper;

    public function offsetSet($offset, $value) 
    {
        return $this->setProerty($offset, $value);
    }
    public function offsetExists($offset) 
    {
        return this->proertyExists($offset]);
    }
    public function offsetUnset($offset) 
    {
        return $this->unsetProerty($offset);
    }
    public function offsetGet($offset) {
        return $this->getProerty($offset]);
    }
}

まぁこのやり方でも、インターフェイスの実装は必要なだけど、幾つものクラスにインタフェイスを実装するときはこの方法でタイプの量をかなり減らせる。
(※1)

あと、以前のプロジェクトではCodeIgniterのModelにTraitを使っていた。

  • コネクションを保持するのはCI_Model の$db
  • 特定のテーブルのアクセスはメソッドはTraitにまとめる
  • アプリ内で使用するModelは上記2つを合わせて構築する

上記のルールでテーブルへのアクセス処理をかなり共通化出来たのですが、
その代わり最初に書いた問題も露呈指摘たのでTraitの使い処は難しい。


(※1) ArrayAccessを実装したクラスをを継承したほうが手っ取り早い事に気づいた、、、

複数環境でPHPを動かすときに気をつけていること。

ほとんどのサーバー再度開発は Local→ステージング→本番の様に コーディングからリリースまでに複数の環境で動かすことが多いと思います。

この時に問題になるのが“Localでの環境設定がそのまま本番にUPされてしまった。”といった環境依存コードの管理ではないでしょうか?

今回自分が環境依存コードの管理で気をつけている事をまとめてみました。

1. 環境の設定をSCMに入れない。

subversionやgitにどの環境を判定・設定するコードを入れずに、サーバーの設定や、デプロイ時のコマンドで対応するようにします。

下記の様なコードをSCMに上げていると”Localの環境が本番に上がってた。” といった危険が増えます。

#本番では下をコメントアウトする。
define(DEBUG, true);

上記を防ぐために環境切り替えのためのコードはSCMで管理している場所以外に置くようにします。

よく使う場所としてはApacheのconfです。

<localhost *:80>
...
SetEnv APP_ENV development
...
</localhost>

上記で設定した環境変数はPHPではgetenv関数で取得する事が可能です。

$env = getenv('APP_ENV');

switch($env) {
    case: 'production'
        include('prod_conf.php');
        break;
    case: 'development'
        include('dev_conf.php');
        break;
    case: 'test'
        include('test_conf.php');
        break;
}

上記の様な工夫により環境の設定ミスを起こす可能性がかなり減らせます。

2. 非機能要件は抽象化する。

非機能要件→キャッシュ、ログ、セキュリティなどは必ず何らかのラッパーを入れて
環境により切り替えられるようにしないと、「テストのためだけにコメントアウトしたコードが本番に上がる」
といった事態が起こります。

//windows環境で動かせないので下をコメント(といった一時的なコードがそのまま本番に上がってしまう。)
// $settings = $memcache->get('setting');

SymfonyやSpringなど、DIコンテナが使えるのであればそれを使ってキャッシュやログ管理を抽象化するようにしましょう。
そういったものが使えない場合もライブラリを導入するか自作するかして、他のプログラマが、キャッシュ機構やログ機構を意識しないような設計にするのは重要です。

以上です。
こういうのはユニットテストなんかを書くと早めに気づけるので、テストコードを書きつつ設計を見直すことをおすすめします。

Macのeclipseにsubclipseを入れても使えずに困った。

MacBook Pro(Lion)にPHPの開発環境を作るために、eclipseとsubclipseを入れてチェックアウトしようとしたら

変なエラーが出て進めない、、、

なんだかJavaHLライブラリがないと言うエラーのようで検索してみるとMac Portsでインストールできる事が判明。

$ sudo port install subversion-javahlbindings

これでようやく使える様になった。手こずってしまった、、、

ForkwellのおおかゆかさんとStartup Datingで話した。

興味本位で登録していたFacebookグループ”Startup Dating”でForkwellの話を聞くことが出来るというので、初めて参加してみた。

http://www.startup-dating.com/2012/01/startupdating-salon/

ココでForkwellディレクターのおおかゆかさんや、アメリカのスタートアップの環境に詳しい方々から非常に濃い話を聞いたのでまとめてみる。

Forkwellの話

  • 最初からシリコンバレーで使われる事を念頭に置いているので、デフォルトの言語は英語・サーバーはAWSの西海岸リージョンを使用している。
  • スキルのあるエンジニアが一つの会社に縛られることなく、プロジェクトを渡り歩ける様にしたい。
  • 登録者のスキルに+1出来るのはFacebookで友達になってる人だけなのでレピュテーションの信頼性が高い。
  • スキルのロゴに自動的にフォントを適用するなどデザインには相当こだわってる。
  • 将来の求人サービスは、あまり「求人スパム」的なものが来ないような仕組みを作りたい。

おおかゆかさんから聞いた話

  • 今、Slerの若い優秀なエンジニアがどんどんWeb系の起業に転職している。
  • 最近、SI案件で大きな失敗の事例が増えているのは、優秀なエンジニアが逃げ出してるのもひとつの要因では?
  • PG/SE/PMみたいに職種分けされる事にエンジニアが嫌気を感じている。
  • 私はドリコムでソーシャルゲームの開発も手がけていたが「自分のサービスが億単位の金を動かしている」のを体感するのは一度経験する価値がある。
  • 「日本のデザインはアメリカではうけない」とか言われているけど、私はそうは思わない。nintendoのコンテンツなどアメリカでヒットしている日本のデザインはある。

アメリカのエンジニアの環境の話など

  • 日本のエンジニアは優秀な人が多く、アメリカに行けば年収600~900万は見込めるのに日本の仕事に満足しているのはもったいない。
  • 日本のエンジニアの技術力は、米国のエンジニアと比較しても遜色はない。
  • 英語が不自由でも、技術がある人を欲しがってる会社は西海岸にはたくさんある。
  • 日本のエンジニアは「オープンソースのコミッタになった」とか、「〇〇のライブラリを公開した」とか、技術者としての名誉を得ることへの関心は強いが、経済的な成功を得る事への関心が低すぎる。
  • エンジニアはもっと自分のプロダクトや、技術がマネタイズされる事へ関心を持って欲しい。

僕が話したこと、思った事

  • 技術者がマネタイズに関心が薄い理由は、SIerとか長らくシステム部門が「コストセンター」として扱われてきた事が大きいと思う。仕様を削る、人件費を削るなどコスト削減に強いエンジニアは周りにも多いけど、「こういう機能つけたら利用者数増える」とか「アクセスログからしてこの機能は使われてないからテコ入れしたい」みたいな事を考えるエンジニアは少ない気がする。
  • 日本のエンジニアが「アメリカに行って稼ごう」と思わないのは、「日本でもそこそこの給料がもらえる仕事が十分にあるから」と、「プログラミングや開発といった行為が十分楽しいので、その職種につける事に満足してしまうから」かなぁ。。。
  • でもこの前エルピーダが倒産した時の竹内健さんのtweet、これこれを見て、エンジニアももう少しお金ハングリーな方がむしろ技術スキルが上がる様な気がしてきた。
  • 金稼ぎに興味が無いことはエンジニアに限った話でないと思う。 ただ、「ITでお金を稼ぐ」事は「ITエンジニアの雇用を生む」「ITエンジニアのキャリアを積む機会を作る」事に繋がるから、結果的に「IT業界に貢献する」のは間違いない。「OSSに貢献する」とか「〇〇の本を執筆した」以外にもITや社会に貢献する方法はある。
  • おおかゆかさんはディレクターなのにRubyもScalaもPythonも出来てカッコイイ!」と思ってたら、元々エンジニアとして参画してたけど、ディレクション担当になりそのまま今のポジションに落ち着いているようです。(garbsさんは代表取締役以外全員エンジニアなのかな?)

久しぶりにバイト時代の先輩と会う

大学時代の知人の死があり、10年ぐらいぶりに大学の友だちと集まる機会があった。その集まりの後、僕にずっと親身にしてくれているバイト時代の先輩の元に出かけた。

その先輩は学生時代から人間や時代に対する観察眼が鋭く、話を聞く度に感心させられる事が多い。

その時の3時間ぐらいの雑談も非常に内容が濃かった。

続きを読む