七、使用Nexus创建私服
目前有三种Maven仓库管理软件,来帮助建立私服:Apache基金会的Archiva、JFrog的Artifactory、Sonatype的Nexus。
1、Nexus的下载和安装
Nexus是典型的Java Web应用,最新版的是nexus3。
下载地址:https://www.sonatype.com/download-oss-sonatype
下载文件:nexus-3.4.0-02-win64
安装:运行nexus-3.4.0-02-win64\nexus-3.4.0-02\bin目录下的nexus.exe即可
2、Nexus的仓库与仓库组
Nexus的仓库概念有:代理仓库、宿主仓库、仓库组等。
仓库的类型:group(仓库组)、hosted(宿主)、proxy(代理)和virtual(虚拟)。
仓库的Policy属性,表示该仓库为发布(Release)版本仓库还是快照(Snapshot)版本仓库。
<1>、Nexus的内置仓库
【】maven-central:该仓库代理Maven中央仓库,其策略为Release
【】maven-releases:策略为Release的宿主类型仓库,用来部署组织内部的发布版本构件
【】maven-snapshots:策略为Snapshot的宿主类型仓库,用来部署组织内部的快照版本构件
【】maven-public:这是一个仓库组,将上述所有策略为Release的仓库聚合并通过一致的地址提供服务
<2>、Nexus仓库的分类
注:Maven可以直接从宿主仓库下载构件;也可以从代理仓库下载构件,代理仓库会间接地从远程仓库下载并缓存构件;仓库组没有实际内容(图中用虚线表示),它会转向其包含的宿主仓库或者代理仓库获得实际构件的内容。
3、Nexus的索引与构件搜索
Nexus通过维护仓库的索引来提供搜索功能,能在很大程度上方便Maven用户定位构件坐标。
Nexus关于Maven的搜索服务:
【】GAV搜索(GAV Search):允许用户通过设置GroupId、ArtifactId、Version等信息来针对性搜素;
【】类名搜索(Classname Search):允许用户搜索包含某个Java类的构件;
【】校验和搜索(Checksum Search):允许用户直接使用构件的校验和来搜索该构件。
4、配置Maven从Nexus下载构件
(1)、在当前项目POM中配置,只对当前Maven项目有效,示例如下:
<project>
...
<repositories>
<repository>
<id>nexus</id>
<name>Nexus</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>Nexus</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
...
</project>
(2)、通过一次配置,使得本机所有的Maven项目都使用自己的Maven私服
在settings.xml中使用Profile机制,示例如下:
<settings>
...
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<name>Nexus</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>Nexus</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
...
</settings>
上述配置中使用了一个id为nexus的profile,这个profile包含了相关仓库配置,同时配置中又使用activeProfile元素将nexus这个profile激活。这样当执行Maven构建时,激活的profile会将仓库配置应用到项目中去。
(3)、配置私服作为所有远程仓库的镜像
我们希望所有Maven下载请求都仅仅通过Nexus,以全面发挥私服的作用。这时可以使用Maven镜像配置,示例如下:
<settings>
...
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<name>central</name>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Nexus</name>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
...
</settings>
注意:上述仓库的url已经无关紧要,因为所有的请求都会通过镜像访问私服地址。
5、部署构件至Nexus
用户可以配置Maven自动部署构件至Nexus的宿主仓库,也可以通过界面手动上传构件。
(1)、使用Maven部署构件至Nexus(即之前提到的部署至远程仓库的方法)
通过在项目POM中配置,就可以实现部署(通过命令执行)。示例:
<project>
...
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Releases Repository</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshots Repository</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
...
</project>
另外,Nexus仓库对于匿名用户是只读的,为了能够部署构件,还需要在settings.xml中配置认证信息,如下所示:
<settings>
...
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>adamin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
...
</settings>
(2)、手动部署第三方构件至Nexus
6、Nexus的权限管理
(1)、Nexus的访问控制模型
Nexus是基于权限(Privilege)做访问控制的,服务器的每一个资源都有相应的权限来控制,用户执行特定的操作时必须拥有必要的权限。管理员必须以角色(Role)的方式将权限赋予Nexus用户。
用户可以被赋予一个或者多个角色,角色可以包含一个或者多个权限,角色还可以包含一个或者多个其他角色。
Nexus预定义了三个用户:
【】admin:该用户拥有对Nexus服务的完全控制,默认密码为admin123;
【】deployment:该用户能够访问Nexus,浏览仓库内容,搜索,并且上传部署构件,但是无法对Nexus进行任何配置,默认密码为deployment123;
【】anonymous:该用户对应了所有未登录的匿名用户,它们可以浏览仓库并进行搜索。
Nexus预定义的一些常用且重要的角色:
【】UI:Basic UI Privaleges:包含了访问Nexus界面必须的最基本的权限;
【】UI:Repository Browser:包含了浏览仓库页面所需要的权限;
【】UI:Search:包含了访问快速搜索栏及搜索页面所需要的权限;
【】Repo:All Repositories(Read):给予用户读取所有仓库的权限,没有仓库的浏览权限,不能再仓库页面上看到实际的仓库内容。
【】Repo:All Repositories(Full Control):给予用户完全控制所有仓库内容的权限。浏览、下载构件、部署构件、删除仓库等权限。
(2)、为项目分配独立的仓库
7、Nexus的调度任务
Nexus提供了一系列可配置的调度任务来方便用户管理系统。
Nexus3与之前的版本变化很大,有许多任务可控选择:Execute Script Task、Publish Maven Indexes等。
八、使用Maven进行测试
maven 通过maven-surefire-plugin与主流的单元测试框架JUnit3、JUnit4以及TestNG集成,并生成结果报告。
1、maven-surefire-plugin简介
maven-surefire-plugin插件被称为测试运行器(Test Runner),在默认情况下,maven-surefire-plugin的test目标会自动执行测试源码路径下所有符合命名模式的测试类,这些模式是:
【】**/Test*.java:任何子目录下所有命名以Test开头的Java类;
【】**/*Test.java:任何子目录下所有命名以Test结尾的Jave类;
【】**/*TestCase.java:任何子目录下所命名以TestCase结尾的Jave类;
注:Tests结尾的测试类不会得以自动执行
2、跳过测试
【】skipTests参数,告诉Maven跳过测试。例如:mvn package -D skipTests
【】maven.test.skip = true ,跳过测试代码编译,并且跳过测试执行。例如:mvn package -D maven.test.skip=true
注:在项目POM中,通过配置编译插件、测试插件的参数,可以控制跳过测试,例如:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
上述代码可以控制跳过测试编译、测试运行
3、动态指定要运行的测试用例
【】命令行test参数,可以控制运行哪个测试用例,例如:
mvn test -D test=RandomGeneratorTest // 运行测试用例类名为RandomGeneratorTest的用例;
mvn test -D test=Random*Test // 星号可以匹配零个或多个字符,这里是运行项目中所有类名以Random开头、Test结尾的测试类;
mvn test -D test=RandomGeneratorTest,AccountCaptchaServiceTest // 逗号分隔多个测试类,这里是运行RandomGeneratorTest、AccountCaptchaServiceTest两个测试类;
mvn test -D test=Random*Test, AccountCaptchaServiceTest // 运行所有以Random开头、Test结尾的测试类和AccountCaptchaServiceTest测试类。
注:test参数的值必须匹配一个或者多个测试类,如果maven-sure-plugin找不到任何匹配的测试类,就会报错并导致构建失败。例如:mvn test -D test
可以通过failIfNoTests=false参数来控制即使没有测试类,也不报错,例如:mvn test -D test -D failIfNoTests=false
【】包含与排除测试用例
maven可以通过以下在POM中的配置,控制maven自动运行配置的测试用例,例如:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>
上述配置,控制maven在测试时自动执行以Tests结尾的Java类。(注:两个星号**用来匹配任意路径,一个星号*匹配除路径风格外的0个或者多个字符)。
也可以通过配置,排除一些符合默认命名模式的测试类,例如:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<excludes>
<exclude>**/*ServiceTest.java</exclude>
<exclude>**/TempDaoTest.java</exclude>
</excludes>
</configuration>
</plugin>
上述配置,控制Maven排除所有以ServiceTest结尾的测试类,和一个名为TempDaoTest的测试类。
4、测试报告
(1)、基本的测试报告
默认情况下,maven-surefire-plugin会在项目的target/surefire-reports目录下生成两种格式的错误报告:
【】简单文本格式 (主要用于人为阅读)
【】与JUnit兼容的XML格式 (主要用于支持工具的解析,如Eclipse的JUnit插件等)
(2)、测试覆盖率报告
测试覆盖率是衡量项目代码质量的一个重要的参看指标。Cobertura是一个优秀的开源测试覆盖率统计工具,Maven与其集成提供测试覆盖率报告。
【】运行命令生成报告:mvn cobertura:cobertura
执行上述命令,会在项目目录target/site/cobertura/下生成报告,点击index.html文件,在浏览器中查看。
6、运行TestNG测试
TestNG是Java社区中除JUnit之外另一个流行的单元测试框架,TestNG在JUnit的基础上增加了很多特性。
在Maven中使用TestNG需要如下步骤:
【】先删除POM中的JUnit依赖,加入TestNG依赖;如下:
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.9</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
【】将JUnit的类库引用改成TestNG类库引用,例如:
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Unit test for simple App.
*/
public class AppTest
{
@BeforeClass
public void beforeClass() {
System.out.println("this is before class");
}
@Test
public void TestNgLearn() {
System.out.println("this is TestNG test case");
}
@AfterClass
public void afterClass() {
System.out.println("this is after class");
}
}
【】命令行输入:mvn test,执行测试。会在target\surefire-reports下生成测试报告。
注:TestNG允许用户使用testng.xml文件来配置想要运行的测试集合。例如,可以在项目根目录下创建一个testng.xml文件,配置只运行RandomGeneratorTest,如下:
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite1" verbose="1">
<test name="Regression1">
<classes>
<class name="com.juvenxu.mvnbook.account.captcha.RandomGeneratorTest"/>
</classes>
</test>
</suite>
然后,再配置maven-surefire-plugin使用该testng.xml,配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
7、重用测试代码
一些常用的测试工具类,或一些高质量的测试基类,如果需要重用的话,可以通过配置maven-jar-plugin将测试类打包,配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
注:maven-jar-plugin有两个目标,分别是jar和test-jar,前者通过Maven的内置绑定在default生命周期的package阶段运行,其行为就是对项目主代码进行打包,而后者并没有内置绑定,需要显示声明该目标来打包测试代码。test-jar的默认绑定生命周期阶段为package。
打包后的测试代码,可以像如下配置一样,添加到项目依赖中:
<dependency>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-captcha</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
注意:所有测试包构件都使用特殊的test-jar打包类型。