torutkのブログ

ソフトウェア・エンジニアのブログ

Java読書会「JUnit実践入門を読む会第3回」を実施しました

5月18日(土)に、Java読書会BOF主催の「JUnit実践入門を読む会 第3回」を実施しました(通算170回目)。

今回は、5月11日(土)の日本Javaユーザーグループ主催クロス・コミュニティ・カンファレンス 2013春のBOFセッションで開催した「Java読書会ライブ」に参加された方2名が初参加しました。開催してよかったです。

読書会は開始時は14名、都合で午前中で帰った方が結構いて午後は8人くらいの参加人数でした(つまり遅刻早退問題ありません)。

雑談、2次会で得た情報が有益だったので、今日はそのメモを残しておくことにします。

Windows OSのプロセス・エクスプローラ

読書会中、JUnitのTemporaryFolderルールのところで発生した議論が脱線気味になって、Windows 7でファイル削除の挙動が怪しかった(削除してもフォルダが残ってしまう)と話をしたときに、MicrosoftのSysinternalsというツール集に含まれるprocess explorerを使うと指定したフォルダのハンドルを握っているプロセスを検索できることを教えてもらいました。[検索]メニューから、調べたいフォルダ名を入力すると、そのハンドルを握っているプロセス一覧が表示されます。実行ファイルが格納されるフォルダについては何かあるらしいです。
http://technet.microsoft.com/ja-jp/sysinternals/bb545021.aspx

TestNGのDataProviderをJUnitに移植したものがある

今日の読書会の範囲で、@Theory、@DataPoint、@DataPoints を使ってテストデータをまとめて定義し利用する方法がありましたが、複数のパラメータをテストメソッドに渡すためには複数のパラメータを1つに束ねるネストクラスを定義するなどコード記述が冗長な面があります。TestNGを使っている人から、TestNGにある@DataProviderはJUnitの@Theoryより簡潔に書けるよという紹介と、TestNGの@DataProviderの仕掛けをJUnitに移植したものがあると紹介がありました。
https://github.com/TNG/junit-dataprovider

命名(特に変数)について

昼休み中の話題だったともいますが、いまだに変数名を省略する人たちがいますというネタふりがありました。確かにいまだにちらほら見かけます。特にローカル変数に多いですが、ときおりメソッド名やクラス名に省略が滲出しています。

特に多いのが母音を省略した命名です。deleteをdltとか、checkをchkとかですね。

昔はC言語の識別子が文字数制限(7文字とか?)で略語にせざるを得ない時期がありましたが、今はそのような時代ではないし、好んで略語にする人はそうした制限の時代を経験していない若い子にも多く見受けられます。(タイプするのが面倒というのが理由かも)

コードレビューをする、人にコードが見られるという組織でないと改善されないのでは、という話で打ち切りになりました。

IBM developerWorksの記事「訛りのないJava言語を話す」
http://www.ibm.com/developerworks/jp/java/library/j-noaccent.html
命名規則ー省略しないことの節に関連することが書いてあります。

sprintf や nmtkns のような名前は、スーパーコンピューターのメモリーが 32 KB だった時代の遺物です。コンパイラーはメモリーを節約するため、ID を 8 文字以下に制限していました。しかしこの 30 年以上、名前の文字数は問題ではなくなっています。現在、変数やメソッドの名前を完全にスペルアウトしない理由はありません。母音がなくて理解不可能な変数名は他の何よりも、C から転向したハッカーが作ったプログラムであることを示す明らかな証拠となります。

コードは作成される回数よりも、読まれる回数のほうが多いため、Java 言語は読みやすさのために最適化されています。

モックツールについてとユニットテストの範囲

2次会において、モックツールの話題がでたときに、「JUnit実践入門」では後ほどMochito(読み方はモヒート?モキート?)が登場しますが、JMockitという強力なモックツールもありますよという紹介をしました。finalなクラス、staticなメソッドもモック化できるツールです。以前、自分のブログに比較紹介を書いていたことをググって発見しました。
http://d.hatena.ne.jp/torutk/20101003

ユニットテストといっても、テスト対象とするクラス以外も実際に動かしてテストすることが多いようです。純粋なユニットテストであれば、自分がまさに今書いているテスト対象以外のプロダクトコードのクラスを一緒に動かすことはユニットテストの範疇を逸脱し結合テストに入ってしまっていますが、現実的には依存関係の下側(被依存側)のクラスを先にユニットテストし、それはテスト済みとして一部結合しながらユニットテストをしていく(テスト技法的にはボトムアップ結合テスト)ことが多いように思えます。そうした場合はユニットテストツールはユニットテストのために使うのではなく、結合テストボトムアップ結合でのドライバとして使っているだけで、モックツールの必要性があまりないのかもしれません。

テスト駆動開発(TDD)を取り入れているなら、今まさに作成しようとしているクラス以外にクラスはおそらくないので、モックの必要性が高いかと推測します(TDDは実践できていない身の上なので想像するしか・・・)。

プログラマーが乗り越えるべき壁

Java SE 8で導入されるラムダ式とStream、filter/map/reduceといった処理の書き方は、手続き型プログラミングに馴染んだプログラマーには敷居が高いですよと他人事のようにカモフラージュして自分のことをしゃべっていました。2次会で周囲の人に聞いてみると、そこはRubyでプログラミングしている人、Scalaでプログラミングしている人に囲まれた席だったことも災いし、「for文にくらべて気持ち良くプログラミングできる、簡潔だ」などと敷居の向こうな話が出てきてしまいました。

きっと壁を乗り越えた人にとっては、壁の前に立ちすくんでいたことを思い返すのは難しいのではないかと思います。結局自力で超えるしかないんでしょう。このような乗り越える壁が高い技術には、オブジェクト指向プログラミング、コレクションライブラリの使いこなし、2Dグラフィックス(ピクセルべた書きではなく、ベクターとアフィン変換で書くやつ)、3Dグラフィックス(ローカル座標系で形状を定義し、カメラ、光源を指定して描画する)、関数プログラミング再帰正規表現、地図(投影法、歪み)といったものがあるのでは? といった話をしていました。

壁を超えるのに最も障害となるのは、壁を越えなくても今までのやり方で動かすことができてしまう場合ではないかと思います。Java SE 8のラムダ式等であれば、今までのように外部イテレータでごりごりプログラミングしても動くものは出来上がります。たぶんオブジェクト指向プログラミングもそうではないかと。逆に今までのやり方ではできないものとして2D/3Dグラフィックス、地図などがあります。代替えができないので正面から取り組む必要があります。

新しいプログラミング言語を1年に1つは学習するということが挫折しているのも、今使える言語のどれかでできることを、わざわざ新しい言語で作らなくても・・・となっているからだろうなと少し反省(?)しています。そうでなければ毎年1つずつレパートリーが増えて今頃15個くらいの言語はマスターできていたはずなのですが・・・