Scala学习笔记 之 ScalaTest

ScalaTest提供了好多种单元测试的方法,这里记录其目前官网推荐的用法。

FlatSpec示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import collection.mutable.Stack
import org.scalatest._

class ExampleSpec extends FlatSpec with Matchers {

"A Stack" should "pop values in last-in-first-out order" in {
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
stack.pop() should be (2)
stack.pop() should be (1)
}

it should "throw NoSuchElementException if an empty stack is popped" in {
val emptyStack = new Stack[Int]
a [NoSuchElementException] should be thrownBy {
emptyStack.pop()
}
}
}

这里继承了FlatSpec,可以看到其用法非常的”Human Readable”,所以基本上就不用解释了。

命令行

编译的命令:

1
$ scalac -cp scalatest_2.11-2.2.4.jar ExampleSpec.scala

运行的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ scala -cp scalatest_2.11-2.2.4.jar org.scalatest.run ExampleSpec
Discovery starting.
Discovery completed in 21 milliseconds.
Run starting. Expected test count is: 2
ExampleSpec:
A Stack
- should pop values in last-in-first-out order
- should throw NoSuchElementException if an empty stack is popped
Run completed in 76 milliseconds.
Total number of tests run: 2
Suites: completed 1, aborted 0
Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0
All tests passed.

定义抽象基类UnitSpec

另外官网给出了一个用法建议,就是可以自己写一个抽象类,在抽象类中写入继承和混入 的特质(也就是选定我们的测试Style),这样我们在自己写代码的时候就只需要从我们自己写的抽象类继承了。虽然这个类的名称可以随意起,但是官网推荐使用UnitSpec这个名称。

1
2
3
4
5
6
package com.mycompany.myproject

import org.scalatest._

abstract class UnitSpec extends FlatSpec with Matchers with
OptionValues with Inside with Inspectors
1
2
3
4
5
6
7
package com.mycompany.myproject

import org.scalatest._

class MySpec extends UnitSpec {
// Your tests here
}

在eclipse中用JUnit运行

如果要你定义的Spec能在Eclipse中用JUnit运行,则需要在Spec上加上这样的一句话:

1
2
3
4
5
6
7
8
9
10
package com.mycompany.myproject

import org.scalatest._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

@RunWith(classOf[JUnitRunner])
class MySpec extends UnitSpec {
// Your tests here
}

注意需要在maven中添加junit依赖。

Marchers

上面的实例中混入了特质Matchers,这个特质是非常强大的。在混入它之前,只能使用assert来进行测试。混入它之后,就可以使用一些非常易读的测试方法。

这里需要注意的是should beshould equal的用法:

1
2
3
4
5
result should equal (3) // can customize equality
result should === (3) // can customize equality and enforce type constraints
result should be (3) // cannot customize equality, so fastest to compile
result shouldEqual 3 // can customize equality, no parentheses required
result shouldBe 3 // cannot customize equality, so fastest to compile, no parentheses required

上面非常明确的列举了出来,只有should equal才会调用自定义的相等方法。自定义相等方法记录在这里

更具体的用法可以在其官网的文档上查询使用。