@Nested 让测试按“场景”组织成层次,但它的实例与生命周期、发现与选择、继承规则都有不直观的地方。这篇用真实的运行日志把它们逐项量出来。
[Shop 整个类]
构造 Shop #1
@BeforeEach Shop(外层)#1
测试 shopTest(外层)#1
@AfterEach Shop(外层)#1
构造 Shop #2
@BeforeEach Shop(外层)#2
测试 EmptyCart.total
@AfterEach Shop(外层)#2
构造 Shop #3
构造 WithCart #4(外层 Shop #3)
@BeforeEach Shop(外层)#3
@BeforeEach WithCart(第 2 层)#4
测试 cartTest(第 2 层)#4
@AfterEach WithCart(第 2 层)#4
@AfterEach Shop(外层)#3
构造 Shop #5
构造 WithCart #6(外层 Shop #5)
构造 WithItem #7(外层 WithCart #6,最外层 Shop #5)
@BeforeEach Shop(外层)#5
@BeforeEach WithCart(第 2 层)#6
@BeforeEach WithItem(第 3 层)#7
测试 itemTest1(第 3 层)#7
@AfterEach WithItem(第 3 层)#7
@AfterEach WithCart(第 2 层)#6
@AfterEach Shop(外层)#5
构造 Shop #8
构造 WithCart #9(外层 Shop #8)
构造 WithItem #10(外层 WithCart #9,最外层 Shop #8)
@BeforeEach Shop(外层)#8
@BeforeEach WithCart(第 2 层)#9
@BeforeEach WithItem(第 3 层)#10
测试 itemTest2(第 3 层)#10
@AfterEach WithItem(第 3 层)#10
@AfterEach WithCart(第 2 层)#9
@AfterEach Shop(外层)#8
→ 5 tests found | 0 tests skipped | 5 tests successful | 0 tests failed
汇总:共 5 个测试方法被执行;@BeforeEach 总共执行 10 次;构造函数总共被调用 10 次;外层 Shop 被构造 5 次 [tree 输出]
构造 Shop #1
@BeforeEach Shop(外层)#1
测试 shopTest(外层)#1
@AfterEach Shop(外层)#1
构造 Shop #2
@BeforeEach Shop(外层)#2
测试 EmptyCart.total
@AfterEach Shop(外层)#2
构造 Shop #3
构造 WithCart #4(外层 Shop #3)
@BeforeEach Shop(外层)#3
@BeforeEach WithCart(第 2 层)#4
测试 cartTest(第 2 层)#4
@AfterEach WithCart(第 2 层)#4
@AfterEach Shop(外层)#3
构造 Shop #5
构造 WithCart #6(外层 Shop #5)
构造 WithItem #7(外层 WithCart #6,最外层 Shop #5)
@BeforeEach Shop(外层)#5
@BeforeEach WithCart(第 2 层)#6
@BeforeEach WithItem(第 3 层)#7
测试 itemTest1(第 3 层)#7
@AfterEach WithItem(第 3 层)#7
@AfterEach WithCart(第 2 层)#6
@AfterEach Shop(外层)#5
构造 Shop #8
构造 WithCart #9(外层 Shop #8)
构造 WithItem #10(外层 WithCart #9,最外层 Shop #8)
@BeforeEach Shop(外层)#8
@BeforeEach WithCart(第 2 层)#9
@BeforeEach WithItem(第 3 层)#10
测试 itemTest2(第 3 层)#10
@AfterEach WithItem(第 3 层)#10
@AfterEach WithCart(第 2 层)#9
@AfterEach Shop(外层)#8
→ 5 tests found | 0 tests skipped | 5 tests successful | 0 tests failed
├─ JUnit Platform Suite ✔
├─ JUnit Jupiter ✔
│ └─ Shop ✔
│ ├─ shopTest() ✔
│ ├─ 空购物车 ✔
│ │ └─ 总价为 0 ✔
│ └─ WithCart ✔
│ ├─ cartTest() ✔
│ └─ WithItem ✔
│ ├─ itemTest1() ✔
│ └─ itemTest2() ✔
└─ JUnit Vintage ✔
想只运行嵌套类里的一部分,控制台启动器的几种选择方式的结果:
[--select-class Shop$WithCart$WithItem(直接选择最内层类)]
→ 0 tests found | 0 tests skipped | 0 tests successful | 0 tests failed
[--select-method Shop$WithCart#cartTest]
→ 0 tests found | 0 tests skipped | 0 tests successful | 0 tests failed
[--select-class Shop --include-classname '.*WithItem']
构造 Shop #1
@BeforeEach Shop(外层)#1
测试 shopTest(外层)#1
@AfterEach Shop(外层)#1
构造 Shop #2
@BeforeEach Shop(外层)#2
测试 EmptyCart.total
@AfterEach Shop(外层)#2
构造 Shop #3
构造 WithCart #4(外层 Shop #3)
@BeforeEach Shop(外层)#3
@BeforeEach WithCart(第 2 层)#4
测试 cartTest(第 2 层)#4
@AfterEach WithCart(第 2 层)#4
@AfterEach Shop(外层)#3
构造 Shop #5
构造 WithCart #6(外层 Shop #5)
构造 WithItem #7(外层 WithCart #6,最外层 Shop #5)
@BeforeEach Shop(外层)#5
@BeforeEach WithCart(第 2 层)#6
@BeforeEach WithItem(第 3 层)#7
测试 itemTest1(第 3 层)#7
@AfterEach WithItem(第 3 层)#7
@AfterEach WithCart(第 2 层)#6
@AfterEach Shop(外层)#5
构造 Shop #8
构造 WithCart #9(外层 Shop #8)
构造 WithItem #10(外层 WithCart #9,最外层 Shop #8)
@BeforeEach Shop(外层)#8
@BeforeEach WithCart(第 2 层)#9
@BeforeEach WithItem(第 3 层)#10
测试 itemTest2(第 3 层)#10
@AfterEach WithItem(第 3 层)#10
@AfterEach WithCart(第 2 层)#9
@AfterEach Shop(外层)#8
→ 5 tests found | 0 tests skipped | 5 tests successful | 0 tests failed
[--select-class Shop --include-tag nonexistent(对照:标签过滤)]
→ 0 tests found | 0 tests skipped | 0 tests successful | 0 tests failed [--select-class WithStatic]
测试 WithStatic.outerTest
测试 WithStatic.IsNested.nestedTest
→ 2 tests found | 0 tests skipped | 2 tests successful | 0 tests failed
[--scan-class-path 且匹配 WithStatic.*]
测试 WithStatic.NotNested.staticNestedTest(没有 @Nested 的静态嵌套类)
测试 WithStatic.outerTest
测试 WithStatic.IsNested.nestedTest
→ 3 tests found | 0 tests skipped | 3 tests successful | 0 tests failed [BeforeAllNested]
@BeforeAll(外层,static)
测试 outerTest
@BeforeAll(PER_CLASS 嵌套类里的实例方法)
测试 PerClassAll.t1 counter=1
测试 PerClassAll.t2 counter=2
@BeforeAll(嵌套类里的 static 方法)
测试 StaticAll.t1
测试 StaticAll.t2
@AfterAll(外层,static)
→ 5 tests found | 0 tests skipped | 5 tests successful | 0 tests failed [ExtOuter 全部]
测试 ExtOuter.plain
测试 NoExt.c(没有扩展)
扩展 beforeEach:WithExt.a()(第 1 次)
测试 WithExt.a
扩展 beforeEach:Deeper.b()(第 2 次)
测试 WithExt.Deeper.b(继承了外层的 @ExtendWith 与 @Tag)
→ 5 tests found | 1 tests skipped | 4 tests successful | 0 tests failed
[ExtOuter,--include-tag slow]
扩展 beforeEach:WithExt.a()(第 1 次)
测试 WithExt.a
扩展 beforeEach:Deeper.b()(第 2 次)
测试 WithExt.Deeper.b(继承了外层的 @ExtendWith 与 @Tag)
→ 2 tests found | 0 tests skipped | 2 tests successful | 0 tests failed
[DisabledOuter(外层 @Disabled,里面有 @Nested)]
→ 2 tests found | 2 tests skipped | 0 tests successful | 0 tests failed