修司(287)321321件のシェア(そこそこ話題の記事)この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。DevelopersIOでの100本目のエントリーがJUnitネタとなりました。自分がJUnit実践入門を執筆したのは2011年から2012年にかけてです(出版が2012年11月)。それからJava8がリリースされていますが、JUnit4自体は大きな進化はしていませんでした。Prototypeが公開されました。プロトタイプということで、今後の変更は大きいかと思いますが、いよいよ次世代のJUnitの足音が聞こえてきた感じがします。Lambdaの概要と方針について速報をお送りしたいと思います。現在JUnitチームでは、このプロトタイプに対するフィードバックを募集しています。Lambda(以後、JUnit5)はJUnit4から仕組みを一新し、Java8時代の新しいJUnitとして提供する方針になっています。JUNit5の印象を3行で書くとこんな感じです。JUnitの歴史について簡単に解説しておきます。現在主流であるJUnit4は、Java1.4時代に作られたJUnit3がベースであり、基本設計は非常に古いものです。アノテーションもありませんでした。Java1.4の時代には、Javaのユニットテスティングフレームワークとして主流となります。Java1.4からJava5への以降はかなり期間が空いたのですが、JUnit4のリリースもJava5のリリースからかなり後になります。Java1.4時代の設計では厳しいので、Java5で導入されたアノテーション対応やユニットテストに必要な機能拡張などを行ったのがJUnit4です(ぶっちゃけ魔改造)。このため、JUni4はユニットテストに必要な機能を多く提供していましたが、JUnit3との互換性や言語機能の制約などから使いにくい部分も多くあったと言えます。JUnit5はJava8以降をターゲットとしています。JUnitの名前は残っていますが、完全に新しいテスティングフレームワークと言えます。いえ、xUnitの系譜である点は変わりません。基本的な部分をJUnit4から継承しつつ、機能の整理を行い、作り直したのがJUnit5です。新しいアノテーションとJUnit5のテストコードもう一度言いますが、JUnit5は、JUnit4とは全く異なるテスティングフレームワークです。JUnit5では、JUnit4と同様に@Testアノテーションを宣言してテストメソッドを定義します。JUnit5の@TestアノテーションとJUnit4の@Testアノテーションは、パッケージが異なります。それでは、JUnit5のテストコードを見てみましょう。{}}JUnit5では、テストクラス・テストメソッド共にpublicである必要がなくなりました。IDEを利用していれば大きな手間ではありませんが、タイピングが少なくなることは良いことでしょう。@TestInstance@TestInstanceアノテーションはテストクラスに宣言し、テストクラスのライフサイクルについて定義します。省略した場合も含め、デフォルトでは、JUnit4と同様に、テストメソッドの実行毎にテストクラスのインスタンスが作成されます。@TestInstance(PER_CLASS)を宣言した場合は、テストクラスのインスタンスは再利用され、テストメソッド毎に作成されません。@AfterAll@BeforeAllアノテーションと@AfterAllアノテーションは、JUnit4の@BeforeClassアノテーションと@AfterClassアノテーションに対応するアノテーションです。テストの初期化と後処理を行うメソッドを定義します。JUnit5での変更点は、テストクラスを@TestInstance(PER_CLASS)で宣言した場合は、staticメソッドにする必要がない点です。テストクラスを従来通りにテストメソッド毎に作成する場合は、staticメソッドにする必要があるので注意してください。@AfterEach@BeforeEachアノテーションと@AfterEachアノテーションは、JUnit4の@Beforeアノテーションと@Afterアノテーションに対応するアノテーションです。JUnit4と挙動は変わらず、テストメソッドの実行前と実行後に実行するメソッドです。@Test@Testアノテーションは、テストメソッドに定義するアノテーションです。パッケージ以外に大きな変更点はありませんが、アノテーションのアトリビュートはすべて廃止されました。テストに必要な属性はすべて別個のアノテーションとして宣言します。アサーションテストクラスとテストメソッドの構造は、若干の違いはあるもののJUnit4を踏襲しています。アサーションには大きく手が入っています。Lambda式対応とMatcherの廃止です。アサーションメソッドJUnit5のアサーションは、org.junit.gen5.api.Assertionsクラスのstaticメソッドとして提供されています。基本的な使い方はJUnit4と変わりませんが、Lambda式に対応している点が大きく異なります。assertTrueといったアサーションメソッドが提供されていますが、エラーメッセージ部分がLambda式に対応しているため、評価が失敗した場合にエラーメッセージ部分が評価されることになります。今の所、このメリットとしては、toStringメソッドのコストを考慮する程度の使い方しか思いつきませんが・・・。まとめてアサーションを行うassertAllメソッドが追加されました。address.getLastName()));addressグループの中でアサーションが2回宣言されていますが、それぞれがLambda式になっています。assertAllでは、最初のアサーションが失敗した場合でも、すべてのアサーションを評価するのがポイントです。なんでもかんでも詰め込みすぎると「なんのテストを行うテストメソッドか解らない」状態となってしまいます。1つ目のアサーションを通っても2つ目が通らなかったりすることは多々あるので、便利な機能です。これはLambda式を有効に使っているパターンでしょう。例外のテスト例外のテストは、expectThrowsメソッドにテストの実行部分をLambda式として渡す事で実行できるようになりました(expectedはありません)。例外メッセージの検証も容易です。Matcherの廃止ここまでassertTrueメソッドやassertEqualsメソッドを見てきましたが、assertThatメソッドは?と思った人は多いはずです。JUnit4でHamcrestライブラリと合わせて導入されたassertThatメソッドはJUnit5には存在しません。isメソッド(Isクラス)などのMatcherもありません。実は、JUnit5ではMatcherは各プログラマが自由に選択する、というスタンスをとっています。JUnit4で一時期は標準となったHamcrestを利用するのもひとつです。TruthといったMatcherがあります。JUnit5ではテストメソッドの実行時に例外が送出された場合、テスト失敗として扱います。Ruleの廃止とJUnit5の拡張JUnit4では多くの拡張機能がRuleやTestRunnerとして提供されました。Ruleによりテストメソッドの振る舞いなどをカスタマイズすることができるようになり、ユニットテストの手法は大きく進化したと言えます。全部捨てましたwしかし、実際は多くのRuleやTestRunnerが、JUnit5の基本機能として実装されています。@TestName@Nameアノテーションと@TestNameアノテーションはテスト名を定義するアノテーションです。fail(testName);}@Nameアノテーションは、テストランナーやIDEが表示するテスト名を定義するアノテーションです。Javaはメソッド名の制約が強いため、先頭に数字を入れたり、空白や句読点を含めることができません。@Nameアノテーションに自由に文字列を入れることで回避することができます。@TestNameアノテーションは、@TestNameルールに相当するアノテーションです。Ruleはテストクラスのインスタンス変数に宣言する必要があり、非常に残念なテストコードになることはよく知られています。JUnit5では、テストメソッドの引数などの制限も大幅に緩和されたため、@TestNameアノテーションをつけた引数を設定することで、テスト名をテストメソッド内で利用できます。@NestedJUnit4では@Enclosedテストランナーを利用することでネストしたテストクラスを作成することができました。ネストしたテストクラスは、テストを構造化する時に便利な機能です。JUnit5では@Enclosedテストランナーは廃止されましたが、@Nestedアノテーションで同様の機能を提供します。}}JUnit4との大きな違いは、ネストしたテストクラスが非staticなインナークラスとなったことです。したがって、アウタークラスの変数にアクセスすることができます。アウタークラス側にもテストメソッドを定義できるため、サンプルのように「空のオブジェクトに対するテスト」と、「オブジェクトに子を追加した場合のテスト」を構造化して定義することができるようになりました。テストの拡張JUnit5では、RuleやTestRunnerとは異なる形でテストを拡張することができます。イメージとしてはTestRunnerに近く、テストの実行前などにフックを行い、共通の前処理などを行うことになります。Mockitoの拡張を作ったならば次のように宣言します。...}実装例はこちらにありますが、テストの前処理やパラメータなどをハンドリングするメソッドを実装するだけなので、魔改造に近かったJUnitのTestRunnerより使いやすいでしょう。テストメソッドの引数が自由となり、拡張ポイントからパラメータを渡せるのは大きな変更点になります。パラメータ化テスト現時点ではパラメータ化テストに相当する機能はJUnit5のコア機能では提供されていません。これも拡張機能を利用すれば実現する事は可能と思われます。JUnit5のcore機能ではなく、拡張機能や外部ライブラリとして提供されるのでは?という感じです。まとめJUnit5はJUnit4に似た部分はありますが、フレームワークとしては全く別のものとなっています。アノテーションベースのJUnit4の構造を踏襲し、RuleやTestRunnerで無理矢理実装されていた機能を整理して作り直したフレームワークです。基本的にユニットテストの手法を学んでいれば違和感なく使うことは可能かと思いますが、移行の過渡期では互換性の低さがネックになることは否めません。今後、どのようなプロダクトになるかは解らない部分はありますが、現状はこんな感じで準備されています。2,874,987札幌の猫大好きエンジニア。著書に「JUnit実践入門」。趣味はロードバイクやスノーボードなど。Developers.IOでは、ユニットテスト・AWS・Ansibleの話題などを書いています。〜ログ収集、監視、分析を触って体感しよう!〜」を開催しますお申し込み受付は終了しました。ありがとうございました。今後セミナーのお知らせを受け取りたい方は、こちらからご登録をお願いします。CAFEのサービスが「LINEアプリ」として利用できるようになりました。これまではLINEのトークから利用する形でしたが、LINEサービス内から利用できるようになりました。これまでより便利に、シームレスにご利用いただけます。Cafe300件のシェア(そこそこ話題の記事)インフラ未経験の私が内定から入社までに読んだ技術書11冊ブログ記事2020年01月16日Yui300インフラ未経験で入社した私がインフラを勉強するために読んだ技術書11冊を感想とともにまとめました。平野重利123Pythonで、標準入力を変換して標準出力に出すCLIプログラムのテンプレートをご紹介します。菊池修治47こんにちは、菊池です。勉強会#1に登壇しました。サーバのみならずネットワーク機器の仮想化も年々進んでいます。スペックに縛られないこととか、展開のしやすさとか初期考慮点が少なくなるのは嬉しいです。武田隆志1098このエントリは、2018年、2019年に公開したAWS全サービスまとめの2020年版です。これまではいくつかに分割して公開していましたが、1エントリにまとめてほしいという要望をもらっていたため、今年は1エントリに集約してみました。CAFEのサービスが「LINEアプリ」として利用できるようになりました。これまではLINEのトークから利用する形でしたが、LINEサービス内から利用できるようになりました。これまでより便利に、シームレスにご利用いただけます。Cafe300件のシェア(そこそこ話題の記事)インフラ未経験の私が内定から入社までに読んだ技術書11冊ブログ記事2020年01月16日Yui300インフラ未経験で入社した私がインフラを勉強するために読んだ技術書11冊を感想とともにまとめました。悠紀235ShifterはWordPress環境をサーバーレスで立ち上げ、静的なサイトを生成することができるサービスです。FAQサイトをサクッと作ってみました。Takumi227こんにちは。DA事業本部の春田です。クラスメソッド株式会社が運営するAWS・iOS・HTML5に関する技術情報サイトです。