56
from old JUnit to modern JUnit 関西Javaエンジニアの会'13 7月度 @irof

from old JUnit to modern JUnit

  • Upload
    irof-n

  • View
    4.657

  • Download
    4

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: from old JUnit to modern JUnit

from old JUnitto modern JUnit

関西Javaエンジニアの会'13 7月度@irof

Page 2: from old JUnit to modern JUnit

@irof========* ふつうのプログラマ * TDD

* Java, Jenkins

* Groovy, Gradle, Git

関西Javaエンジニアの会, hoge駆動,

大阪Jenkins勉強会……とかの中の人。

Page 3: from old JUnit to modern JUnit

タイトルの元ネタ(Java1.4から7へアップグレードするのいい資料なので是非)

Page 4: from old JUnit to modern JUnit

JUnitの話をだらだらします

Page 5: from old JUnit to modern JUnit

おしながき

JUnitを使うわけ

良いテストコードとは

JUnitの進化

JUnit4を使いこなす

Page 6: from old JUnit to modern JUnit

JUnitを使うわけ

Page 7: from old JUnit to modern JUnit

テスティングフレームワーク

テストを実行する

テスト結果を検証する

テストのフォーマットを提供する

実行方法、記述方法を統一することで、知っている人なら誰でも読めて実行できるようにするのが目的。

Page 8: from old JUnit to modern JUnit

xUnitを使うわけ

みんな使ってるから。

テスト実行時に興味の無いことをやってくれるから。

他のツールと連携してくれるから。

IDE, ビルドツール, CI, カバレッジ, テストレポート, etc...

Page 9: from old JUnit to modern JUnit

TestNGでないわけ

とくにない。

Page 10: from old JUnit to modern JUnit

おしながき

JUnitを使うわけ

良いテストコードとは

JUnitの進化

JUnit4を使いこなす

Page 11: from old JUnit to modern JUnit

良いテストコードとは

Page 12: from old JUnit to modern JUnit

F.I.R.S.T.

Fast - 高速

Independent - 独立

Repeatable - 再現

Self-Validating - 自己検証

Timely - 適時

Page 13: from old JUnit to modern JUnit

A-TRIP

Automatic - 自動

Thorough - 徹底

Repeatable - 再現

Independent - 独立

Professional - 専門的

Page 14: from old JUnit to modern JUnit

以上は借りてきた言葉。

Page 15: from old JUnit to modern JUnit

良いテストコードとは

失敗の扱いがうまい

読みやすい

Page 16: from old JUnit to modern JUnit

失敗の扱いがうまい

失敗すること

すぐ失敗すること

何故失敗したかわかること

どうするべきかわかること

失敗時の振る舞いで良し悪しが決まる

Page 17: from old JUnit to modern JUnit

テストの価値は

失敗にある

Page 18: from old JUnit to modern JUnit

詳しくはSlideShareで

Page 19: from old JUnit to modern JUnit

読みやすい

テストコードはプロダクトコードよりも可読性が求められる。

何故か?

テストのテストは困難。

テストのバグはレビューで潰す?

Page 20: from old JUnit to modern JUnit

可読性が高いとバグが減る

“極限まで可読性の高いコードにバグが混入する可能性は限りなく低い”

ってブログに書いてた。私の。

Page 21: from old JUnit to modern JUnit

可読性のための構造化

たとえば4フェーズテスト(xUTP)を使う

Page 22: from old JUnit to modern JUnit

Four-Phase Test

@Test public void hoge() { Hoge sut = new Hoge(); String actual = sut.hoge(); assertThat(actual, is("fuga")); }

フェーズの間を1行空けるとかsetup

exercise

verify

構造がわかると読みやすくなる

Page 23: from old JUnit to modern JUnit

おしながき

JUnitを使うわけ

良いテストコードとは

JUnitの進化

JUnit4を使いこなす

Page 24: from old JUnit to modern JUnit

JUnitの進化

Page 25: from old JUnit to modern JUnit

JUnit 3

public class JUnit3Test extends TestCase {  public void testHoge() {  assertEquals(2, 1); }}

Page 26: from old JUnit to modern JUnit

JUnit 4

public class JUnit4Test {  @Test public void hoge() {  assertThat(1, is(2)); }}

Page 27: from old JUnit to modern JUnit

TestCaseの継承が不要。

メソッド名のtest始まり制約が不要。

メソッドに@Testを付ける。

assertThatが標準(個人の趣味)

JUnit3 to JUnit4

Page 28: from old JUnit to modern JUnit

何が嬉しい?

TestCaseの継承が不要。Javaの継承は1クラスのみ。

いざと言う時のカードが残せる。

Page 29: from old JUnit to modern JUnit

何が嬉しい?

メソッド名のtest始まり制約が不要。

testのtypoが無くなる。

日本語テストメソッド名の違和感が軽減される。

Page 30: from old JUnit to modern JUnit

何が嬉しい?

assertThatが標準。Matcherが使える。

あと引数の順番(ブログ参照)

Page 31: from old JUnit to modern JUnit

※補足※

assertThatはJUnit4.4でAssertクラスに追加されたが、hamcrestを直接使用すればJUnit3でも使える。

所詮AssertionErrorを投げるだけだし。

Page 32: from old JUnit to modern JUnit

JUnit4.4以降の主な機能

4.4 - assertThat, Theories

4.7 - Rule(MethodRule)

4.8 - Categories

4.9 - TestRule

4.10 - RuleChain

4.11 - FixMethodOrder

※個人の趣味で抜粋

Page 33: from old JUnit to modern JUnit

おしながき

JUnitを使うわけ

良いテストコードとは

JUnitの進化

JUnit4を使いこなす

Page 34: from old JUnit to modern JUnit

JUnit4を使いこなす

Page 35: from old JUnit to modern JUnit

JUnit4の三本柱

MatcherRuleRunner

Page 36: from old JUnit to modern JUnit

Matcher

ひとまとまりの検証に名前をつけてひとまとめにする。

テストコード自体の可読性の向上

失敗時メッセージの可読性の向上

describeTo/describeMismatchで失敗時のメッセージを編集可能。

describeMismatchはhamcrest1.2以降(最新は1.3)JUnit実践入門は1.1のため未掲載

Page 37: from old JUnit to modern JUnit

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で編集可

Page 38: from old JUnit to modern JUnit

メッセージがわかりやすい!

ステキ!!

Page 39: from old JUnit to modern JUnit

Rule

とりあえずExpectedExceptionは覚える。

他はおいおいでも……

@Ruleと@ClassRuleがある。

基本は@Ruleを使う。

Page 40: from old JUnit to modern JUnit

Ruleの活用例

例外を検証するRuleとか(後述)

Logを検証するRuleとか(作れる)

TestWatcherを拡張すると捗る。

starting/finished

succeeded/failed/skipped

Page 41: from old JUnit to modern JUnit

例外のテスト

Page 42: from old JUnit to modern JUnit

old Exception Test

@Test public void hoge() { try { sut.hoge(); fail(); } catch(NullPointerException e) { assertEquals("ぬるぽ", e.getMessage()); } }

Page 43: from old JUnit to modern JUnit

modern Exception Test

@Test(expected = NullpointerException.class)public void hoge() { sut.hoge();}

例外の型だけで良いならこれでおk

Page 44: from old JUnit to modern JUnit

modern Exception Test

@Rulepublic ExpectedException thrown = ExpectedException.none();

@Testpublic void hoge() { thrown.expect(NullPointerException.class); thrown.expectMessage("ぬるぽ"); sut.hoge();}

Page 45: from old JUnit to modern JUnit

modern Exception Test

例外が発生しなかった場合の fail を書かなくて良い(忘れない)。

try-catchのような構造がテストコード内に出現しない。

(例外の検証にMatcherを使える)

Page 46: from old JUnit to modern JUnit

Ruleを使えば継承無しで横断的なルールを適用できる!

しかも組み合わせ放題!(継承では難しい)

ステキ!!

Page 47: from old JUnit to modern JUnit

Runner

JUnitの実行方法を制御する。

標準機能で以下が提供。

Enclosed

Parameterized

Theories

Suite

Categories

Page 48: from old JUnit to modern JUnit

Runnerの活用例

Arquillian

WebコンテナでJUnitのテストを実行する。

SpringTest

ApplicationContextの初期化をしてくれたりする。

Page 49: from old JUnit to modern JUnit

Runnerをいじる

「実行方法の制御」

その気になれば何でもできる。

TestNGのテストも実行できる。

ネタだけど

Page 50: from old JUnit to modern JUnit

続きはWebで

JavaAdventCalendar2011で似たこと書いてます。

Page 51: from old JUnit to modern JUnit

まとめ

Page 52: from old JUnit to modern JUnit

まとめ

JUnitも進化してます。

昔の常識、今は?

最新を追うと色々見えて楽しい。

Page 53: from old JUnit to modern JUnit

one more thing...

Page 54: from old JUnit to modern JUnit

Groovy x JUnit

Page 55: from old JUnit to modern JUnit

Groovy x JUnit

JUnitのテストをGroovyで書く。

Spockを使う。

JUnitを拡張したフレームワーク

@RunWith(Sputnik.class)

JUnitとして実行できる!

Page 56: from old JUnit to modern JUnit

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    }}

詳しくは別の機会に。