[英]IntelliJ Idea - JUnit5 - Getting an error -> [ '@Suite' not applicable to method ]
[英]JUnit5: Before and After Suite method invocation
我花了幾天時間尋找解決方案,所以我知道所有基本答案
我看過文檔,我知道,@BeforeClass/@AfterClass 被@BeforeAll/@AfterAll 替換了,@RunWith 不再存在; 被@ExtendWith取代我已經閱讀了stackoverflow上的所有主題(刪除鏈接,因為stackoverflow假裝它是垃圾郵件:(
我曾經在套件中運行一些 JUnit4 測試。 每個 Suite class Suite1.class、Suite2.class都有幾個@Test方法, @BeforeClass/@AfterClass在所有測試方法之前/之后運行。
@RunWith(StopOnFailureSuite.class)
@Suite.SuiteClasses({
Test1.class,
Test2.class
})
public class TSuite_20 {
private static final byte SUITE_NUMBER = 20;
@BeforeClass
public static void setUpClass() {
//some logic for suite setup
}
@AfterClass
public static void tearDownClass() {
//some logic for teardown
}
}
因為我想使用 @ParameterizedTests,所以我需要遷移到 JUnit5。 突然我意識到,完全相同的行為,曾經在 JUnit4 中是不可能實現的。 [運行一些自定義設置代碼; 運行多個測試類,其中可能包含多個@Test 方法; 運行一些自定義的拆卸代碼];
有沒有人知道(最好有例子)用 JUnit 5 制作它的方法?
選項 1此代碼永遠不會執行BeforeAfterSuite#beforeAll
和BeforeAfterSuite#afterAll
@ExtendWith(BeforeAfterSuite.class)
@Suite
@SelectClasses({
Test1.class,
Test2.class
})
public class TSuite_20 {
public static final byte SUITE_NUMBER = 20;
}
public class BeforeAfterSuite implements BeforeAllCallback, AfterAllCallback
/*,TestInstancePreConstructCallback, BeforeTestExecutionCallback,
AfterTestExecutionCallback, ExtensionContext.Store.CloseableResource*/ {
private static boolean started = false;
@Override
public void beforeAll(ExtensionContext context) {
if (!started) {
started = true;
//before stuff
}
}
@Override
public void afterAll(ExtensionContext context) throws Exception {
//after all;
}
}
選項 2我只是好奇,如果我將測試方法放入其中,JUnit 將如何處理套件 class...此代碼將在 TSuite_20#test 之前和之后執行一次BeforeAfterSuite#beforeAll
和BeforeAfterSuite#afterAll
一次
@ExtendWith(BeforeAfterSuite.class)
@Suite
@SelectClasses({
Test1.class,
Test2.class
})
public class TSuite_20 {
public static final byte SUITE_NUMBER = 20;
@Test
public void test() {
}
}
選項 3我們還可以為每個測試 class 應用@ExtendWith(BeforeAfterSuite.class)
,這將導致每個測試 class 的BeforeAfterSuite#beforeAll
和BeforeAfterSuite#afterAll
。(在此示例中 - 2 次)。
@ExtendWith(BeforeAfterSuite.class)
public class Test1 {
@Test
public void test11() {
}
@Test
public void test12() {
}
}
@ExtendWith(BeforeAfterSuite.class)
public class Test2 {
@Test
public void test21() {
}
@Test
public void test22() {
}
}
選項 4我也試一試
@ExtendWith()
和@BeforeAll + @AfterAll
; (正如預期的那樣,什么也沒發生)`@ExtendWith()
和@BeforeAll + @Test + @AfterAll
; (正如預期的那樣,針對特定套件類單獨執行 BeforeAll/AfterAll)`選項 5聽眾是我實現預期行為的最后希望。 我已經為 LauncherSessionListener 創建了自己的 impl,只是因為我認為它可以讓我在測試開始之前准確地執行 smth。
public class BeforeAfterSuiteLauncher implements LauncherSessionListener {
private static boolean started = false;
@Override
public void launcherSessionOpened(LauncherSession session) {
if (!started) {
started = true;
//before all
}
}
@Override
public void launcherSessionClosed(LauncherSession session) {
//after all
}
}
我還添加了一些默認的 impl CompositeLauncherSessionListener
包結構截圖顯示 Java SPI 配置: LauncherSessionListener
對於 TestExecutionListener,我添加了兩個默認實現,只是為了捕獲至少一個 Listener:
org.junit.platform.launcher.listeners.LoggingListener
org.junit.platform.launcher.listeners.SummaryGeneratingListener
和一個習俗
public class BeforeAfterExecutionListener implements TestExecutionListener {
@Override
public void testPlanExecutionStarted(TestPlan testPlan) {
//before all
}
@Override
public void testPlanExecutionFinished(TestPlan testPlan) {
//after all
}
}
包結構截圖顯示 Java SPI 配置: TestExecutionListener
並且只觸發了 SummaryGeneratingListener!
我究竟做錯了什么? 為什么我的 BeforeAfterExecutionListener impl 沒有被加載和觸發?
PS 以上代碼均在Intellij Idea 2021.1.3 旗艦版下執行
java version "1.8.0_341"
Java(TM) SE Runtime Environment (build 1.8.0_341-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)
這是 intelliJs 命令:
C:\Tools\jdk\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:61280,suspend=y,server=n -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:C:\Users\userName\AppData\Local\JetBrains\IntelliJIdea2021.1\groovyHotSwap\gragent.jar -javaagent:C:\Users\userName\AppData\Local\JetBrains\IntelliJIdea2021.1\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath C:\Users\userName\AppData\Local\Temp\classpath1705687115.jar com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 com.testdirectly.application.testcase.TSuite_20
我的 gradle 依賴項
dependencies {
//JUnit platform
// to group tests by package, by class name, by class name pattern, etc (use @Suite, @SelectClasses) :junit-platform-suite-api:1.9.2
// and to filter/discover and run them (SuiteLauncher, SuiteTestEngine, SuiteTestDescriptor) :junit-suite-engine:1.9.2
testImplementation "org.junit.platform:junit-platform-suite:1.9.2"
//Launcher, engine discovery
testImplementation "org.junit.platform:junit-platform-launcher:1.9.2"//to run tests
//JUnit Jupiter
//to use assertions and so on
testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.2"
//to use @ParameterizedTest
testImplementation "org.junit.jupiter:junit-jupiter-params:5.9.2"
//Jupiter engine to run junit5 tests (JupiterTestEngine, Extensions, etc)
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.2"
}
如果您稍微調整選項 5,它就會起作用(見下文)。
選項 1 和 2 不起作用,因為@ExtendWith
是 Jupiter 擴展機制,而@Suite
觸發它自己的引擎。 測試引擎不結合 JUnit 平台。
選項 4 也是如此,因為@BeforeAll
和@AfterAll
是 Jupiter 注釋。
首先,我建議使用TestExecutionListener
而不是LauncherSessionListener
,因為后者仍處於實驗階段。
因此我們有
package my.project.suites;
import org.junit.platform.launcher.*;
public class BeforeAfterSuiteListener implements TestExecutionListener {
@Override
public void testPlanExecutionStarted(TestPlan testPlan) {
System.out.println("before all");
}
@Override
public void testPlanExecutionFinished(TestPlan testPlan) {
System.out.println("after all");
}
}
現在缺少的是您必須全局注冊BeforeAfterSuiteListener
。 在基於類路徑的 Java 中,您通過資源文件META-INF/services/org.junit.platform.launcher.TestExecutionListener
:
my.project.suites.BeforeAfterSuiteListener
現在before all
和after all
應該在每次測試運行時恰好在您的 output 中顯示一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.