Testlivssyklus og rekkefølge
Kontroller kjøringsrekkefølgen for tester, og håndter oppsett og nedbryting av tester ved hjelp av avanserte livssyklusannotasjoner.
Testlivssyklus og rekkefølge er en gratis leksjon i Testing i praksis: JUnit, Mockito og integrasjonstester på CoddyKit. Dette er leksjon 1 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Testing i praksis: JUnit, Mockito og integrasjonstester, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Testing i praksis: JUnit, Mockito og integrasjonstester inneholder totalt 4 leksjoner.
Introduksjon til JUnit-testlivssyklusen
Velkommen! I denne leksjonen skal du utforske avanserte JUnit 5-funksjoner for å styre hvordan testene kjøres. Det er viktig å forstå testlivssyklusen for å håndtere ressurser og sikre riktig oppsett og opprydding av tester.
Livssyklusen definerer rekkefølgen på handlingene JUnit utfører før og etter testmetodene og klassene dine.
Oppsett på klassenivå: @BeforeAll
Noen ganger trenger du å utføre oppsetthandlinger bare én gang for alle testene i en bestemt testklasse. Annotasjonen @BeforeAll markerer en metode som skal kjøre før alle testmetodene i klassen.
Som standard må @BeforeAll-metoder være static. Snart skal du se hvordan dette kan endres!
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class BeforeAllDemo {
private static StringBuilder log = new StringBuilder();
@BeforeAll
static void setupOnce() {
log.append("-> @BeforeAll: Setup done once.\n");
System.out.println("Setup for all tests.");
}
@Test
void testA() {
log.append(" -> @Test: Running testA.\n");
System.out.println(" Running testA.");
assertTrue(true);
}
@Test
void testB() {
log.append(" -> @Test: Running testB.\n");
System.out.println(" Running testB.");
assertTrue(true);
}
// The log output would typically be verified in @AfterAll or debugger.
}Opprydding på klassenivå: @AfterAll
Tilsvarende kan det hende du må rydde opp i ressurser én gang etter at alle testene i en klasse er fullført. Annotasjonen @AfterAll markerer en metode som skal kjøre etter alle testmetodene i klassen.
I likhet med @BeforeAll må den som standard være static.
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class AfterAllDemo {
private static StringBuilder log = new StringBuilder();
@BeforeAll
static void setup() {
log.append("-> @BeforeAll: Setup for AfterAllDemo.\n");
}
@Test
void testOne() {
log.append(" -> @Test: Running testOne.\n");
assertTrue(true);
}
@Test
void testTwo() {
log.append(" -> @Test: Running testTwo.\n");
assertTrue(true);
}
@AfterAll
static void teardown() {
log.append("-> @AfterAll: Teardown for AfterAllDemo.\n");
System.out.println("--- Execution Log ---");
System.out.println(log.toString()); // See the full order
System.out.println("--- End Log ---");
}
}@TestInstance: PER_CLASS-livssyklus
Som standard oppretter JUnit en ny instans av testklassen for hver testmetode (Lifecycle.PER_METHOD). Dette sikrer at testene er isolerte.
Hvis du trenger at @BeforeAll- og @AfterAll-metoder skal være ikke-statiske, eller hvis du vil dele tilstand mellom alle testene i en klasse, kan du endre testinstansens livssyklus til Lifecycle.PER_CLASS.
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import static org.junit.jupiter.api.Assertions.assertEquals;
@TestInstance(Lifecycle.PER_CLASS) // Allows non-static @BeforeAll/@AfterAll
public class PerClassLifecycleDemo {
private int counter = 0; // Instance variable, shared across tests
@BeforeAll // No longer needs to be static!
void setupPerClass() {
counter = 10;
System.out.println("-> @BeforeAll (PER_CLASS). Counter: " + counter);
}
@Test
void testIncrementOne() {
counter++;
System.out.println(" -> @Test 1. Counter: " + counter);
assertEquals(11, counter); // Shared state is modified
}
@Test
void testIncrementTwo() {
counter++;
System.out.println(" -> @Test 2. Counter: " + counter);
assertEquals(12, counter); // Counter continues from previous test
}
@AfterAll // No longer needs to be static!
void teardownPerClass() {
System.out.println("-> @AfterAll (PER_CLASS). Final Counter: " + counter);
}
}Når bør testrekkefølge brukes?
Ideelt sett bør JUnit-tester være uavhengige og kjøre riktig i hvilken som helst rekkefølge. Hvis du er avhengig av en bestemt rekkefølge, kan testene bli sårbare og vanskeligere å vedlikeholde.
Det finnes likevel enkelte situasjoner der en eksplisitt rekkefølge kan være nyttig:
- Testing av en kompleks arbeidsflyt med tydelige, sekvensielle trinn.
- Optimalisering av ytelsen ved å gruppere raske tester eller tester med felles, kostbart oppsett.
- Arbeid med eldre systemer som krever en bestemt rekkefølge på samhandlingene.
@TestMethodOrder-annotasjonen
For å definere en utførelsesrekkefølge for testmetoder i en klasse bruker du annotasjonen @TestMethodOrder på klassenivå. Den tar en implementasjon av MethodOrderer som argument.
JUnit 5 har flere innebygde strategier:
Alphanumeric.class: Sorterer alfabetisk etter metodenavn.OrderAnnotation.class: Bruker@Order-annotasjonen.Random.class: Gjør rekkefølgen tilfeldig.DisplayName.class: Sorterer etter visningsnavnene til metodene.
Alfanumerisk metoderekkefølge
La oss se MethodOrderer.Alphanumeric.class i praksis. JUnit sorterer ganske enkelt testmetodene etter navn i alfabetisk rekkefølge.
Dette er en enkel måte å få en forutsigbar rekkefølge på hvis metodenavnene dine naturlig følger en sekvens.
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.MethodOrderer.Alphanumeric;
import static org.junit.jupiter.api.Assertions.assertTrue;
@TestMethodOrder(Alphanumeric.class) // Tests run A, B, C
public class AlphanumericOrderDemo {
@Test
void testA_First() {
System.out.println("-> Running testA_First");
assertTrue(true);
}
@Test
void testC_Third() {
System.out.println("-> Running testC_Third");
assertTrue(true);
}
@Test
void testB_Second() {
System.out.println("-> Running testB_Second");
assertTrue(true);
}
}Egendefinert rekkefølge med @Order
For detaljert kontroll kombinerer du @TestMethodOrder(MethodOrderer.OrderAnnotation.class) med annotasjonen @Order(value) på individuelle testmetoder. Lavere value-verdier betyr tidligere kjøring.
Dette lar deg definere en presis, egendefinert rekkefølge for testene dine.
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import static org.junit.jupiter.api.Assertions.assertTrue;
@TestMethodOrder(OrderAnnotation.class) // Activate @Order annotation
public class CustomOrderDemo {
@Test
@Order(2) // This test runs second
void processStepTwo() {
System.out.println("-> Running processStepTwo");
assertTrue(true);
}
@Test
@Order(1) // This test runs first
void initializeSystem() {
System.out.println("-> Running initializeSystem");
assertTrue(true);
}
@Test
@Order(3) // This test runs third
void finalizeReport() {
System.out.println("-> Running finalizeReport");
assertTrue(true);
}
}Beste praksis for rekkefølge
Selv om eksplisitt testrekkefølge er kraftig, bør den brukes med varsomhet:
- Prioriter uavhengighet: Hver test bør ideelt sett kunne kjøres alene.
- Lesbarhet: For mye styring av rekkefølgen kan gjøre testene vanskeligere å forstå og vedlikeholde.
- Vedlikeholdsbyrde: Endringer i systemet kan kreve at du vurderer og oppdaterer rekkefølgeverdiene på nytt.
Bruk bare rekkefølgestyring når det finnes en sterk og velbegrunnet grunn, og foretrekk @Order for å gjøre hensikten tydelig.
Kontroll av livssyklus og rekkefølge
Se på følgende JUnit 5-testklasse:
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class QuizTest {
private int sharedValue = 0;
@BeforeAll
void setup() {
sharedValue = 10;
System.out.println("BeforeAll: sharedValue = " + sharedValue);
}
@Test
@Order(2)
void testB() {
sharedValue += 2;
System.out.println(" TestB: sharedValue = " + sharedValue);
assertEquals(13, sharedValue);
}
@Test
@Order(1)
void testA() {
sharedValue += 1;
System.out.println(" TestA: sharedValue = " + sharedValue);
assertEquals(11, sharedValue);
}
@AfterAll
void teardown() {
System.out.println("AfterAll: sharedValue = " + sharedValue);
}
}Hva blir den endelige verdien av sharedValue som skrives ut i @AfterAll-metoden?
Oppsummering: Livssyklus og rekkefølge
I denne leksjonen har du lært avanserte JUnit 5-funksjoner for å styre testkjøringen:
- Livssyklus på klassenivå:
@BeforeAllog@AfterAllfor oppsett og opprydding som bare utføres én gang. - Instanslivssyklus:
@TestInstance(Lifecycle.PER_CLASS)for å aktivere delt tilstand og ikke-statiske koblinger på klassenivå. - Rekkefølge for testmetoder:
@TestMethodOrder(med strategier somAlphanumericellerOrderAnnotation) for å definere utførelsesrekkefølgen. - Egendefinert rekkefølge:
@Orderfor presis kontroll over metodenes rekkefølge.
Husk å bruke eksplisitt rekkefølge med omtanke, og prioriter uavhengige og robuste tester!
Lær deg Testing i praksis: JUnit, Mockito og integrasjonstester med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 12
- Leksjoner
- 48
Ofte stilte spørsmål
Er leksjonen «Testlivssyklus og rekkefølge» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Testing i praksis: JUnit, Mockito og integrasjonstester, inkludert «Testlivssyklus og rekkefølge», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Testing i praksis: JUnit, Mockito og integrasjonstester inneholder totalt 4 leksjoner.
Hva lærer jeg i «Testlivssyklus og rekkefølge»?
Kontroller kjøringsrekkefølgen for tester, og håndter oppsett og nedbryting av tester ved hjelp av avanserte livssyklusannotasjoner. Du øver på Testing i praksis: JUnit, Mockito og integrasjonstester med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Testing i praksis: JUnit, Mockito og integrasjonstester?
Ingen tidligere erfaring er nødvendig. Testing i praksis: JUnit, Mockito og integrasjonstester på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.
Hvor lang tid tar leksjonen «Testlivssyklus og rekkefølge»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Testing i praksis: JUnit, Mockito og integrasjonstester-leksjonen?
Ja. Alle Testing i praksis: JUnit, Mockito og integrasjonstester-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Testlivssyklus og rekkefølge
- Parametriserte og dynamiske tester
- Testing av unntak og tidsavbrudd
- Betingede tester og antakelser