Menu Close
Settings Close

Language and Page Formatting Options

10.8. アプリケーションのテスト

適切なアプリケーションにはテストが含まれます。時間割プロジェクトで制約とソルバーをテストします。

10.8.1. 時間割の制約のテスト

時間割プロジェクトの各制約を分離してテストするには、ユニットテストで ConstraintVerifier を使用します。これにより、各制約のコーナーケースが他のテストから分離され、適切なテストカバレッジで新しい制約を追加する場合のメンテナンスが低くなります。

このテストは、同じ部屋で 3 つの授業があり、授業の 2 つの授業に同じ時間帯が指定されている場合に、制約 TimeTableCon straintProvider::roomConflict が指定されていることを確認します。一致の重み 1 でペナルネートします。そのため、制約の重みが 10hard の場合、スコアは -10hard 低くなります。

手順

src/test/java/org/acme/optaplanner/solver/TimeTableConstraintProviderTest.java クラスを作成します。

package org.acme.optaplanner.solver;

import java.time.DayOfWeek;
import java.time.LocalTime;

import javax.inject.Inject;

import io.quarkus.test.junit.QuarkusTest;
import org.acme.optaplanner.domain.Lesson;
import org.acme.optaplanner.domain.Room;
import org.acme.optaplanner.domain.TimeTable;
import org.acme.optaplanner.domain.Timeslot;
import org.junit.jupiter.api.Test;
import org.optaplanner.test.api.score.stream.ConstraintVerifier;

@QuarkusTest
class TimeTableConstraintProviderTest {

    private static final Room ROOM = new Room("Room1");
    private static final Timeslot TIMESLOT1 = new Timeslot(DayOfWeek.MONDAY, LocalTime.of(9,0), LocalTime.NOON);
    private static final Timeslot TIMESLOT2 = new Timeslot(DayOfWeek.TUESDAY, LocalTime.of(9,0), LocalTime.NOON);

    @Inject
    ConstraintVerifier<TimeTableConstraintProvider, TimeTable> constraintVerifier;

    @Test
    void roomConflict() {
        Lesson firstLesson = new Lesson(1, "Subject1", "Teacher1", "Group1");
        Lesson conflictingLesson = new Lesson(2, "Subject2", "Teacher2", "Group2");
        Lesson nonConflictingLesson = new Lesson(3, "Subject3", "Teacher3", "Group3");

        firstLesson.setRoom(ROOM);
        firstLesson.setTimeslot(TIMESLOT1);

        conflictingLesson.setRoom(ROOM);
        conflictingLesson.setTimeslot(TIMESLOT1);

        nonConflictingLesson.setRoom(ROOM);
        nonConflictingLesson.setTimeslot(TIMESLOT2);

        constraintVerifier.verifyThat(TimeTableConstraintProvider::roomConflict)
                .given(firstLesson, conflictingLesson, nonConflictingLesson)
                .penalizesBy(1);
    }

}

ConstraintVerifierConstraintProvider でハードコーディングされた制約の重みがあっても、テスト中に制約の重みを無視することに注意してください。これは、実稼働環境に移行する前に制約の重みが定期的に変更されるためです。このようにして、制約の重み調整によってユニットテストが中断されることはありません。