Scala Check & Leetcode
发布于
- 修改于
2021/01/09
- 大约需要 2 分钟
- 611 字
起因
起因只是单纯在了解了属性测试之后觉得非常有趣,想要试试,但是能用到的场合并不是很多。在算法竞赛的时候,很多时候会有很多边界条件会没有注意,而如果提交错误回答是会被惩罚。因此便想到对于某些问题使用属性测试,而不是靠自己想。
注意:仅供娱乐
使用
此处以Leetcode 136题作为例子:
build.sbt
:
scalaVersion := "2.13.3"
libraryDependencies += "org.scalactic" %% "scalactic" % "3.2.2"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test"
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.15.2" % "test"
libraryDependencies += "org.scalatestplus" %% "scalacheck-1-14" % "3.2.2.0" % "test"
lazy val root = (project in file("."))
Leetcode.scala
:
object Solution {
def singleNumber(nums: Array[Int]): Int = ???
}
LeetcodeTest.scala
:
import org.scalacheck.Prop.{forAll, propBoolean}
import org.scalacheck.Gen
import org.scalacheck.Arbitrary
import org.scalatestplus.scalacheck.Checkers
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import scala.util.Random
class LeetCodeSuite extends AnyFunSuite with Checkers with Matchers {
test("Standard test") {
Solution.singleNumber(Array(2, 2, 1)) should equal(1)
Solution.singleNumber(Array(4, 1, 2, 1, 2)) should equal(4)
}
test("props test") {
val props = forAll((set: Set[Int], value: Int) =>
!set.contains(value) ==> (Solution.singleNumber(
Random.shuffle(set.toVector ++ set.toVector :+ value).toArray
) == value)
)
check(props)
}
}
测试部分采用了scalatest
作为框架,并采用AnyFunSuite
这种风格来写测试,同时使用了Matchers
,这样对于常规的测试部分就可以用should equal
这种贴近自然语言的方式进行断言,而不是在一个布尔表达式外套一个assert
。
另外依靠scalatestplus
这个scalatest
的附加库来使用Checkers
直接check(props)
。
属性测试部分,首先需要找到输入。显然一般的Array[Int]
并不符合题目中所说的一个非空整数数组,除了某个元素只出现过一次以外,其余每个元素均出现两次这个条件。因此我采用了Set[Int]
来获得其余每个元素,在重复两遍并加上一个不在这个集合中的元素后再进行打乱。最后我们可以断言对生成后的数组,我们的函数可以找到只出现过一次的数字。