from old JUnit
to modern JUnit
関西Javaエンジニアの会'13 7月度
@irof
@irof
========
* ふつうのプログラマ
* TDD
* Java, Jenkins
* Groovy, Gradle, Git
関西Javaエンジニアの会, hoge駆動,
大阪Jenkins勉強会……とかの中の人。
タイトルの元ネタ
(Java1.4から7へアップグレードするのいい資料なので是非)
JUnitの話をだらだらします
おしながき
JUnitを使うわけ
良いテストコードとは
JUnitの進化
JUnit4を使いこなす
JUnitを使うわけ
テスティングフレームワーク
テストを実行する
テスト結果を検証する
テストのフォーマットを提供する
実行方法、記述方法を統一するこ
とで、知っている人なら誰でも読めて
実行できるようにするのが目的。
xUnitを使うわけ
みんな使ってるから。
テスト実行時に興味の無いことをやって
くれるから。
他のツールと連携してくれるから。
IDE, ビルドツール, CI, カバレッジ,
テストレポート, etc...
TestNGでないわけ
とくにない。
おしながき
JUnitを使うわけ
良いテストコードとは
JUnitの進化
JUnit4を使いこなす
良いテストコードとは
F.I.R.S.T.
Fast - 高速
Independent - 独立
Repeatable - 再現
Self-Validating - 自己検証
Timely - 適時
A-TRIP
Automatic - 自動
Thorough - 徹底
Repeatable - 再現
Independent - 独立
Professional - 専門的
以上は借りてきた言葉。
良いテストコードとは
失敗の扱いがうまい
読みやすい
失敗の扱いがうまい
失敗すること
すぐ失敗すること
何故失敗したかわかること
どうするべきかわかること
失敗時の振る舞いで良し悪しが決まる
テストの価値は
失敗にある
詳しくはSlideShareで
読みやすい
テストコードはプロダクトコードよりも
可読性が求められる。
何故か?
テストのテストは困難。
テストのバグはレビューで潰す?
可読性が高いとバグが減る
“極限まで可読性の高いコードにバグ
が混入する可能性は限りなく低い”
ってブログに書いてた。私の。
可読性のための構造化
たとえば4フェーズテスト(xUTP)を使う
Four-Phase Test
@Test
public void hoge() {
Hoge sut = new Hoge();
String actual = sut.hoge();
assertThat(actual, is("fuga"...
おしながき
JUnitを使うわけ
良いテストコードとは
JUnitの進化
JUnit4を使いこなす
JUnitの進化
JUnit 3
public class JUnit3Test extends TestCase {
 
public void testHoge() {
 
assertEquals(2, 1);
}
}
JUnit 4
public class JUnit4Test {
 
@Test
public void hoge() {
 
assertThat(1, is(2));
}
}
TestCaseの継承が不要。
メソッド名のtest始まり制約が不要。
メソッドに@Testを付ける。
assertThatが標準(個人の趣味)
JUnit3 to JUnit4
何が嬉しい?
TestCaseの継承が不要。
Javaの継承は1クラスのみ。
いざと言う時のカードが残せる。
何が嬉しい?
メソッド名のtest始まり制約
が不要。
testのtypoが無くなる。
日本語テストメソッド名の違和感が
軽減される。
何が嬉しい?
assertThatが標準。
Matcherが使える。
あと引数の順番(ブログ参照)
※補足※
assertThatはJUnit4.4でAssertク
ラスに追加されたが、hamcrestを直
接使用すればJUnit3でも使える。
所詮AssertionErrorを投げるだけ
だし。
JUnit4.4以降の主な機能
4.4 - assertThat, Theories
4.7 - Rule(MethodRule)
4.8 - Categories
4.9 - TestRule
4.10 - RuleChain
4.11 - ...
おしながき
JUnitを使うわけ
良いテストコードとは
JUnitの進化
JUnit4を使いこなす
JUnit4を使いこなす
JUnit4の三本柱
Matcher
Rule
Runner
Matcher
ひとまとまりの検証に名前をつけてひと
まとめにする。
テストコード自体の可読性の向上
失敗時メッセージの可読性の向上
describeTo/describeMismatch
で失敗時のメッセージを編集可能。
describeMi...
Matcherの使い方
assertThat(today, is(dateOf(2013, 2, 3)));
java.lang.AssertionError:
Expected: is "2013/02/03"
but: "2013/07/3...
メッセージがわかりやすい!
ステキ!!
Rule
とりあえずExpectedExceptionは覚
える。
他はおいおいでも……
@Ruleと@ClassRuleがある。
基本は@Ruleを使う。
Ruleの活用例
例外を検証するRuleとか(後述)
Logを検証するRuleとか(作れる)
TestWatcherを拡張すると捗る。
starting/finished
succeeded/failed/skipped
例外のテスト
old Exception Test
@Test
public void hoge() {
try {
sut.hoge();
fail();
} catch(NullPointerException e) {
assertEquals("ぬる...
modern Exception Test
@Test(expected = NullpointerException.class)
public void hoge() {
sut.hoge();
}
例外の型だけで良いならこれでおk
modern Exception Test
@Rule
public ExpectedException thrown =
ExpectedException.none();
@Test
public void hoge() {
thrown....
modern Exception Test
例外が発生しなかった場合の fail を
書かなくて良い(忘れない)。
try-catchのような構造がテストコー
ド内に出現しない。
(例外の検証にMatcherを使える)
Ruleを使えば継承無しで横
断的なルールを適用できる!
しかも組み合わせ放題!
(継承では難しい)
ステキ!!
Runner
JUnitの実行方法を制御する。
標準機能で以下が提供。
Enclosed
Parameterized
Theories
Suite
Categories
Runnerの活用例
Arquillian
WebコンテナでJUnitのテストを実行
する。
SpringTest
ApplicationContextの初期化をし
てくれたりする。
Runnerをいじる
「実行方法の制御」
その気になれば何でもできる。
TestNGのテストも実行できる。
ネタだけど
続きはWebで
JavaAdventCalendar2011で似たこ
と書いてます。
まとめ
まとめ
JUnitも進化してます。
昔の常識、今は?
最新を追うと色々見えて楽しい。
one more thing...
Groovy x JUnit
Groovy x JUnit
JUnitのテストをGroovyで書く。
Spockを使う。
JUnitを拡張したフレームワーク
@RunWith(Sputnik.class)
JUnitとして実行できる!
Spockの例
class HelloSpock extends spock.lang.Specification {
    def "length of Spock's and his friends' names"() {
       ...
Upcoming SlideShare
Loading in …5
×

from old JUnit to modern JUnit

4,978 views

Published on

関西Javaエンジニアの会'13 7月度の発表資料です。

Published in: Technology

from old JUnit to modern JUnit

  1. 1. from old JUnit to modern JUnit 関西Javaエンジニアの会'13 7月度 @irof
  2. 2. @irof ======== * ふつうのプログラマ * TDD * Java, Jenkins * Groovy, Gradle, Git 関西Javaエンジニアの会, hoge駆動, 大阪Jenkins勉強会……とかの中の人。
  3. 3. タイトルの元ネタ (Java1.4から7へアップグレードするのいい資料なので是非)
  4. 4. JUnitの話をだらだらします
  5. 5. おしながき JUnitを使うわけ 良いテストコードとは JUnitの進化 JUnit4を使いこなす
  6. 6. JUnitを使うわけ
  7. 7. テスティングフレームワーク テストを実行する テスト結果を検証する テストのフォーマットを提供する 実行方法、記述方法を統一するこ とで、知っている人なら誰でも読めて 実行できるようにするのが目的。
  8. 8. xUnitを使うわけ みんな使ってるから。 テスト実行時に興味の無いことをやって くれるから。 他のツールと連携してくれるから。 IDE, ビルドツール, CI, カバレッジ, テストレポート, etc...
  9. 9. TestNGでないわけ とくにない。
  10. 10. おしながき JUnitを使うわけ 良いテストコードとは JUnitの進化 JUnit4を使いこなす
  11. 11. 良いテストコードとは
  12. 12. F.I.R.S.T. Fast - 高速 Independent - 独立 Repeatable - 再現 Self-Validating - 自己検証 Timely - 適時
  13. 13. A-TRIP Automatic - 自動 Thorough - 徹底 Repeatable - 再現 Independent - 独立 Professional - 専門的
  14. 14. 以上は借りてきた言葉。
  15. 15. 良いテストコードとは 失敗の扱いがうまい 読みやすい
  16. 16. 失敗の扱いがうまい 失敗すること すぐ失敗すること 何故失敗したかわかること どうするべきかわかること 失敗時の振る舞いで良し悪しが決まる
  17. 17. テストの価値は 失敗にある
  18. 18. 詳しくはSlideShareで
  19. 19. 読みやすい テストコードはプロダクトコードよりも 可読性が求められる。 何故か? テストのテストは困難。 テストのバグはレビューで潰す?
  20. 20. 可読性が高いとバグが減る “極限まで可読性の高いコードにバグ が混入する可能性は限りなく低い” ってブログに書いてた。私の。
  21. 21. 可読性のための構造化 たとえば4フェーズテスト(xUTP)を使う
  22. 22. Four-Phase Test @Test public void hoge() { Hoge sut = new Hoge(); String actual = sut.hoge(); assertThat(actual, is("fuga")); } フェーズの間を 1行空けるとかsetup exercise verify 構造がわかると読みやすくなる
  23. 23. おしながき JUnitを使うわけ 良いテストコードとは JUnitの進化 JUnit4を使いこなす
  24. 24. JUnitの進化
  25. 25. JUnit 3 public class JUnit3Test extends TestCase {   public void testHoge() {   assertEquals(2, 1); } }
  26. 26. JUnit 4 public class JUnit4Test {   @Test public void hoge() {   assertThat(1, is(2)); } }
  27. 27. TestCaseの継承が不要。 メソッド名のtest始まり制約が不要。 メソッドに@Testを付ける。 assertThatが標準(個人の趣味) JUnit3 to JUnit4
  28. 28. 何が嬉しい? TestCaseの継承が不要。 Javaの継承は1クラスのみ。 いざと言う時のカードが残せる。
  29. 29. 何が嬉しい? メソッド名のtest始まり制約 が不要。 testのtypoが無くなる。 日本語テストメソッド名の違和感が 軽減される。
  30. 30. 何が嬉しい? assertThatが標準。 Matcherが使える。 あと引数の順番(ブログ参照)
  31. 31. ※補足※ assertThatはJUnit4.4でAssertク ラスに追加されたが、hamcrestを直 接使用すればJUnit3でも使える。 所詮AssertionErrorを投げるだけ だし。
  32. 32. JUnit4.4以降の主な機能 4.4 - assertThat, Theories 4.7 - Rule(MethodRule) 4.8 - Categories 4.9 - TestRule 4.10 - RuleChain 4.11 - FixMethodOrder ※個人の趣味で抜粋
  33. 33. おしながき JUnitを使うわけ 良いテストコードとは JUnitの進化 JUnit4を使いこなす
  34. 34. JUnit4を使いこなす
  35. 35. JUnit4の三本柱 Matcher Rule Runner
  36. 36. Matcher ひとまとまりの検証に名前をつけてひと まとめにする。 テストコード自体の可読性の向上 失敗時メッセージの可読性の向上 describeTo/describeMismatch で失敗時のメッセージを編集可能。 describeMismatchはhamcrest1.2以降(最新は1.3) JUnit実践入門は1.1のため未掲載
  37. 37. Matcherの使い方 assertThat(today, is(dateOf(2013, 2, 3))); java.lang.AssertionError: Expected: is "2013/02/03" but: "2013/07/31" at org.hamcrest.MatcherAssert.assertThat(MatcherAssert at org.junit.Assert.assertThat(Assert.java:865) at org.junit.Assert.assertThat(Assert.java:832) at JUnit4Test.hoge(JUnit4Test.java:24) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native describeMismatchで編集可 describeToで編集可
  38. 38. メッセージがわかりやすい! ステキ!!
  39. 39. Rule とりあえずExpectedExceptionは覚 える。 他はおいおいでも…… @Ruleと@ClassRuleがある。 基本は@Ruleを使う。
  40. 40. Ruleの活用例 例外を検証するRuleとか(後述) Logを検証するRuleとか(作れる) TestWatcherを拡張すると捗る。 starting/finished succeeded/failed/skipped
  41. 41. 例外のテスト
  42. 42. old Exception Test @Test public void hoge() { try { sut.hoge(); fail(); } catch(NullPointerException e) { assertEquals("ぬるぽ", e.getMessage()); } }
  43. 43. modern Exception Test @Test(expected = NullpointerException.class) public void hoge() { sut.hoge(); } 例外の型だけで良いならこれでおk
  44. 44. modern Exception Test @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void hoge() { thrown.expect(NullPointerException.class); thrown.expectMessage("ぬるぽ"); sut.hoge(); }
  45. 45. modern Exception Test 例外が発生しなかった場合の fail を 書かなくて良い(忘れない)。 try-catchのような構造がテストコー ド内に出現しない。 (例外の検証にMatcherを使える)
  46. 46. Ruleを使えば継承無しで横 断的なルールを適用できる! しかも組み合わせ放題! (継承では難しい) ステキ!!
  47. 47. Runner JUnitの実行方法を制御する。 標準機能で以下が提供。 Enclosed Parameterized Theories Suite Categories
  48. 48. Runnerの活用例 Arquillian WebコンテナでJUnitのテストを実行 する。 SpringTest ApplicationContextの初期化をし てくれたりする。
  49. 49. Runnerをいじる 「実行方法の制御」 その気になれば何でもできる。 TestNGのテストも実行できる。 ネタだけど
  50. 50. 続きはWebで JavaAdventCalendar2011で似たこ と書いてます。
  51. 51. まとめ
  52. 52. まとめ JUnitも進化してます。 昔の常識、今は? 最新を追うと色々見えて楽しい。
  53. 53. one more thing...
  54. 54. Groovy x JUnit
  55. 55. Groovy x JUnit JUnitのテストをGroovyで書く。 Spockを使う。 JUnitを拡張したフレームワーク @RunWith(Sputnik.class) JUnitとして実行できる!
  56. 56. Spockの例 class HelloSpock extends spock.lang.Specification {     def "length of Spock's and his friends' names"() {         expect:         name.size() == length         where:         name     | length         "Spock"  | 5         "Kirk"   | 4         "Scotty" | 6     } } 詳しくは別の機会に。

×