Scala项目代码质量

本文基于Scala和Java进行混合编程的Maven项目介绍搭建代码质量设施,本文旨在快速理解以及搭建过程,并不侧重介绍每个工具的具体使用方法,详细参见各相关文档。

构建代码风格设施

Java风格

Maven Checkstyle

Checkstyle插件基于一组约定的代码编程风格规则,对项目中Java代码进行检查,最终检查生成报告。其内预定义了两个规则集:sun_checks.xmlgoogle_checks.xml

参看:Maven Checkstyle简介

运行Checkstyle

使用Checkstyle Maven插件有三种方式,参看Maven Checkstyle用法

  • Checkstyle报告作为项目所有报告的一部分,借助<reporting/>元素和mvn site命令;
  • 如果不需要进行针对性的配置,可以直接运行mvn checkstyle:checkstyle命令来生成Checkstyle报告,而不需要在pom.xml中配置Checkstyle插件;
  • 将Checkstyle绑定到项目Maven项目的构建过程,这样可以使用Checkstyle的检查结果来决定项目构建是否继续进行;

Scala风格

Scalastyle

Scalastyle可以认为是Scala版本的Maven Checkstyle,用于检查Scala代码并给出检查报告。Scalastyle为我们提供了一个默认的配置scalastyle_config.xml

参看:Scalastyle简介

运行Scalastyle

Maven插件

以下配置指定了:

  • <sourceDirectory/>:源码路径
  • <testSourceDirectory/>:test源码路径
  • <configLocation/>:风格文件
  • <outputFile/>:检查报告输出文件
  • 并且,check mojo没有绑定到Maven项目的构建过程当中,而是要独立运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugin>
<groupId>org.scalastyle</groupId>
<artifactId>scalastyle-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<verbose>false</verbose>
<failOnViolation>true</failOnViolation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<failOnWarning>false</failOnWarning>
<sourceDirectory>${project.basedir}/src/main/scala</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/scala</testSourceDirectory>
<configLocation>${project.basedir}/style/scalastyle_config.xml</configLocation>
<outputFile>${project.build.directory}/scalastyle-output.xml</outputFile>
<outputEncoding>UTF-8</outputEncoding>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>

运行mvn scalastyle:check并查看输出报告:

构建测试设施

Java测试

JUnit

参考:

1
2
3
4
5
6
7
8
9
10
<dependencies>
... ...
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
... ...
</dependencies>

运行JUnit测试单元

Maven插件

Surefire插件用于在Maven项目构建生命周期中的test阶段执行单元测试。

参看:Surefire介绍

以下配置指定了:

  • <includes/>:对java文件名称满足规则的运行的单元测试
  • <reportsDirectory>:单元测试报告输出路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugins>
... ...

<!-- Surefire runs all Java tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
<include>**/*Suite.java</include>
</includes>
<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
</configuration>
</plugin>
... ...
</plugins>

运行mvn test并查看测试报告(注意,我们的demo项目中包含一个名为JavaExampleTest的测试单元):

Scala测试

Scala单元测试框架有ScalaTest、specs2、ScalaCheck,其中ScalaTest最为灵活。

ScalaTest

参看:ScalaTest简介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
... ...

<dependency>
<groupId>org.scalactic</groupId>
<artifactId>scalactic_${scala.binary.version}</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_${scala.binary.version}</artifactId>
<version>3.2.2</version>
<scope>test</scope>
</dependency>

... ...
</dependencies>

运行ScalaTest测试单元

Maven插件

ScalaTest Maven插件包含两个“mojo”:test和reporter,分别针对mvn testmvn site命令。

参看:ScalaTest Maven plugin

以下配置指定了:

  • <reportsDirectory/>:单元测试报告输出路径(注意,这里配置的和Surefire插件配置的输出路径一致)
  • <filereports>:测试报告
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugins>
... ...
<!-- Scalatest runs all Scala tests -->
<plugin>
<groupId>org.scalatest</groupId>
<artifactId>scalatest-maven-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
<junitxml>.</junitxml>
<filereports>WDF TestSuite.txt</filereports>
</configuration>
<executions>
<execution>
<id>test</id>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
... ...
</plugins>

运行mvn test并查看测试报告(注意,我们的demo项目中包含一个名为ScalaExampleSuite的测试单元):

Java测试覆盖率

JaCoCo(Java Code Coverage)

JaCoCo是一个免费的Java代码覆盖率类库,它执行Eclipse Public License。

Maven插件

JaCoCo Maven插件向测试用例提供了JaCoco运行时,可以创建测试报告。该插件提供了很多Maven goal,使用mvn help:describe -Dplugin=org.jacoco:jacoco-maven-plugin -Ddetail可以列出它所提供的goal。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>

运行mvn clean test jacoco:report

Scala测试覆盖率

SCoverage

SCoverage是一个Scala代码覆盖率工具,它执行Apache License,提供语句和分支的覆盖率。

Maven插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<plugin>
<groupId>org.scoverage</groupId>
<artifactId>scoverage-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
<highlighting>true</highlighting>
</configuration>
<executions>
<execution>
<id>instrument</id>
<goals>
<goal>pre-compile</goal>
<goal>post-compile</goal>
</goals>
</execution>
<execution>
<id>scoverage-report</id>
<goals>
<goal>report</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>

运行:mvn clean test scoverage:report

SonarQube

1
docker run -p 80:9000 -d mwizner/sonarqube-scala-plugins:latest-full

访问http://localhost,使用admin/admin进行登录,导航到“Quality Profiles”,我们可以看到sonarqube针对Scala集成了4种质量配置,如下图:

1
mvn -Dsonar.host.url=http://localhost clean test scoverage:report jacoco:report scala:compile sonar:sonar

SonarScala Maven 插件

参考

  1. https://www.scalatest.org/user_guide/using_the_scalatest_maven_plugin
  2. https://www.scalatest.org/user_guide/running_your_tests
  3. https://github.com/jacoco/jacoco
  4. https://www.eclemma.org/jacoco/trunk/doc/maven.html
  5. https://github.com/scoverage/scoverage-maven-plugin
  6. https://sonar-scala.com/
  7. https://github.com/mwz/sonar-scala/tree/master/examples/mvn/scala-java
  8. https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/