connpass(告知サイト)
http://connpass.com/event/1694/
Togetter
http://togetter.com/li/463129
以下の書籍をターゲットとした読書会なのです。
![]() | JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus) (2012/11/21) 渡辺 修司 商品詳細を見る |
場所は横浜のタネマキさんです。参加者は15名くらいでしょうか。
今日は「第12章 データベースのユニットテスト」が範囲でした。
写経する時間が取れなかったので、書籍を一通り読んでサンプルコードを動作するトコまでやってから参加しました。
サンプルコードを動かす時にハマッた箇所をメモに残しておく。
(環境はWin7のEclipse3.7、他は書籍のミドル指定と同様の構成、バージョンです)
■サンプルコードを動作させるためのメモ
H2 Database + DbUnitを使ってUserDaoTest.javaを動作させようとすると、最初、以下のエラーが出ました。
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory |
ググってみると、どうやら以下のjarをクラスパスに通しておく必要があるらしい。(書籍には指示なし)
・slf4j-api-1.7.2.jar
・slf4j-nop-1.7.2.jar
ということで、以下から「slf4j-1.7.2.zip」をダウンロードします。解凍して上記2つをビルドパス追加。
http://www.slf4j.org/
再度、DbUnitを使ってUserDaoTest.javaを動作させようとすると、今度は以下のエラーが出ました。
org.dbunit.dataset.DataSetException: java.net.MalformedURLException |
どうやら、usersテーブルのデータセットを指定したXMLファイルが見つからないらしい。
ということで、EclipseでXMLファイルが入っているフォルダをソースフォルダーとして明示的に指定してやる。

再度、DbUnitを使ってUserDaoTest.javaを動作させると、今度はうまく単体テストできました。

んで、その後いろいろH2 Databaseの設定とかいじっていたら、単体テストで以下のエラーが出るようになってしまった。。。
org.h2.jdbc.JdbcSQLException: スキーマ "UT" が見つかりません Schema "UT" not found; SQL statement: |
どうやらH2 Databaseのデータを格納しているファイルに不一致らしき事象が生じたらしい。
んで、いろいろ調べてもわからなかったので、勉強会の場で質問してみたら、@PoohSunny さんも以前、同じ事象になったことがあるとのこと。
僕も一度スキーマないって怒られましたよ。えらいこっちゃ。 #junitbook
— Yotaro TAKAHASHI さん (@PoohSunny) 2013年3月3日
ということで、@PoohSunny さんから解決方法のヒントをいただきました。
んでアドバイスを参考にH2DatabaseServer.javaを以下のように修正すると、なんと解決~!感謝!
■修正前:H2DatabaseServer.javaの37行目あたり
String url = "jdbc:h2:" + server.getURL() + "/" + dbName; |
■修正後:H2DatabaseServer.javaの37行目あたり
String url = "jdbc:h2:tcp://localhost/db"; |
どうやらデータベースサーバへの接続URL(特にポート番号まわり)が怪しそうだったので、ポート番号を含まないURL(localhost指定)を指定してスキーマを一度作り直すよう、細工してやったのです。
上記のようにソースを1回修正し実行することで、@before により再度スキーマUTが作り直されて、以降は修正前のソースに戻してもちゃんと動作するようになりました。
■ディスカッションのメモ
以下、ディスカッションタイムに私がとったメモ。
■Web三層構造アーキテクチャ(P.200)
Seasar2は3層に分かれているが、Play Frameworkは3層に分かれおらず、パーシステンス層とロジック層が密に結合している。
→ この書籍のとおりとはいかない。
■スローテストに直面している人は参加者のうち2名くらい。
■スローテストの解決案
・単体テストはH2 Databaseを使って、速度が遅い部分はカテゴリのアノテーション使って後に回す。
・設定ファイルを分けて、単体テストと結合テストでテスト対象を切り替える。
・遅くなりそうなテストだけ纏めて抜き出す。
■Salesforceでのテスト
・テストに7時間くらいかかってて、スローテスト問題に悩んでいる。。。
・Salesforceのフレームワークが、テストで全件流さないといけない仕組みになっている。
・テストが途中でコケても途中で止められない。
・データクリアができないのでテストの時間もすごくかかる。
・デプロイの時にテストが走ってカバレージを取得し、75%以上じゃないとデプロイできない仕組みにしている。
・Salesforceの開発言語Apexはローカルでコンパイルやテストができないので、手元で確認できないのが辛い。。。。
■他の人は、スローテストになるほどテスト書いてなかったりする。。。?
■テストの工夫
・DBを単体テスト用、結合テスト用、ステージング用と複数用意する。
→ 単体テスト用は中身を空にしておいて、テスト時にコミットが実行されないようにしておく。
→ 単体テストの最初にテストデータを投入し、テストが終わったらコミットがされない(≒ロールバックされる)ので自動でデータが消える仕組みにしている。
■DBを使ったテストでハマったこと
・同じスキーマに複数の人がテストしてて、1人がデバッグでステップ実行しててテーブルにロックがかかった。
→ その結果、もう1人のテストがコケた。集中型DBのテスト環境だとよく起こる。
・一人ひとりにDB環境を作れば、このような事象は起こらない。
■データベーススキーマのバージョンを管理するツールがある。
"Javaのデータベースマイグレーションツール「Flyway」" bit.ly/1609cY9 #junitbook #ステマ
— Ryuji TSUTSUIさん (@ryu22e) 2013年3月3日
■H2 Databaseは他のDBMSとエミュレートできるのが良い。
■groovyとyamlを使った @grimrose さんのLT。
https://github.com/grimrose/junit-boost-camp
■Seasar2は開発が止まっちゃているのが難点。@Theoryが使えなかったり。。。
■レガシーコード改善ガイド
![]() | レガシーコード改善ガイド (Object Oriented SELECTION) (2009/07/14) マイケル・C・フェザーズ 商品詳細を見る |
・この本は、テスト時のDBアクセスを極度に嫌っている。
→ DBをモックに置き換えないといけないと思い、頑張ったが苦しんでいた。。。
→ @t_wada に相談してみたら、t_wadaさん曰く、「DBに繋いでテストしちゃえばいいんじゃないの?」
→ 目からウロコだった。
■ @sue445 さんのLT
・Rails版
「JUnit実践入門」の「第12章 データベースのテスト」をRailsで書きなおしてみた
https://bitbucket.org/sue445/junitbook-study-rails
・Seasar2版
「JUnit実践入門」の「第12章 データベースのテスト」をSeasar2で書きなおしてみた
https://bitbucket.org/sue445/junitbook-study-seasar2
■@PoohSunny さんによるLT
■おまけ
今日はジョジョ2巻の途中まで読んだ。次回はもうちょっと早めに行って、たくさん読むんだ!
★感想:
今日もディスカッションが活発で、大変有意義でした。
スキーマUTが見つからない、というエラーも解決できたことだし。
惜しむらくは、写経の時間が十分にとれなかったこと。
次回はもうちょっと早めに予習することにしよう。
最後に、主催者さん、参加者さん、皆様ありがとうございました。
- 関連記事
-
- アジャイルサムライ読書会 横浜道場 「イテレーションの運営:実現させる」に参加しました
- 「『JUnit実践入門』写経・実践会 in 横浜 #4」に参加しました
- 「第n回GOOS(日本語版)読書会」に参加しました