这是我参与更文挑战的第19天,活动详情查看: 更文挑战
前情提示
至此我们在前几天已经学习了三个实例的学习,相信大家对OptaPlanner有了一个更深的学习。大家会发现这几个例子我们使用的都是Drools来编写约束和评分。在这几个例子的学习,大家会有一个疑问,我们增加或者修改约束,如何测试约束是否生效了,匹配的情况如何?那么今天就来学习下基于Drools方式的约束测试内容。
内容
基于Drools的约束条件有一个单元测试工具,要使用它,首先要添加optaplanner-test.jar
,以利用JUnit集成的优势,并使用ScoreVerifier
类来测试DRL中的分数规则(或一个约束匹配的增量分数计算器)。例如,我们来看CloudBalance
案例,测试这些分数规则:
global HardSoftScoreHolder scoreHolder;
rule "requiredCpuPowerTotal"
when
...
then
scoreHolder.addHardConstraintMatch(...);
end
...
rule "computerCost"
when
...
then
scoreHolder.addSoftConstraintMatch(...);
end
复制代码
实现
对于每个评分规则,创建一个单独的@Test
,只测试该评分规则对分数的影响。
CloudBalancingScoreConstraintTest.java
public class CloudBalancingScoreConstraintTest {
private HardSoftScoreVerifier<CloudBalance> scoreVerifier = new HardSoftScoreVerifier<>(
SolverFactory.createFromXmlResource(CloudBalancingApp.SOLVER_CONFIG));
@Test
public void requiredCpuPowerTotal() {
......
}
@Test
public void requiredMemoryTotal() {
......
@Test
public void requiredNetworkBandwidthTotal() {
......
}
@Test
public void computerCost() {
CloudComputer c1 = new CloudComputer(1L, 1, 1, 1, 200);
CloudComputer c2 = new CloudComputer(2L, 1, 1, 1, 30);
CloudComputer c3 = new CloudComputer(3L, 1, 1, 1, 4);
CloudProcess p1 = new CloudProcess(1L, 5, 5, 5);
CloudProcess p2 = new CloudProcess(2L, 5, 5, 5);
CloudProcess p3 = new CloudProcess(3L, 5, 5, 5);
CloudBalance solution = new CloudBalance(0L,
Arrays.asList(c1, c2, c3),
Arrays.asList(p1, p2, p3));
scoreVerifier.assertSoftWeight("computerCost", 0, solution);
p1.setComputer(c1);
p2.setComputer(c1);
scoreVerifier.assertSoftWeight("computerCost", -200, solution);
p3.setComputer(c3);
scoreVerifier.assertSoftWeight("computerCost", -204, solution);
}
}
复制代码
可以看到,如果我们测试某一个规则,最好单独增加一个方法进行测试。
测试方法
我们来看这一个约束测试:
@Test
public void computerCost() {
CloudComputer c1 = new CloudComputer(1L, 1, 1, 1, 200);
CloudComputer c2 = new CloudComputer(2L, 1, 1, 1, 30);
CloudComputer c3 = new CloudComputer(3L, 1, 1, 1, 4);
CloudProcess p1 = new CloudProcess(1L, 5, 5, 5);
CloudProcess p2 = new CloudProcess(2L, 5, 5, 5);
CloudProcess p3 = new CloudProcess(3L, 5, 5, 5);
CloudBalance solution = new CloudBalance(0L,
Arrays.asList(c1, c2, c3),
Arrays.asList(p1, p2, p3));
scoreVerifier.assertSoftWeight("computerCost", 0, solution);
p1.setComputer(c1);
p2.setComputer(c1);
scoreVerifier.assertSoftWeight("computerCost", -200, solution);
p3.setComputer(c3);
scoreVerifier.assertSoftWeight("computerCost", -204, solution);
}
复制代码
测试步骤
首先我们需要new
一个Solution对象,CloudBalance
案例中的Solution类为CloudBalance.java
。然后进行数据初始化。
CloudProcess
是一个PlanningEntity
,其中的computer
属性是PlanningVariable
,我们可以通过修改这个变量后,通过assertSoftWeight
断言方法来测试结果是否符合我们的预期。
步骤1:初始化Progress
未分配Computer
的,其成本为0;
步骤2:p1
和p2
线程分配Computer
中c1
的机器,其成本为-200元;
步骤3:p3
线程分配Computer
中c3
的机器,其成本为-204元;
我们执行一下看看结果:
com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit5 org.optaplanner.examples.cloudbalancing.solver.CloudBalancingScoreConstraintTest,computerCost
Process finished with exit code 0
复制代码
此时我们修改一行:
......
scoreVerifier.assertSoftWeight("computerCost", 0, solution);
p1.setComputer(c1);
p2.setComputer(c1);
scoreVerifier.assertSoftWeight("computerCost", 0, solution); // 200 -> 0
......
复制代码
此时我们再来看结果:
org.opentest4j.AssertionFailedError:
Expected :0
Actual :-200
<Click to see difference>
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher$$Lambda$132/695682681.accept(Unknown Source)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
复制代码
预期结果Expected与Actual结果不相符。
总结
通过这个例子,我们学习了OptaPlanner如何测试Drools的约束规则,这对我们来说非常的重要,因为你不会期望着在生产环境测试,或者本地需要一套完整的求解数据才能开始测试。
结束语
下一篇章我们来学习ConstraintStream
的测试例子。
创作不易,禁止未授权的转载。如果我的文章对您有帮助,就请点赞/收藏/关注鼓励支持一下吧??????