下面是各个章节使用的代码和命令说明。
第一章没有相关代码,有两个实用的命令构造测试文件。
dd if=/dev/zero of=ouput.txt bs=1M count=10
echo hello > test.txt
truncate -s 1024 test.txt
fsutil file createnew <输出的文件名> <文件大小(字节)>
常用的静态代码分析工具,示例包名和代码路径如下:
选择这几个工具的原因是主流项目基本上都在使用,如果条件允许可以使用 SonarQube + 社区的一些插件。由于示例项目为多模块项目方便演示更多内容,进入模块执行相应命令。
书中示例的几个 FindBugs 是我们团队上最容易出现的几个问题,但是 FindBugs 不同的版本下无法全部找出来(让我也非常迷惑)。
使用 Maven 插件安装 Hooks 的代码片段如下:
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<gitConfig>
<!-- 指定代码库中的 Hook 脚本位置,插件会帮助安装到 gitconfig 中 -->
<core.hooksPath>hooks-directory/</core.hooksPath>
<custom.configuration>true</custom.configuration>
</gitConfig>
</configuration>
<executions>
<execution>
<goals>
<!-- Maven 生命周期配置 -->
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Gradle 安装 Hooks
task installGitHooks(type: Copy) {
from new File(rootProject.rootDir, 'pre-commit')
into {
new File(rootProject.rootDir, '.git/hooks')
}
fileMode 0755
}
build.dependsOn installGitHooks
pre-commit 的一个示例
#!/bin/sh
# 需要运行的命令
mvn clean install
# 获取上一个命令的执行结果
RESULT=$?
# 使用上一个命令的执行结果来退出,这样做可以选择是否中断构建
exit $RESULT
测试目录下的文件说明:
- HelloWorldTest.java 第一个测试示例
- AssertPractiseTest.java 断言示例
- CurrentSystemTimeMatcher.java 自定义的 Matcher
- CustomMatcherTest.java 自定义的 Matcher 的测试
- PreparationMethodsPractiseTest.java 测试准备示例
- UseCaseDesignPractiseTest.java 单元测试用例设计
- ParameterizedPractiseTest.java 参数化测试用例设计
- ExceptionPractiseTest.java 异常测试
- NameRuleTest.java NameRule 的使用
- GlobalTimeoutPractiseTest.java 计时器的使用
- SuitesPractiseTest.java 嵌套测试
- IPv4ServiceTest.java 补充示例
- StringUtilTest.java 补充示例
手写一个断言库的代码为 JavaScript:
function assertEquals(description, expected, actual) {
if (expected !== actual) {
throw new Error("ComparisonFailure, Expected:" + expected + ",Actual:" + actual);
} else {
console.log(description + " : %c pass", "color:#0f0;")
}
}
function should_return_hello_world(){
assertEquals("test hello world", "Hello", "Hello");
}
- HelloWorldTest.java Junit 5 基本示例
- ExceptionPractiseTest.java 更方便的异常处理
- NestedTest.java 嵌套测试示例
测试目录下的文件说明:
- UserServiceTest.java 包含了普通的 mock 方法使用、BDD 风格演示、Lambda 方式的验证、获取模拟信息
- UserServiceAnnotationTest.java 使用注解的方式注入模拟对象
- ArgumentMatchersExampleTest.java 参数匹配器的各种例子
- UserServiceAnnotationTest.java 模拟静态方法
- ConstructorTest.java 模拟构造方法
- PrivateTest.java 模拟私有方法
- WhiteBoxTest.java 反射工具类
测试目录下的文件说明:
- service/UserServiceTest.java 只有必要 Bean 的 Spring 测试
- ApplicationTest.java Spring Boot 测试示例
- ApplicationWithJdbcTemplateTest.java 使用 JdbcTemplate 的 Spring Boot 测试示例
- service/UserServiceMockBeanTest.java 使用 Bean 模拟的测试
- ApplicationTestOnlyController.java Spring Boot 切片测试 WebMvcTest 示例
- TestForMapper.java Mybatis Mapper 专用测试
- TestForJson.java JSON 专用测试
- controller/UserControllerTest.java 使用 MockMvc 的 API 测试
- ReflectionTestUtilsTest.java 反射工具箱
- PropertyTest.java Property 注入
- OutputCaptureTest.java 控制台输出的文本捕获
- embedded/SpringBaseTest 内嵌工具 Redis 的配置
在这一章中,我们使用了 MariaDB4j 来实现数据库基础设施的自动化管理,该库依赖 libssl,可能有如下报错:
Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
参考解决方法:
brew install rbenv/tap/openssl@1.0
ln -sfn /usr/local/Cellar/openssl@1.0/1.0.2t /usr/local/opt/openssl
测试目录下的文件说明:
- config/MariaDB4jSpringConfiguration.java MariaDB4j的配置文件
- config/ResetDbListener.java 重置和恢复数据库的方法
- config/ResetDbService.java 重置和恢复的服务
- TestBase.java REST Assured 的主要配置方法
- controller/UserControllerTest.java REST Assured 基本使用
- FileTest.java 文件处理的示例
无法在一个项目中实现不同的鉴权例子,只贴了示例代码:
使用 Header
given().header("Authorization", "Basic YWRtaW46MTIzNDU2")
使用 auth 方法
given().auth().basic("admin", "123456")
使用全局拦截器
RestAssured.authentication = basic("admin", "123456");
token 鉴权设置示意:
@Autowired
private AuthorizeService authorizeService;
private String token;
...
@BeforeEach
public void setup() {
// 调用父类的初始化方法
super.setup();
// 设置一个默认测试用户
...
this.token = authorizeService.login(User user);
}
@Test
public void test() {
given().contentType("application/json").header("Authorization","Bearer " + token);
...
}
Cookie 鉴权设置示意:
// 1. 登录并留存 Cookies
Map<String, String> cookies = given()
.contentType("application/json")
.body(Maps.of("email", "test@email.com", "password", "123456"))
.when().post("/authorizes")
.then().statusCode(201).extract().cookies();
// 2. 使用 cookies 获取用户个人信息
given()
.contentType("application/json")
.cookies(cookies)
.when().post("/authorizes/me")
.then().statusCode(200);
SessionFilter 示意:
SessionFilter sessionFilter = new SessionFilter();
given()
.contentType("application/json")
.filter(sessionFilter)
.body(Maps.of("email", "test@email.com", "password", "123456"))
.when().post("/authorizes")
.then().statusCode(201);
WireMock 的几个命令:
启动
java -jar wiremock-jre8-standalone-2.28.0.jar
写入数据
curl -X POST \
--data '{ "request": { "url": "/info.0.json", "method": "GET" }, "response": { "status": 200, "body": "{\"hello\":\"world\"}" }}' \
http://localhost:8080/__admin/mappings/new
验证
curl http://localhost:8080/info.0.json
生成 JMH 工程
mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=test \
-Dversion=1.0
进入 test 目录后执行
mvn clean install
运行测试
java -jar target/benchmarks.jar
MyBenchmark 文件
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 3)
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
@Threads(8)
@Fork(1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class MyBenchmark {
@Benchmark
public void test_simple_string() {
String s = "Hello world!";
for (int i = 0; i < 10; i++) {
s += s;
}
}
@Benchmark
public void test_string_builder() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(i);
}
}
}
使用 Jar 启动 JMeter
java -jar bin/ApacheJMeter.jar
测试 API 的命令
curl http://localhost:8080/api/hello
JMeter
./bin/jmeter.sh -n -t hello.jmx -l output.jtl
使用 Maven 执行 JMeter
mvn verify
源码包目录下关键文件说明
- SynchronizationCount.java 全局变量的原子性问题
- ConcurrencyExample.java 使用 ArrayList 的一个并发问题
- DeadLockExample.java 死锁示例
- MemoryLeakExample.java 内存泄露的例子
测试目录下关键文件说明
- DeadLockTest.java 死锁测试
- RunConcurrentlyTest.java 浸泡测试
测试目录文件说明
- AvatarServiceTest.java 组合生成文本和生成图像的组合类
- AvatarTextUtilTest.java 生成文本工具类
- ImageUtilTest.java 生成图像类
下载 Jenkins 文件
wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war
启动
java -jar jenkins.war --httpPort=8080
示例流水线代码
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
流水线配置文件说明
- Jenkinsfile.groovy 流水线基本示例
- Jenkinsfile_parallel.groovy 并行流水线
- Jenkinsfile_test_report.groovy 测试报告
用来创建测试覆盖率的项目在另外一个仓库。
Arthas 的使用
wget https://arthas.aliyun.com/arthas-boot.jara
java -jar arthas-boot.jar
文件说明
- HelloServiceTest.java 使用打印出来的日志文本进行测试
测试目录文件说明
- BatchJobTest.java
- BatchStepTest.java
源码目录文件说明
- BasicVersion.java 基本版本
- InterfaceVersion.java 接口版本
- ProviderVersion.java ProviderVersion 的版本
Spring 体系中的特性开关 主要使用 Spring 的列表注入多个 Bean 实现以及使用 Togglz 来实现特性开关
source-analysis 该模块用于通过命令来启动 JUnit 从而找到测试的入口
source-analysis2 该模块用于放置分析源码时的几个测试类
helloworld 该模块用于生成应用项目,被用于验证 Java Agent
helloworld Java Agent 示例