6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JUnit5: ParameterizedTest+ArgumentSetでテスト出力を改善

Posted at

JUnit 5.11の新機能 - ArgumentSetとは?

JUnit5では、ParameterizedTestを使用することで入力・出力の単純な繰り返しを単純化することができるようになりました。

しかし、5.10までは名前を付けながら複数の引数を設定することが難しかったため、例えば[1]テストケース名[2]インプット[3]期待値となるような書き方をするテストケースの表示はあまり改善できていませんでした。

5.11以降は、ArgumentSetを使用することで入力・出力の単純な繰り返しがさらに改善されます。

改善例

今回の例は、nablarch-exmample-webのProjectProfitTestを例に改善例を示します。

改善前

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

    @Nested
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    class 配賦前利益 {
        List<Param<Long>> parameters() {
            return Arrays.asList(
                    new Param<>(new ProjectProfit(987654321, 123456789, 12345678, 300), 851851854L),
                    new Param<>(new ProjectProfit(999999999, 0, 0, 300), 999999999L),
                    new Param<>(new ProjectProfit(0, 999999999, 999999999, 300), -1999999998L),
                    new Param<>(new ProjectProfit(0, 0, 0, 300), 0L),
                    new Param<Long>(new ProjectProfit(null, 2000000, 1000000, 300), null),
                    new Param<Long>(new ProjectProfit(3000000, null, 1000000, 300), null),
                    new Param<Long>(new ProjectProfit(3000000, 2000000, null, 300), null),
                    new Param<>(new ProjectProfit(3000000, 2000000, 1000000, null), 0L),
                    new Param<Long>(new ProjectProfit(null, null, null, 300), null)
            );
        }

        @ParameterizedTest
        @MethodSource("parameters")
        void test(Param<Long> param) throws Exception {
            assertThat(param.projectProfit.getProfitBeforeAllocation(), is(param.expected));
        }
    }
    
    private static class Param<T> {

        private ProjectProfit projectProfit;

        private T expected;

        public Param(final ProjectProfit projectProfit, final T expected) {
            this.projectProfit = projectProfit;
            this.expected = expected;
        }
    }

出力

  • 改善前のテストは、下記の点でやや読みづらい
    1. どのようなケースかの説明がない。ProjectProfitTest$Param@...部分の情報には意味がない
    2. 期待値が表示されない

image.png

改善後

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

    static List<Arguments.ArgumentSet> caseGetGrossProfit() {
        return List.of(
                caseOf("正常値", new ProjectProfit(987654321, 123456789, 12345678, 300), 851851854L),
                caseOf("売上高上限値", new ProjectProfit(999999999, 0, 0, 300), 999999999L),
                caseOf("売上原価・販管費上限値", new ProjectProfit(0, 999999999, 999999999, 300), -1999999998L),
                caseOf("売上高・売上原価・販管費0", new ProjectProfit(0, 0, 0, 300), 0L),
                caseOf("売上高null", new ProjectProfit(null, 2000000, 1000000, 300), null),
                caseOf("売上原価null", new ProjectProfit(3000000, null, 1000000, 300), null),
                caseOf("販管費null", new ProjectProfit(3000000, 2000000, null, 300), null),
                caseOf("本社配賦null", new ProjectProfit(3000000, 2000000, 1000000, null), 0L),
                caseOf("売上高・売上原価・販管費null", new ProjectProfit(null, null, null, 300), null)
        );
    }
    
    @DisplayName("配賦前利益")
    @ParameterizedTest(name = "[{index}] {argumentSetNameOrArgumentsWithNames} - 期待値: {1}")
    @MethodSource("caseGetGrossProfit")
    public void testGetGrossProfit(ProjectProfit projectProfit, Long expected) throws Exception {
        assertThat(projectProfit.getProfitBeforeAllocation(), is(expected));
    }
    
    private static<E> Arguments.ArgumentSet caseOf(String name, ProjectProfit projectProfit, E expected){
        return argumentSet(name, projectProfit, expected);
    }

出力

  • 改善後のテストは、下記の点が改善されている
    1. どのようなケースかの説明が表示される
    2. 期待値が表示される

image.png

参考資料

(JUnitリリースノート)New Features and Improvements

(JUnitユーザーガイド)2.17.6. Customizing Display Names

(javadoc)org.junit.jupiter.params.provider.Arguments#argumentSet

Github

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?