Maven 和 JUnit 初步尝试

最近由于软件构造课的实验需要,我需要进行 Java 的单元测试。但是 Eclipse 的体验个人不太 喜欢,IDEA 在自己的渣笔记本又太慢,所以学习使用 Maven 来管理和测试。

此时大喊 emacs 大法好!!!

Maven

Maven 是 Apache 开源组织的一个开源项目,Maven 的本质是一个项目管理工具,将项目开发和 管理过程抽象成一个项目对象模型(Project Object Model,POM)。

Maven 的主要功能有:

  • 提供了一套标准化的项目结构;
  • 提供了一套标准化的构建流程(编译,测试,打包,发布……);
  • 提供了一套依赖管理机制。

安装 Maven

Windows

首先需要安装 JDK,然后从 Maven 官网 下载 Maven,之后解压、配置环境变量。

1
2
M2_HOME=/path/to/maven-3.6.x
PATH=$PATH:$M2_HOME/bin

Linux

同样可以从官网下载,也可以通过包管理器下载。如 Arch Linux 可以:

1
sudo pacman -S maven

macOS

其实穷人并没有 mac。ε=ε=ε=ε=ε=ε=┌(; ̄ ◇  ̄)┘

判断

可以在终端中输入

1
mvn --version

判断是否安装成功。

配置镜像

由于种种原因,Maven 的官方源访问十分慢,需要配置国内镜像源。我使用的是阿里的源。

方式一

修改/path/to/maven/conf/settings.xml,在 mirrors 节点下面添加子节点:

1
2
3
4
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>

方式二

在~/.m2 中修改文件 settings.xml,这样不用使用 root 权限,而且可以为每个用户使用单独的配置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<settings>
  <mirrors>
    <mirror>
      <id>aliyun</id>
      <name>aliyun</name>
      <mirrorOf>central</mirrorOf>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
  </mirrors>
</settings>

方式三

单项目配置时,需要修改 pom 文件。pom 文件中,没有 mirror 元素。在 pom 文件中,通过覆盖 默认的中央仓库的配置,实现中央仓库地址的变更。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>conifg</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>

<repositories>
    <repository>
        <id>central</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <layout>default</layout>
        <!-- 是否开启发布版构件下载 -->
        <releases>
            <enabled>true</enabled>
        </releases>
        <!-- 是否开启快照版构件下载 -->
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

使用 Maven

Maven 的关键是项目描述文件 pom.xml。下面是我此次实验中使用的 pom.xml。

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>HIT</groupId>
    <artifactId>cycleke</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <source>8</source>
        <target>8</target>
    </properties>

    <build>
        <sourceDirectory>src</sourceDirectory>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src</directory>
                <includes>
                    <include>*.*</include>
                </includes>
            </resource>
            <resource>
                <filtering>true</filtering>
                <directory>txt</directory>
                <includes>
                    <include>*.*</include>
                </includes>
            </resource>
        </resources>

        <testSourceDirectory>test</testSourceDirectory>
        <testResources>
            <testResource>
                <filtering>true</filtering>
                <directory>src</directory>
                <includes>
                    <include>*.*</include>
                </includes>
            </testResource>
            <testResource>
                <filtering>true</filtering>
                <directory>txt</directory>
                <includes>
                    <include>*.*</include>
                </includes>
            </testResource>
        </testResources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>

其中,groupId 类似于 Java 的包名,通常是公司或组织名称,artifactId 类似于 Java 的类名 ,通常是项目名称,再加上 version,一个 Maven 工程就是由 groupId,artifactId 和 version 为唯一标识。我们在引用其他第三方库的时候,也是通过这 3 个变量确定。

注意上述版本的SNAPSHOT,SNAPSHOT 版本和正式版本的区别可见理解 Maven 中的 SNAPSHOT 版本和正式版本

标准的 Maven 项目结构是

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
maven-project
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   └── test
│       ├── java
│       └── resources
└── target

其中 src 中存放代码,main 是主要代码,test 是测试代码,java 放代码文件,resources 放资 源;target 存放生成的文件。

但是我们可以通过 pom.xml 修改和添加 src 等文件,如上面的 pom.xml 将代码目录修改了 src 和 test 目录,项目结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Lab1
├── src
│   ├── P1
│   ├── P2
│   └── P3
├── test
│   ├── P1
│   ├── P2
│   └── P3
└── target

通过 pom.xml,我们还可以配置插件(如上面的 maven-compiler-plugin)和第三方库(junit)。

常用指令

下面是 Maven 的常用指令:

命令 作用
mvn clean 清理所有生成的 class 和 jar
mvn clean compile 先清理,再编译
mvn clean test 先清理,再编译、运行测试
mvn clean package 先清理,再编译、测试、打包
mvn exec:exec 运行程序
mvn dependency:tree 查看依赖关系

JUnit

JUnit 是一个开源的 Java 语言的单元测试框架,专门针对 Java 设计,使用最广泛。一般的 IDE 都支持 JUnit 或对应的插件。JUnit 已经发展到 JUnit5,然而一般用的似乎是 JUnit4。

又想起还有多少项目在 Java8。。。GTMD Oracle

JUnit 的测试方法有@Test注释,如下例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package P1;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class MagicSquareTest {
  @Test
  public void isLegalMagicSquareTest() {
    boolean[] corrects = new boolean[] { true, true, false, false, false, true };
    for (int i = 0; i < 6; ++i) {
    String fileName = String.format("txt/%d.txt", i + 1);
      assertEquals(corrects[i], MagicSquare.isLegalMagicSquare(fileName));
    }
  }

  @Test
  public void generateMagicSquareTest()  {
    assertEquals(false, MagicSquare.generateMagicSquare(0));
    assertEquals(false, MagicSquare.generateMagicSquare(2));
    assertEquals(true, MagicSquare.generateMagicSquare(101));
  }
}

assertEquals会判断函数运行结果是否与期望相同。 Assertion还定义了其他断言方法,可以翻阅wiki 查看。

JUnit 还可以通过如下方式测试异常:

1
2
3
4
@Test(expected = RuntimeException.class)
public void expectedTest() {
  throws new RuntimeException("/人◕ ‿‿ ◕人\");
}

写完单元测试后在 Maven 加入 JUnit 第三方库依赖,然后运行mvn clean test测试。

参考

  1. Maven 官网
  2. Maven 介绍
  3. Maven 之阿里云镜像仓库配置
  4. 理解 Maven 中的 SNAPSHOT 版本和正式版本
  5. 如何查看 Maven 项目中的 jar 包依赖树情况?
  6. JUnit 官网
comments powered by Disqus