Scala项目结构
- Scala项目结构一般是使用Maven约定的项目结构。
IDEA安装Scala插件
- File->Settings->Plugins->Install JetBrains plugin->输入”scala”->搜索->下载->安装

配置Scalastyle
- Scalastyle 官网:http://www.scalastyle.org/
- Scalastyle 默认配置文件
- Scalastyle 默认60条规则说明:http://www.scalastyle.org/rules-0.7.0.html
- IDEA中配置规则:把scalastyle_config.xml 放到项目根目录或项目中.idea目录中
Sacla UnitTest
Scala 的单元测试框架主要有三个:ScalaTest、ScalaCheck和Spec2。其中ScalaTest是比较全面的测试框架。后面也主要使用ScalaTest编写Scala单元测试。以下介绍在各种构建环境下如何导入ScalaTest。同时我们公司开发测试都使用ScalaTest。不同的构建工具,导入ScalaTest的方式稍有区别。
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.11</artifactId>
<version>3.0.1</version>
<scope>test</scope>
</dependency>
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "3.0.1" % "test"
编写ScalaUnitTest
选择测试风格
- ScalaTest支持多种测试书写风格,我们使用推荐的FlatSpec编写单元测试,FeatureSpec编写验收类测试。各种测试风格介绍
定义测试抽象类,推荐命名为:unitSpec
package com.mycompany.myproject
import org.scalatest._
abstract class UnitSpec extends FlatSpec with Matchers with
OptionValues with Inside with Inspectors
使用自定义测试基类,编写测试类
package com.mycompany.myproject
import org.scalatest._
class MySpec extends UnitSpec {
// Your tests here
}
测试类的命名约束
- 单元测试类的命名:被测试类名+UnitSpec,例如:生产代码中有个需要写单元测试的类为:InMemoryResitory.scala,则对应的单元测试类名为:InMemoryResitoryUnitSpec.scala
编写测试主题和测试
在FlatSpec中,用主题来表达一组验证相同功能的测试。用it来表示单个测试,测试可以写成:”A should B”, ”A must B”, ” A can B”, 后面跟in闭包表示需要被测试的代码块。
behavior of "A Stack (with one item)"
it should "be non-empty" in {}
it should "return the top item on peek" in {}
it should "not remove the top item on peek" in {}
it should "remove the top item on pop" in {}
"A Stack (with one item)" should "be non-empty" in {}
it should "return the top item on peek" in {}
it should "not remove the top item on peek" in {}
it should "remove the top item on pop" in {}
import collection.mutable.Stack
import org.scalatest._
class StackSpec extends FlatSpec {
"A Stack" should "pop values in last-in-first-out order" in {
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
assert(stack.pop() === 2)
assert(stack.pop() === 1)
}
it should "throw NoSuchElementException if an empty stack is popped" in {
val emptyStack = new Stack[String]
assertThrows[NoSuchElementException] {
emptyStack.pop()
}
}
}
assert(a == b || c >= d)
// Error message: 1 did not equal 2, and 3 was not greater than or equal to 4
assert(xs.exists(_ == 4))
// Error message: List(1, 2, 3) did not contain 4
assert("hello".startsWith("h") && "goodbye".endsWith("y"))
// Error message: "hello" started with "h", but "goodbye" did not end with "y"
assert(num.isInstanceOf[Int])
// Error message: 1.0 was not instance of scala.Int
assert(Some(2).isEmpty)
// Error message: Some(2) was not empty
- Expected results(预期结果等于实际结果)
val a = 5
val b = 2
assertResult(2) {
a - b
}
val s = "hi"
try {
s.charAt(-1)
fail()
}
catch {
case _: IndexOutOfBoundsException => // Expected, so continue
}
- Share Fixture:before – after
package org.scalatest.examples.flatspec.beforeandafter
import org.scalatest._
import collection.mutable.ListBuffer
class ExampleSpec extends FlatSpec with BeforeAndAfter {
val builder = new StringBuilder
val buffer = new ListBuffer[String]
before {
builder.append("ScalaTest is ")
}
after {
builder.clear()
buffer.clear()
}
"Testing" should "be easy" in {
builder.append("easy!")
assert(builder.toString === "ScalaTest is easy!")
assert(buffer.isEmpty)
buffer += "sweet"
}
it should "be fun" in {
builder.append("fun!")
assert(builder.toString === "ScalaTest is fun!")
assert(buffer.isEmpty)
}
}
运行ScalaUnitTest
ScalaTest支持多种方式运行测试,同样支持 Junit4 Runner方式运行,例子如下:
Run, Debug, Coverage
前提:安装IDEA scala 插件
- IDEA 运行测试
- IDEA Degug 测试
- 测试类->右键点击->选择 Debug ‘XXX’
- IDEA生成覆盖率
- 测试类->右键点击->选择 Run ‘XXX’ with Coverage