走进Java接口测试之构建工具Maven入门_远程仓库

前言

Maven 作为一个构建工具,不仅能帮我们自动化构建、自动化测试、还能够抽象构建过程,提供构建任务实现;它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的、流行的构建工具。Maven 不仅是构建工具,还是一个依赖管理工具和项目管理工具,它提供了中央仓库,能帮助我们自动下载构件。

官网:https://maven.apache.org/

安装

这里只介绍 window下如何安装,在安装 Maven 之前,先确认已经安装了 JDK。

走进Java接口测试之构建工具Maven入门_maven_02

接着去下载附件解压到你想要的目录就行了。

走进Java接口测试之构建工具Maven入门_远程仓库_03

最后设置一下环境变量,将 Maven 安装配置到操作系统环境中,主要就是配置 M2_HOME 和 PATH 两项,如下图:

走进Java接口测试之构建工具Maven入门_远程仓库_04

都搞定后,验证一下,打开 doc 输入 mvn-v 如何得到下面信息就说明配置成功了。

走进Java接口测试之构建工具Maven入门_maven_05

主要目录

走进Java接口测试之构建工具Maven入门_远程仓库_03

  • bin 目录:包含了 mvn 运行的脚本,这些脚本用来配置 java 命令,准备好 classpath 和相关的 Java 系统属性,然后执行Java命令;
  • boot 目录:只包含一个文件,该文件为 plexus-classworlds-2.5.2.jar。 plexus-classworlds 是一个类加载器框架,相对于默认的 java 类加载器,它提供了更加丰富的语法以方便配置,Maven 使用该框架加载自己的类库;
  • conf 目录:包含了一个非常重要的文件 settings.xml。直接修改该文件,就能在机器上全局地定制 Maven 的行为,一般情况下,我们更偏向于复制该文件至 ~/.m2/ 目录下(~表示用户目录),然后修改该文件,在用户范围定制 Maven 的行为;
  • lib 目录:包含了所有 Maven 运行时需要的 Java 类库,Maven 本身是分模块开发的,因此用户能看到诸如 maven-core-3.0.jar、 maven-model-3.0.jar 之类的文件,此外这里还包含一些 Maven 用到的第三方依赖如 commons-cli-1.2.jar、 commons-lang-2.6.jar 等等;

配置加速镜像

maven 仓库默认在国外,使用难免很慢,尤其是下载包的时候,换为国内镜像,让你感受飞一般的感觉。国内支持 maven 镜像的有阿里云,开源中国等,这里示例阿里云的。

打开 maven 的配置文件(一般在 maven 安装目录的 conf/settings.xml),在 <mirrors></mirrors> 标签中添加 mirror 子节点(当然也可以在用户 home 目录 .m2 下面添加一个 settings.xml 文件)。


1. <!-- 阿里云仓库 -->
2. <mirror>
3.     <id>alimaven</id>
4.     <mirrorOf>central</mirrorOf>
5.     <name>aliyun maven</name>
6.     <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
7. </mirror>

以上central 表示该配置为中央库的镜像,任何对于中央仓库的请求都会转至该镜像,用户也可以用同样的方法配置其他仓库的镜像。

这里介绍下配置的各种选项:

  • <mirrorOf>*<mirrorOf>:匹配所有远程仓库;
  • <mirrorOf>external:*<mirrorOf>:匹配所有远程仓库,使用 localhost 的除外,使用 file:// 协议的除外。也就是说,匹配所有不在本机上的远程仓库;
  • <mirrorOf>repo1,repo2<mirrorOf>:匹配仓库 repo1h 和 repo2,使用逗号分隔多个远程仓库;
  • <mirrorOf>*,!repo1<mirrorOf>:匹配所有远程仓库,repo1 除外,使用感叹号将仓库从匹配中排除;

需要注意的是,当镜像仓库不稳定或者停止服务的时候,Maven 仍将无法访问被镜像仓库,因而将无法下载构件。

与IDEA整合

配置

打开 IDEA,在菜单栏中 File->Settings。然后,在 Settings 对话框中选择 Build,Execution, Deployment->BuildTools->Maven。

走进Java接口测试之构建工具Maven入门_spring_07

保存即可。

IDEA中使用

新建一个 maven 项目后会在窗口的右端出现一个 Maven Project 按钮,单击该按钮后弹出下图的对话框:

走进Java接口测试之构建工具Maven入门_maven_08

其中 Lifecycle 中包括了 maven 常用的命令,Dependencies 展示了当前 Maven项目的相关依赖包列表。

简单介绍下 Maven 的常用命令:

  • mvn clean:表示运行清理操作(会默认把 target 文件夹中的数据清理);
  • mvn clean compile:表示先运行清理之后运行编译,会将代码编译到 target 文件夹中;
  • mvn clean test:运行清理和测试;
  • mvn cleanpackage:运行清理和打包;
  • mvn clean install:运行清理和安装,会将打好的包安装到本地仓库中,以便其他的项目可以调用;
  • mvn clean deploy:运行清理和发布(发布到私服上面);

上面的命令大部分都是连写的,大家也可以拆分分别执行,看个人喜好以及使用需求

pom.xml

入门使用

maven 项目的核心是 pom.xml ——POM(Project Object Model 项目对象模型),如下:


1. <?xml version="1.0" encoding="UTF-8"?>
2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.     <modelVersion>4.0.0</modelVersion>
5.     <groupId>com.zuozewei</groupId>
6.     <artifactId>springBootDemo1</artifactId>
7.     <version>0.0.1-SNAPSHOT</version>
8.     <name>springBootDemo1</name>
9. </project>
  • 代码的第一行是 XML 头,指定了该 XML 文档的版本和编码方式;
  • project 是所有 pom.xml 的根元素,它还声明了一些 POM 相关的命名空间及 xsd 元素
  • 根元素下的第一个子元素 modelVersion 指定了当前的 POM 模型的版本,对于 Maven3 来说,它只能是 4.0.0;
  • 代码中最重要是包含了 groupId,artifactId 和 version 了。这三个元素定义了一个项目基本的坐标,在 Maven 的世界,任何的 jar、pom 或者 jar 都是以基于这些基本的坐标进行区分的:
  • groupId:定义了项目属于哪个组,随意命名,比如谷歌公司的myapp项目,就取名为 com.google.myapp;
  • artifactId:定义了当前 Maven 项目在组中唯一的ID,比如定义hello-world。
  • version:指定了项目当前的版本 0.0.1-SNAPSHOT,SNAPSHOT 意为快照,说明该项目还处于开发中,是不稳定的;
  • name:元素生命了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个 POM 声明 name,以方便信息交流;

依赖的配置


1. <dependencies>
2.     <dependency>
3.         <groupId>实际项目</groupId>
4.          <artifactId>模块</artifactId>
5.         <version>版本</version>
6.         <type>依赖类型</type>
7.         <scope>依赖范围</scope>
8.         <optional>依赖是否可选</optional>
9.         <!—主要用于排除传递性依赖-->
10.         <exclusions>
11.              <exclusion>
12.                  <groupId>…</groupId>
13.                 <artifactId>…</artifactId>
14.             </exclusion>
15.             </exclusions>
16.         </dependency>
17. <dependencies>

根元素 project 下的 dependencies 可以包含一个或者多个 dependency 元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:

grounpId、artifactId 和 version: 以来的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven 根据坐标才能找到需要的依赖。

  • type:依赖的类型,对于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值为jar;
  • scope:依赖的范围;
  • optional:标记依赖是否可选;
  • exclusions:用来排除传递性依赖;

如下示例:


1. dependencies>
2.     <dependency>
3.       <groupId>junit</groupId>
4.       <artifactId>junit</artifactId>
5.       <version>4.12</version>
6.     </dependency>
7.     <dependency>
8.     <groupId>org.springframework</groupId>
9.     <artifactId>spring-test</artifactId>
10.     <version>4.3.14.RELEASE</version>
11.     <scope>test</scope>
12.    </dependency>
13.     <dependency>
14.       <groupId>org.slf4j</groupId>
15.       <artifactId>slf4j-api</artifactId>
16.       <version>${slf4j.version}</version>
17.     </dependency>
18.   </dependencies>

排除依赖

有时候你引入的依赖中包含你不想要的依赖包,你想引入自己想要的,这时候就要用到排除依赖了,比如下图中 spring-boot-starter-web 自带了 logback 这个日志包,我想引入 log4j2 的,所以我先排除掉 logback 的依赖包,再引入想要的包就行了。

走进Java接口测试之构建工具Maven入门_spring_09

排除依赖代码结构:


1. <exclusions>
2.     <exclusion>
3.         <groupId>org.springframework.boot</groupId>
4.         <artifactId>spring-boot-starter-logging</artifactId>
5.     </exclusion>
6. </exclusions>

注意:声明 exclustion 的时候只需要 groupId 和 artifactId,而不需要 version 元素,这是因为只需要 groupId 和 artifactId 就能唯一定位依赖图中的某个依赖。

归类依赖

有时候我们引入的很多依赖包,他们都来自同一个项目的不同模块,所以他们的版本号都一样,这时候我们可以用属性来统一管理版本号。


1. <project>  
2.     <modelVersion>4.0.0</modelVersion>  
3.     <groupId>com.juven.mvnbook.account</groupId>  
4.     <artifactId>accout-email</artifactId>  
5.     <version>1.0.0-SNAPSHOT</version>  
6.     <properties>  
7.         <springframework.version>1.5.6</springframework.version>  
8.     </properties>  
9.     <dependencies>  
10.         <dependency>  
11.             <groupId>org.springframework</groupId>  
12.             <artifactId>spring-core</artifactId>  
13.             <version>${springframework.version}</version>  
14.         </dependency>   
15.         <dependency>  
16.             <groupId>org.springframework</groupId>  
17.             <artifactId>spring-beans</artifactId>  
18.             <version>${springframework.version}</version>  
19.         </dependency>         
20.     </dependencies>  
21. </project>  

如下所示:


1. </properties>
2.     这里定义你先要的版本
3. </properties>

通过以上来定义,然后在下面依赖使用 ${} 来引入你的属性。

了解仓库

概念

在 Maven 世界中,任何一个依赖、插件或者项目构建的输出,都可以称为构件。得益于坐标机制,任何 Maven 项目使用任何一个构件的方式都是完全相同的。在此基础上,Maven可以在某个位置统一存储所有 Maven 项目共享的构件,这个统一的位置就是仓库。实际的 Maven 项目将不再各自存储其依赖文件,它们只需要声明这些依赖的坐标,在需要的时候(例如,编译项目的时候需要将依赖加入到 classpath 中),Maven 会自动根据坐标找到仓库中的构件,并使用它们 为了实现重用,项目构建完毕后可生成的构件也可以安装或者部署到仓库中,供其他项目使用。

仓库的布局

任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是 Maven 的仓库布局方式。该路经与坐标对应关系为 groupId/artifactId/version/artifactId-version.packaging 举个例子,比如下面这个分页插件依赖如下:


1.  <dependency>
2.             <groupId>com.alibaba</groupId>
3.             <artifactId>fastjson</artifactId>
4.             <version>1.2.47</version>
5.  </dependency>

那它对应的仓库的路径就是这样:

走进Java接口测试之构建工具Maven入门_maven_10Maven 仓库是基于简单文件系统存储的,我们也理解其存储方式、因此,当遇到一些与仓库相关的问题时,可以很方便的查找相关文件,方便定位问题。

仓库的分类

走进Java接口测试之构建工具Maven入门_远程仓库_11

本地仓库

一般来说,在 Maven 项目目录下,没有诸如 lib/ 这样用来存放依赖文件的目录。当 Maven 在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。默认情况下,不管在 Window 还是 Linux 下,每个用户在自己用户目录下都有一个路径名为 .m2/repository/ 的仓库目录。如果你想自定义本地仓库目录地址。你可以编辑文件 ~/.m2/settings.xml,设置 localRepository 元素的值为想要的仓库地址,例如:


1. <settings>
2. <localRepository>D:\java\repository\</localRepository>
3. </settings>

复制代码这样,该用户的本地仓库地址就被设置成了 D:\java\repository\ 需要注意的是,默认情况下, ~/.m2/settings.xml文件不存在,用户需要从 Maven 安装目录复制 $M2_HOME/conf/settings.xml文件再进行编辑。

远程仓库-中央仓库

由于最原始的本地仓库是空的,Maven 必须知道至少一个可用的远程仓库,才能在执行 Maven 命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库,Maven 的安装文件自带了中央仓库的配置。中央仓库包含了这个世界上绝大多数流行的开源 Java 构件,以及源码、作者信息、SCM,信息、许可证信息等,每个月这里都会接受全世界 Java 程序员大概1亿次的访问,它对全世界 Java 开发者的贡献由此可见一斑。

远程仓库-私服

私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的 Maven 用户使用。当 Maven 需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为 Maven 的下载请求提供服务。因此,一些无法从外部仓库下载到的构件也能从本地上传到私服上供大家使用。私服的好处:

  • 节省自己的外网速度;
  • 加速 Maven 构建;
  • 部署第三方构建;
  • 提高稳定性,增强控制;
  • 降低中央仓库的负荷;

仓库服务搜索

这里介绍两个提供仓库服务搜索的地址:

  • Sonatype Nexus:https://repository.sonatype.org/
  • MVNrepository:http://mvnrepository.com/

maven test

maven-surefire-plugin

maven 本身并不是一个单元测试框架,maven 做的只是在构建执行到特定生命周期阶段的时候,通过插件来执行 Junit 或 TestNG 的测试用例。这插件是 maven-surefire-plugin—测试运行器。

默认情况下, maven-surefire-plugin 的 test 目标会自动执行测试源码路径(默认 src/test/java/)下所有符合一组命名模式的测试类如:


1. **/Test*.java  : 任何子目录下所有命名以Test开头的Java类
2. **/*Test.java  :任何子目录下所有命名以Test结尾的Java类
3. **/*TestCase.java :任何子目录下所有命名以Test结尾的java类

跳过测试


1. mvn package-DskipTests

第一种方式:POM中配置 maven-surefire-plugin 插件提供该属性(一般不推荐):


1. <plugin>
2.     <groupId>org.apache.maven.plugins</groupId>
3.     <artifactId>maven-surefire-plugin</artifactId>
4.     <version>2.5</version>
5.     <configuration>
6.        <skipTests>true</skipTests>
7.     </configuration>
8. </plugin>

第二种方式:跳过测试代码的编译:

    1. mvn  package-Dmaven.test.skip=true

    参数 maven.test.skip 同时控制了 maven-compiler-plugin 和 maven-surefire-plugin 两个插件的行为,测试代码编译跳过,测试运行跳过。

    maven.test.skip 的 POM 配置如下:


    1. <plugin>
    2.     <groupId>org.apache.maven.plugins</groupId>
    3.     <artifactId>maven-compiler-plugin</artifactId>
    4.     <version>2.5</version>
    5.     <configuration>
    6.        <skipTests>true</skipTests>
    7.     </configuration>
    8. </plugin>
    9.  <plugin>
    10.     <groupId>org.apache.maven.plugins</groupId>
    11.     <artifactId>maven-surefire-plugin</artifactId>
    12.     <version>2.5</version>
    13.     <configuration>
    14.        <skipTests>true</skipTests>
    15.     </configuration>
    16. </plugin>

    动态执行运行的测试用例

    maven-surefire-plugin 提供一个 test 参数让用户能够在命令行指定要运行的测试用例。

    • mvn test-Dtest=RandomGeneratorTest[测试用例的类名] ——效果是只有需要测试的测试类得到运行;
    • mvn test-Dtest=Random*Test ——运行所有类名以 Random 开头,Test 结尾的测试类;
    • mvn test-Dtest=test1test2test3 ——逗号指定多个测试用例,效用是告诉 maven 运行这些测试类;
    • mvn test-Dtest=test1test2test3Random*Test ——星号和逗号可结合使用;
    • mvn test-Dtest-DfailIfNoTests=false ——效用是告诉 maven-surefire-plugin 即使没有任何测试也不要报错,否侧maven-surefire-plugin找不到任何匹配的测试类,就会报错并导致构建失败;

    PS:上述命令行动态指定测试类的方法都应该只是临时使用,否则失去测试本身意义。

    包含与排除测试用例

    maven 提倡约定优于配置原则。

    maven 自动运行测试:


    1. <plugin>
    2. <groupId>org.apache.maven.plugins</groupId>
    3. <artifactId>maven-surefire-plugin</artifactId>
    4. <version>2.5</version>
    5. <configuration>
    6.     <includes>
    7.     <include>**/*Tests.java</include>
    8.      </includes>
    9. </configuration>
    10. </plugin

    通过 excludes 元素排除一些符合默认命名模式的测试类:


    1. <plugin>
    2.     <groupId>org.apache.maven.plugins</groupId>
    3.     <artifactId>maven-surefire-plugin</artifactId>
    4.     <version>2.5</version>
    5.     <configuration>
    6.         <excludes>
    7.         <exclude>**/*ServiceTest.java</exclude>
    8.         <exclude>**/*TempDaoTest.java</exclude>
    9.          </excludes>
    10.     </configuration>
    11. </plugin>

    有了excludes 配置后, maven-surefire-plugin 将不再自动运行它们。

    小结

    本文介绍了 maven 中常用的知识点,希望对大家有所帮助。