5.15JUnit
一、 实验目的
1、掌握单元测试的基本理论和作用。
2、掌握典型单元测试工具 JUnit 的使用
二、 实验内容
实验题目
实验任务 1 :
请按以下操作步骤完成一个基本的 JUnit 测试实例。
以下是在IntelliJ IDEA环境下使用JUnit对Calculator类进行单元测试的详细步骤:
步骤1:创建Java项目
1. 打开IntelliJ IDEA → 新建项目 → 选择"Java" → 设置项目名称和路径 → 创建
步骤2:创建Calculator类
public class Calculator {
// 加法
public int add(int a, int b) {
return a + b;
}
// 减法
public int subtract(int a, int b) {
return a - b;
}
// 乘法
public int multiply(int a, int b) {
return a * b;
}
// 除法
public double divide(int a, int b) {
if(b == 0) throw new ArithmeticException("Cannot divide by zero");
return (double) a / b;
}
}
步骤3:添加JUnit依赖
1. 右键项目 → Open Module Settings
2. 选择"Libraries" → "+" → From Maven
3. 输入org.junit.jupiter:junit-jupiter-api:5.8.2 → 确定
4. 重复添加:
- org.junit.jupiter:junit-jupiter-engine:5.8.2
- org.junit.jupiter:junit-jupiter-params:5.8.2
步骤4:创建测试类
1. 在src/test/java目录右键 → New → Java Class → 命名为CalculatorTest
2. 添加测试类注解:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void testAdd() {
assertEquals(5, calculator.add(2, 3));
assertEquals(-1, calculator.add(2, -3));
}
@Test
void testSubtract() {
assertEquals(1, calculator.subtract(4, 3));
assertEquals(7, calculator.subtract(10, 3));
}
@Test
void testMultiply() {
assertEquals(6, calculator.multiply(2, 3));
assertEquals(-6, calculator.multiply(2, -3));
}
@Test
void testDivide() {
assertEquals(2.0, calculator.divide(6, 3));
assertEquals(3.333, calculator.divide(10, 3), 0.001);
}
@Test
void testDivideByZero() {
assertThrows(ArithmeticException.class, () -> calculator.divide(5, 0));
}
}
步骤5:运行测试
1. 点击测试类左侧的绿色箭头图标 ▶️
2. 选择"Run 'CalculatorTest'"
3. 查看结果:
- 绿色进度条:所有测试通过
- 红色进度条:存在失败的测试
步骤6:查看测试覆盖率(可选)
1. 右键测试类 → Run 'CalculatorTest' with Coverage
2. 查看覆盖率报告,确认是否覆盖所有代码分支
以下是使用JUnit 5进行参数化测试的详细操作步骤:
步骤1:创建参数化测试方法
在CalculatorTest类中添加以下代码:
java
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
class CalculatorTest {
// ... 其他已有代码 ...
// 参数化加法测试(使用CSV数据)
@ParameterizedTest(name = "[{index}] {0} + {1} = {2}") // 定义测试名称模板
@CsvSource({
"2, 3, 5", // 正常情况
"-5, 5, 0", // 负数加法
"0, 0, 0", // 零值测试
"2147483647, 1, -2147483648" // 整数溢出边界
})
void parameterizedAddTest(int a, int b, int expected) {
assertEquals(expected, calculator.add(a, b));
}
// 参数化除法测试(使用CSV带浮点)
@ParameterizedTest
@CsvSource({
"6, 3, 2.0",
"10, 3, 3.333",
"1, 2, 0.5"
})
void parameterizedDivideTest(int a, int b, double expected) {
assertEquals(expected, calculator.divide(a, b), 0.001);
}
// 参数化异常测试(使用ValueSource)
@ParameterizedTest
@ValueSource(ints = {0, -0, 100}) // 测试多个除数为零的情况
void parameterizedDivideByZeroTest(int divisor) {
assertThrows(ArithmeticException.class, () -> calculator.divide(10, divisor));
}
}
步骤3:数据源类型详解
1. @CsvSource
- 使用CSV格式直接嵌入测试数据
- 适用场景:需要多参数组合的测试
- 语法示例:
java
@CsvSource({
"参数1a, 参数2a, 预期结果a",
"参数1b, 参数2b, 预期结果b"
})
2. @ValueSource
- 提供单个参数的简单值
- 适用场景:单一参数测试
- 支持类型:基本类型、String、Class
java
@ValueSource(ints = {1, 2, 3})
3. @MethodSource
- 通过方法提供复杂参数
- 在测试类中添加静态方法:
java
static Stream<Arguments> provideMultiplyData() {
return Stream.of(
Arguments.of(2, 3, 6),
Arguments.of(-4, 5, -20),
Arguments.of(0, 100, 0)
);
}
@ParameterizedTest
@MethodSource("provideMultiplyData")
void parameterizedMultiplyTest(int a, int b, int expected) {
assertEquals(expected, calculator.multiply(a, b));
}
步骤4:运行参数化测试
1. 在测试类中:
- 点击类名旁的绿色箭头 ▶️ → 运行所有测试
- 点击单个参数化测试方法旁的箭头 → 运行单个测试
2. 查看结果时:
- 每个参数组合会显示为独立测试项
- 测试名称会显示参数值(通过name属性自定义)
步骤5:验证测试报告
执行后会显示详细结果:
✓ parameterizedAddTest(int, int, int)[1] 2 + 3 = 5
✓ parameterizedAddTest(int, int, int)[2] -5 + 5 = 0
✓ parameterizedAddTest(int, int, int)[3] 0 + 0 = 0
✓ parameterizedAddTest(int, int, int)[4] 2147483647 + 1 = -2147483648
参数化测试注意事项
1. 浮点数精度处理:
java
assertEquals(3.333, calculator.divide(10, 3), 0.001); // 第三个参数是允许的误差范围
2. 异常测试特殊处理:
java
@CsvSource({"5, 0", "10, 0"})
void testDivideByZero(int a, int b) {
assertThrows(ArithmeticException.class, () -> calculator.divide(a, b));
}
实验任务 2 :编写程序判断闰年,设计测试⽤例并⽤Junit进⾏测试。
实验任务3:编写程序判断非三角形,等腰三角形,等边三角形,直角三角形,钝角三角形,锐角三角形,设计测试用例并用JUnit进行测试。
三、 实验步骤及结果
实验任务1:JUnit 测试实例
创建Calculator类
添加依赖
创建测试类
运行测试结果
运行参数化测试
实验任务 2 :编写程序判断闰年,设计测试⽤例并⽤Junit进⾏测试。
闰年判断程序
JUnit测试类
测试用例设计
1. 普通闰年测试用例
2000年(能被400整除)
2020年(能被4整除但不能被100整除)
2400年(能被400整除)
2. 普通非闰年测试用例
1900年(能被100整除但不能被400整除)
2021年(不能被4整除)
2100年(能被100整除但不能被400整除)
3. 边界值测试用例
4年(第一个闰年)
1年(第一个非闰年)
4. 异常情况测试用例
0年
负数年份(-1, -4, -100, -400)
5. 参数化测试用例
使用CsvSource提供多组输入和预期输出
使用ValueSource提供多组非法输入
测试覆盖率
所有闰年判断逻辑分支
异常处理分支
所有边界情况
实验任务3:编写程序判断非三角形,等腰三角形,等边三角形,直角三角形,钝角三角形,锐角三角形,设计测试用例并用JUnit进行测试。
三角形判断程序
测试类
测试用例设计
无效输入测试:测试边长为0或负数的三角形
非三角形测试:测试不满足三角形两边之和大于第三边的组合
等边三角形测试:三边相等的三角形
等腰三角形测试:两边相等的三角形
直角三角形测试:满足勾股定理的三角形
钝角三角形测试:最大边的平方大于其他两边平方和的三角形
锐角三角形测试:最大边的平方小于其他两边平方和的三角形
边界值测试:测试接近边界值的三角形边长组合
四、 个人体会
测试除法运算和闰年判断的异常情况时,我学会了使用assertThrows来验证程序是否正确地抛出了预期的异常。这让我意识到良好的异常处理不仅是程序健壮性的保障,也是测试中需要重点验证的部分。