如何用ScalaCheck生成等大集合用于匹配算法属性测试?
完善基于属性的测试:生成等量的Man/Woman集合
我来帮你把这段代码补全,针对匹配算法的属性测试需求,生成大小完全一致的两组输入集合~
首先得把缺失的排序逻辑补上,你原代码里提到的Man.womanByQuality还没定义,咱们先把这部分落地,让排序规则清晰:
case class Man(id: Long, quality: Long, ordering: Ordering[Woman]) case class Woman(id: Long, quality: Long, ordering: Ordering[Man]) // 定义Man对Woman的排序逻辑:按quality从高到低 object Man { val womanByQuality: Ordering[Woman] = Ordering.by(-_.quality) } // 定义Woman对Man的排序逻辑:同样按quality从高到低(也可根据需求修改) object Woman { val manByQuality: Ordering[Man] = Ordering.by(-_.quality) }
接下来完善生成器Gen[Man]和Gen[Woman],确保每个实例都带上正确的排序规则:
import org.scalacheck.Gen val manGen: Gen[Man] = for { id <- Gen.posNum[Long] quality <- Gen.posNum[Long] } yield Man(id, quality, Man.womanByQuality) val womanGen: Gen[Woman] = for { id <- Gen.posNum[Long] quality <- Gen.posNum[Long] } yield Woman(id, quality, Woman.manByQuality)
核心需求是生成两组大小相同的集合,这里可以先随机生成一个集合大小,再分别生成对应数量的Man和Woman:
// 生成大小完全匹配的Man、Woman集合对 val matchedSetsGen: Gen[(List[Man], List[Woman])] = for { // 可根据测试需求调整集合大小范围,比如1到100个实例 size <- Gen.choose(1, 100) men <- Gen.listOfN(size, manGen) women <- Gen.listOfN(size, womanGen) } yield (men, women)
如果想避免测试中出现重复ID的干扰,还可以加一层去重逻辑:
// 生成ID唯一的Man集合 val uniqueManListGen: Gen[List[Man]] = Gen.sized { size => Gen.listOfN(size, Gen.posNum[Long].distinct).map { uniqueIds => uniqueIds.map(id => Man(id, Gen.posNum[Long].sample.get, Man.womanByQuality)) } } // 同理生成ID唯一的Woman集合,再组合成等量对 val uniqueMatchedSetsGen: Gen[(List[Man], List[Woman])] = for { size <- Gen.choose(1, 100) men <- Gen.listOfN(size, manGen).map(_.distinctBy(_.id)) women <- Gen.listOfN(size, womanGen).map(_.distinctBy(_.id)) } yield (men, women)
最后就可以用这个生成器写属性测试了,比如验证匹配算法的稳定性、匹配数量等特性:
import org.scalacheck.Prop.forAll val matchingAlgorithmProp = forAll(matchedSetsGen) { case (men, women) => // 调用你的匹配算法 val matches = yourMatchingAlgorithm(men, women) // 断言结果符合预期,比如匹配数量等于集合大小 matches.size == men.size && matches.forall { case (man, woman) => // 这里可以加更具体的断言,比如双方是否在彼此的偏好列表前列 true // 替换成你的实际验证逻辑 } } // 运行测试 matchingAlgorithmProp.check()
内容的提问来源于stack exchange,提问作者davidrpugh
相关产品推荐
相关产品推荐

