Files

82 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 代码审查报告
**文件:** `data\demo-pmd\src\com\demo\errorprone\extra\JUnit3RulesTest.java`
**语言:** java
**耗时:** 213.2s
**分析工具:** pmd
---
总计: 20 | 错误: 4 | 警告: 14 | 建议: 2
静态分析 · 15 个问题
- 🔴 `pmd:MethodNamingConventions` L12
实例方法名 'TearDown' 不符合 '[a-z][a-zA-Z0-9]*' 命名规范(L12)。
建议: 将 TearDown() 重命名为 tearDown(),使其以大写字母开头变为小写开头,并作为 JUnit3 的清理方法使用。
- 🔴 `pmd:SystemPrintln` L30
使用了 System.out/errL30)。
建议: 在正式代码中改用日志框架,例如 java.util.logging.Logger;也可为 Junit3Main 注入输出流以便测试。
- 🟡 `pmd:AtLeastOneConstructor` L9
每个类都应至少声明一个构造函数(L9)。
建议: 为 JUnitSpellingTest 添加显式构造函数,例如:public JUnitSpellingTest() { super(); }。若该类保留为 public 且供 JUnit3 使用,这个公共无参构造函数也满足 JUnit3 反射实例化的要求。
- 🟡 `pmd:TestClassWithoutTestCases` L9
类 'JUnitSpellingTest' 可能是测试类,但未包含任何测试用例(L9)。
建议: 在该类中新增一个以 test 开头、返回 void、公共无参的测试方法,并添加断言。例如:public void testExample() { assertTrue(true); }。如果该类用于存放公共测试工具,则不应继承 TestCase。
- 🟡 `pmd:JUnitSpelling` L10
你可能拼错了 JUnit 框架方法(setUp 或 tearDown)(L10)。
建议: 将 setup() 重命名为 setUp(),确保 JUnit3 将其识别为初始化方法。若方法体为空,请补充资源初始化逻辑;否则该声明无实际作用。
- 🟡 `pmd:JUnitSpelling` L12
你可能拼错了 JUnit 框架方法(setUp 或 tearDown)(L12)。
建议: 将 TearDown() 重命名为 tearDown(),使其被 JUnit3 识别为 teardown 生命周期方法。
- 🟡 `pmd:AtLeastOneConstructor` L17
每个类都应至少声明一个构造函数(L17)。
建议: 为 JUnitStaticSuiteTest 添加显式构造函数,例如:public JUnitStaticSuiteTest() { super(); }。注意测试类本身还应为 public,才能被 JUnit3 外部加载。
- 🟡 `pmd:TestClassWithoutTestCases` L17
类 'JUnitStaticSuiteTest' 可能是测试类,但未包含任何测试用例(L17)。
建议: 将 suite() 改为 public static junit.framework.Test suite(),并返回包含测试方法的 TestSuite,例如:return new TestSuite(JUnitStaticSuiteTest.class)。同时确保类中至少有一个 test 开头的方法。
- 🟡 `pmd:PublicMemberInNonPublicType` L18
在非 public 类型 JUnitStaticSuiteTest 中声明了 public 成员 'suite'L18)。
建议: JUnit3 要求 suite() 为 public,因此最佳修复是将类 JUnitStaticSuiteTest 移到独立文件并声明为 public class JUnitStaticSuiteTest;不要简单地把方法改为包私有,否则 JUnit 无法调用 suite 入口。
- 🟡 `pmd:JUnitStaticSuite` L18
你有一个 suite() 方法不是 public 且 staticJUnit 不会调用它来获取 TestSuite。这是你期望的吗?(L18)
建议: 将方法签名改为 public static junit.framework.Test suite(),并返回一个 TestSuite 实例,例如 return new TestSuite(JUnitStaticSuiteTest.class)。
- 🟡 `pmd:AtLeastOneConstructor` L23
每个类都应至少声明一个构造函数(L23)。
建议: 为 DetachedTest 添加显式构造函数,例如:public DetachedTest() { super(); }。同时建议将类改为 public 并放入独立文件。
- 🟡 `pmd:DetachedTestCase` L24
可能存在脱离测试套件的 JUnit 测试用例(L24)。
建议: 确保测试类为 public,以便 JUnit3 反射实例化;并将该类纳入某个 TestSuite。若迁移到 JUnit4/5,请使用 @Test 注解替代 test 前缀。
- 🟡 `pmd:PublicMemberInNonPublicType` L24
在非 public 类型 DetachedTest 中声明了 public 成员 'testSomething'L24)。
建议: 将 DetachedTest 改为 public class,并放入独立文件 DetachedTest.java。JUnit3 测试方法必须为 public,因此不要降低方法的可见性。
- 🟡 `pmd:UnitTestShouldIncludeAssert` L24
此单元测试应包含 assert() 或 fail()L24)。
建议: 在 testSomething() 中添加有意义的断言,例如 assertEquals(2, 1 + 1)。空测试永远通过,无法保护代码。
- 🟡 `pmd:UnitTestShouldUseTestAnnotation` L24
单元测试应使用 @Test 注解,否则不会运行。对于 JUnit Jupiter,还可使用 @RepeatedTest@TestFactory@TestTemplate@ParameterizedTest 注解(L24)。
建议: 若迁移到 JUnit4/5,移除 TestCase 继承,在方法上添加 @Test,并使用 org.junit.jupiter.api.Assertions 断言。当前 JUnit3 风格可通过修正类可见性继续运行,但推荐升级。
AI 审查 · 5 条建议
- 🔴 [AI] [bug] `non-public-junit3-test-class` L17
**JUnit3 测试类必须声明为 public 才能被发现**
JUnitStaticSuiteTest 和 DetachedTest 都是包私有类。JUnit3 运行器通过反射从外部包加载测试类,非 public 类会导致测试被跳过或抛出 IllegalAccessException。即使方法都声明为 public,类本身不可见也无法运行。
建议: 将两个测试类分别放入独立文件,并声明为 public class。移动后,默认的 public 无参构造即可满足 JUnit3 的基本实例化要求。
- 🔴 [AI] [bug] `multiple-top-level-classes` L28
**多个顶层类与 Java 文件结构冲突,main 入口不可用**
本文件中的 JUnitSpellingTest 是 public 类,因此文件必须命名为 JUnitSpellingTest.java。Junit3Main 无法在同一文件中声明为 public,导致其 main 方法不能作为程序入口;同时 JUnitStaticSuiteTest 和 DetachedTest 不是 publicJUnit3 无法从外部包加载它们。这种多顶层类布局会造成测试被静默忽略、程序无法启动。
建议: 将 Junit3Main 移到独立文件并声明为 public class Junit3Main;将 JUnitStaticSuiteTest、DetachedTest 也分别移到独立文件并声明为 public class。如果使用 JUnit5,则无需继承 TestCase,文件结构更简单。
- 🟡 [AI] [design] `empty-test-suite` L24
**测试类没有真实断言,测试套件可能空转**
JUnitSpellingTest 没有任何 test 方法;JUnitStaticSuiteTest 只有无效的 suite() 且没有测试方法;DetachedTest.testSomething() 没有断言。这些测试即使全部通过也不能验证任何行为,容易让 CI 产生假阳性。
建议: 为每个测试类添加带断言的 test 方法;若某个类只是测试基类,则不应继承 TestCase。使用 JUnit5 的 @Test 和 Assertions 能更容易写出有效测试。
- 🔵 [AI] [design] `legacy-junit3` L6
**使用已停止维护的 JUnit3 测试框架**
代码通过继承 junit.framework.TestCase 和 test 前缀编写测试,属于 JUnit3 风格。JUnit3 不支持现代测试特性(如异常断言、参数化测试、嵌套测试),不利于长期维护。
建议: 迁移到 JUnit4 或 JUnit5:移除 extends TestCase,测试方法加 @Test 注解,使用 org.junit.jupiter.api.Assertions 断言。迁移前至少先修复类可见性和空测试问题。
- 🔵 [AI] [style] `abbreviation-in-name` L28
**类名 Junit3Main 中 JUnit 缩写大小写不规范**
JUnit 是一个品牌名,通常缩写应保持全部大写。Junit3Main 看起来像类名大小写不规范,建议改为 JUnit3Main,并同步更新文件名和所有引用。
建议: 将 Junit3Main 重命名为 JUnit3Main,更新文件名为 JUnit3Main.java,并修改 main 方法中 Logger.getLogger(Junit3Main.class.getName()) 的类名引用。