3

I am currently working with dynamic weights configured in a ConstraintConfiguration class. But the class doesn't seem to be used while executing my tests that I wrote. It is however used while actually executing the solver.

For example: one of the weights in the configuration class is 16. While testing for a score of 1, it will not be multiplied with the weight and the result will be 1. But while actually solving, it will use it and it will be 16 as expected.

I am guessing that I'm missing something in my testing class. Do you have to tell the ConstraintVerifier or the testing methods in the testing class that there is a ConstraintConfiguration? Or am I missing something else?

Thanks in advance.

My current constraintverifier:

ConstraintVerifier<ExamScheduleConstraintProvider, ExamSchedule> constraintVerifier = ConstraintVerifier.build(
            new ExamScheduleConstraintProvider(), ExamSchedule.class, Exam.class);

Example of test code that won't pass:

constraintVerifier.verifyThat(ExamScheduleConstraintProvider::TestConstraint)
                .given(firstExam, secondExam)
                .penalizesBy(16);
kwaki
  • 33
  • 3

2 Answers2

2

The ConstraintVerifier offers two verification methods:

  1. verifyThat(constraintFunction);
  2. verifyThat();

verifyThat(constraintFunction) accepts a method reference to an individual constraint and verifies that the constraint, given certain entities and facts or an entire solution, penalizes or rewards by the expected match weight. Important to note, this verifier ignores constraint weight completely.

verifyThat() does not accept any argument and checks the score impact (including constraint weight coming from ConstraintConfiguration) of all the constraints defined in the ConstraintProvider implementation for the provided entities and facts or an entire solution.

Radovan Synek
  • 954
  • 6
  • 11
  • Thanks for the quick response. I've changed the test to the following with the help of your info. `constraintVerifier.verifyThat().given(firstExam, secondExam) .scores(HardSoftScore.of(0,16)); ` Now it, should be using the ConstraintConfiguration. But my test still fails (1 soft instead of 16). Any other thoughts? – kwaki Dec 21 '21 at 11:01
  • That's difficult to say without knowing the constraints. Nevertheless, the safest approach is to verify the individual constraints first using the `verifyThat(constraintFunction)` and only after you make sure they work up to your expectations, verify the entire score using the `verifyThat()` as the last step. – Radovan Synek Dec 21 '21 at 15:25
  • Thanks a lot, Radovan! I found my mistake in the constraint. – kwaki Dec 22 '21 at 00:39
2

In addition to Radovan's response, I will provide some rationale for why ConstraintVerifier works the way it does.

For individual constraints, it does not take ConstraintConfiguration into account. That is because ConstraintConfiguration is solution-specific, and we want to be able to test consraints individually and independently. In this case, we only test match weights; match weights exist regardless of the solution, and regardless of constraint configuration. This would be your typical unit test. (If you prefer another way of thinking about this, consider the fact that constraint configuration is optional and most do not, in fact, use it.)

For integration testing, we support testing an entire solution. And when you test all the constraints as a whole, that is where we take your ConstraintConfiguration into account.

Lukáš Petrovický
  • 3,945
  • 1
  • 11
  • 20