基于JUnit 5的三角形分类算法测试用例设计与实现
核心判定逻辑重构
在处理几何图形分类任务时,传统的多重条件分支往往伴随较高的代码冗余度。通过对输入的三条边长进行升序排列,可以大幅简化合法性校验与角度类型判定的流程。排序完成后,最短边固定于索引0,最长边固定于索引2,此时仅需验证两短边之和是否大于最长边即可完成三角形不等式检查。角度分类则依赖余弦定理的代数推论:对比两短边平方和与最长边平方的数值关系,即可精准划分直角、钝角与锐角类型。为防止边长较大时发生整型乘法溢出,平方运算阶段统一采用长整型进行中间值存储。
package com.example.geometry;
import java.util.Arrays;
public class ShapeEvaluator {
public static String classify(int edgeA, int edgeB, int edgeC) {
int[] sides = {edgeA, edgeB, edgeC};
Arrays.sort(sides);
if (sides[0] <= 0) {
return "非法图形";
}
if (sides[0] + sides[1] <= sides[2]) {
return "非法图形";
}
if (sides[0] == sides[2]) {
return "等边三角形";
}
if (sides[0] == sides[1] || sides[1] == sides[2]) {
return "等腰三角形";
}
long shortSqSum = (long) sides[0] * sides[0] + (long) sides[1] * sides[1];
long longSq = (long) sides[2] * sides[2];
if (shortSqSum == longSq) {
return "直角三角形";
}
if (shortSqSum < longSq) {
return "钝角三角形";
}
return "锐角三角形";
}
}
测试用例设计策略
针对该分类器,测试方案主要围绕等价类划分与边界值分析展开。输入域被明确切割为有效几何集合与非法参数集合。非法集合涵盖零值、负数以及违反三角不等式的临界组合。有效集合则进一步细分为等边、等腰、直角、钝角与锐角五个独立子集。在JUnit 5框架下,采用参数化测试机制替代冗余的断言语句,通过数据驱动模式提升测试脚本的可读性与维护效率。每组用例均覆盖典型数值与边界场景,确保核心分支获得充分覆盖。
package com.example.geometry;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ShapeEvaluatorTest {
@Test
@DisplayName("校验非法参数与不构成三角形的边界条件")
void validateInvalidInputs() {
assertEquals("非法图形", ShapeEvaluator.classify(0, 4, 5));
assertEquals("非法图形", ShapeEvaluator.classify(-2, 3, 4));
assertEquals("非法图形", ShapeEvaluator.classify(2, 3, 5));
assertEquals("非法图形", ShapeEvaluator.classify(1, 1, 3));
}
@ParameterizedTest
@CsvSource({
"7, 7, 7, 等边三角形",
"12, 12, 12, 等边三角形"
})
@DisplayName("等边三角形数据驱动验证")
void checkEquilateral(int a, int b, int c, String expected) {
assertEquals(expected, ShapeEvaluator.classify(a, b, c));
}
@ParameterizedTest
@CsvSource({
"4, 4, 6, 等腰三角形",
"8, 5, 5, 等腰三角形",
"9, 9, 12, 等腰三角形"
})
@DisplayName("等腰三角形数据驱动验证")
void checkIsosceles(int a, int b, int c, String expected) {
assertEquals(expected, ShapeEvaluator.classify(a, b, c));
}
@ParameterizedTest
@CsvSource({
"6, 8, 10, 直角三角形",
"9, 12, 15, 直角三角形",
"5, 12, 13, 直角三角形"
})
@DisplayName("直角三角形数据驱动验证")
void checkRightAngled(int a, int b, int c, String expected) {
assertEquals(expected, ShapeEvaluator.classify(a, b, c));
}
@ParameterizedTest
@CsvSource({
"3, 4, 6, 钝角三角形",
"4, 5, 8, 钝角三角形",
"7, 8, 12, 钝角三角形"
})
@DisplayName("钝角三角形数据驱动验证")
void checkObtuse(int a, int b, int c, String expected) {
assertEquals(expected, ShapeEvaluator.classify(a, b, c));
}
@ParameterizedTest
@CsvSource({
"4, 5, 6, 锐角三角形",
"6, 7, 8, 锐角三角形",
"8, 9, 10, 锐角三角形"
})
@DisplayName("锐角三角形数据驱动验证")
void checkAcute(int a, int b, int c, String expected) {
assertEquals(expected, ShapeEvaluator.classify(a, b, c));
}
}
测试执行与验证要点
参数化测试通过CSV格式注入多维数据集,JUnit引擎会自动迭代执行并生成独立的子测试报告。对于非法输入场景,使用标准单元测试方法集中校验异常边界。在实际运行过程中,测试框架会针对每组边长组合调用分类接口,并将实际返回值与预设期望进行严格比对。若平方和比较逻辑或排序预处理存在缺陷,参数化用例将迅速定位失败的数据节点,从而有效保障几何判定算法的鲁棒性。