Für alle Java-Devs, die nicht im Testing-Fachjargon ertrinken wollen! ☕
Seiteninhalt
- 1 🎯 Java Testing Basics – Das Fundament
- 2 📊 Java Coverage-Tools
- 3 🧪 Java Test-Frameworks & Tools
- 4 🏗️ Spring Boot Testing
- 5 🐳 Testcontainers (für Java)
- 6 🔬 Java-spezifische Advanced Testing
- 7 📦 Java Build-Tool Integration
- 8 🎯 Java Test-Naming-Conventions
- 9 🏗️ Java Test-Struktur-Patterns
- 10 🚨 Java-spezifische Testing-Fallstricke
- 11 📊 Java Testing Cheat-Sheet
- 12 🎯 Java Testing Best Practices
- 13 🎯 Basis-Begriffe – Das Fundament
- 14 📊 Coverage-Begriffe – „Wie viel wird getestet?“
- 15 🔬 Test-Arten – „Was wird wie getestet?“
- 16 🏗️ Test-Struktur-Begriffe
- 17 🎯 Assertions – „Was wird geprüft?“
- 18 📈 Qualitäts-Metriken
- 19 🔧 Test-Tools & Frameworks
- 20 🧪 Advanced Testing-Begriffe
- 21 📊 Test-Pyramide
- 22 🚨 Häufige Missverständnisse
- 23 💡 Praktische Tipps
- 24 📚 Glossar-Cheat-Sheet
🎯 Java Testing Basics – Das Fundament
JUnit Test
Was es ist: Der Standard für Tests in Java
Einfach gesagt: Java-Klasse mit @Test
Annotationen
Beispiel:
import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class CalculatorTest { @Test void shouldAddTwoNumbers() { Calculator calc = new Calculator(); int result = calc.add(2, 3); assertThat(result).isEqualTo(5); } }
@Test Annotation
Was es ist: Markiert eine Java-Methode als Test
Einfach gesagt: „Diese Methode ist ein Test, führe sie aus!“
JUnit 5: @org.junit.jupiter.api.Test JUnit 4: @org.junit.Test
Test Class (Test-Klasse)
Was es ist: Java-Klasse die Tests für eine andere Klasse enthält
Naming Convention: {KlassenName}Test.java
Beispiel: Calculator.java → CalculatorTest.java
📊 Java Coverage-Tools
JaCoCo (Java Code Coverage)
Was es ist: Standard Coverage-Tool für Java
Einfach gesagt: Zeigt dir welche Java-Zeilen von Tests ausgeführt werden
Maven Plugin:
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.8</version> </plugin>
Report ansehen: target/site/jacoco/index.html nach mvn test
Line Coverage in Java
Was es ist: Prozentsatz der Java-Code-Zeilen die von Tests durchlaufen werden Beispiel:
public class PaymentService { public String processPayment(BigDecimal amount) { if (amount.compareTo(BigDecimal.ZERO) <= 0) { // Zeile 1 ✅ return "Invalid amount"; // Zeile 2 ❌ nicht getestet } return "Payment processed"; // Zeile 3 ✅ } } // Line Coverage = 66% (2 von 3 Zeilen getestet)
Branch Coverage in Java
Was es ist: Prozentsatz der if/else/switch-Pfade die getestet werden Beispiel:
public String checkAge(int age) { if (age >= 18) { return "adult"; // Branch A ✅ getestet } else { return "minor"; // Branch B ❌ nicht getestet } } // Branch Coverage = 50% (nur if-Pfad getestet, else-Pfad vergessen)
🧪 Java Test-Frameworks & Tools
JUnit 5 (Jupiter)
Was es ist: Aktuelles Standard-Test-Framework für Java
Vorteile: Moderne Annotations, bessere Assertions, Parameter-Tests Dependency:
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.9.2</version> <scope>test</scope> </dependency>
AssertJ (für Java)
Was es ist: Fluent Assertion-Library für Java
Einfach gesagt: Macht Java-Test-Assertions lesbar
Dependency:
<dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.24.2</version> <scope>test</scope> </dependency>
Java-Beispiele:
// Standard JUnit (schlecht lesbar): assertEquals(5, list.size()); assertTrue(user.isActive()); // AssertJ (gut lesbar): assertThat(list).hasSize(5); assertThat(user.isActive()).isTrue(); assertThat(order.getItems()) .hasSize(3) .extracting(Item::getName) .containsExactly("Book", "Pen", "Notebook");
Mockito (für Java)
Was es ist: Standard-Mocking-Framework für Java
Einfach gesagt: Erstellt Fake-Java-Objekte für Tests
Dependency:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>5.1.1</version> <scope>test</scope> </dependency>
Java-Beispiel:
@ExtendWith(MockitoExtension.class) class OrderServiceTest { @Mock private PaymentService paymentService; // Fake PaymentService @InjectMocks private OrderService orderService; // Echte OrderService mit injiziertem Mock @Test void shouldCreateOrder() { // Mock konfigurieren when(paymentService.processPayment(any(PaymentRequest.class))) .thenReturn(PaymentResult.success("PAY-123")); // Test ausführen Order order = orderService.createOrder(orderRequest); // Verifizieren assertThat(order.getStatus()).isEqualTo(OrderStatus.CONFIRMED); verify(paymentService).processPayment(any(PaymentRequest.class)); } }
🏗️ Spring Boot Testing
@SpringBootTest
Was es ist: Startet kompletten Spring-Kontext für Tests
Einfach gesagt: „Lade die ganze Spring-Anwendung für diesen Test“
Langsam aber realistisch:
@SpringBootTest class OrderServiceIntegrationTest { @Autowired private OrderService orderService; // Echte Spring Bean @Test void shouldCreateOrderWithRealSpringContext() { Order order = orderService.createOrder(orderRequest); assertThat(order).isNotNull(); } }
@WebMvcTest
Was es ist: Testet nur die Web-Layer (Controller) ohne kompletten Spring-Kontext
Einfach gesagt: „Teste nur meinen REST Controller, nicht die ganze App“
@WebMvcTest(OrderController.class) class OrderControllerTest { @Autowired private MockMvc mockMvc; // Simuliert HTTP-Requests @MockBean private OrderService orderService; // Spring Boot Mock @Test void shouldCreateOrderViaHttp() throws Exception { when(orderService.createOrder(any())).thenReturn(testOrder); mockMvc.perform(post("/api/orders") .contentType(MediaType.APPLICATION_JSON) .content(orderJson)) .andExpect(status().isCreated()) .andExpect(jsonPath("$.id").value(123)); } }
@DataJpaTest
Was es ist: Testet nur die JPA-Repository-Layer
Einfach gesagt: „Teste nur meine Datenbank-Zugriffe“
@DataJpaTest class OrderRepositoryTest { @Autowired private TestEntityManager entityManager; // Test-DB-Manager @Autowired private OrderRepository orderRepository; @Test void shouldFindOrdersByStatus() { // Given Order order = new Order("Test Order", OrderStatus.PENDING); entityManager.persistAndFlush(order); // When List<Order> pendingOrders = orderRepository.findByStatus(OrderStatus.PENDING); // Then assertThat(pendingOrders).hasSize(1); assertThat(pendingOrders.get(0).getTitle()).isEqualTo("Test Order"); } }
🐳 Testcontainers (für Java)
Testcontainers
Was es ist: Docker-Container in Java-Tests verwenden
Einfach gesagt: „Starte echte PostgreSQL/Redis/etc. für Tests“
Dependency:
<dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <version>1.17.6</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <version>1.17.6</version> <scope>test</scope> </dependency>
Java-Beispiel:
@Testcontainers class OrderRepositoryIntegrationTest { @Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15") .withDatabaseName("testdb") .withUsername("test") .withPassword("test"); @DynamicPropertySource static void configureProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", postgres::getJdbcUrl); registry.add("spring.datasource.username", postgres::getUsername); registry.add("spring.datasource.password", postgres::getPassword); } @Test void shouldPersistOrderInRealPostgreSQL() { // Test mit echter PostgreSQL-Datenbank! } }
🔬 Java-spezifische Advanced Testing
PIT Mutation Testing (für Java)
Was es ist: Java-Tool das Code-Mutationen erstellt und testet
Einfach gesagt: „Ändere Java-Code automatisch und prüfe ob Tests versagen“
Maven Plugin:
<plugin> <groupId>org.pitest</groupId> <artifactId>pitest-maven</artifactId> <version>1.15.2</version> <dependencies> <dependency> <groupId>org.pitest</groupId> <artifactId>pitest-junit5-plugin</artifactId> <version>1.2.1</version> </dependency> </dependencies> </plugin>
Ausführung: mvn org.pitest:pitest-maven:mutationCoverage
Report: target/pit-reports/index.html
jqwik (Property-Based Testing für Java)
Was es ist: Java-Framework für automatisch generierte Test-Daten
Einfach gesagt: „Generiere 1000 zufällige Java-Objekte zum Testen“
Dependency:
<dependency> <groupId>net.jqwik</groupId> <artifactId>jqwik</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency>
Java-Beispiel:
class StringValidationTest { @Property void validStringsShouldNeverBeEmpty(@ForAll @StringLength(min = 1, max = 100) String input) { ValidationResult result = validator.validate(input); if (result.isValid()) { assertThat(input).isNotEmpty(); assertThat(input.trim()).isNotEmpty(); } } }
Pact (Contract Testing für Java)
Was es ist: Java-Tool für API-Contract-Testing zwischen Services
Einfach gesagt: „Stelle sicher dass API-Changes andere Java-Services nicht brechen“ Dependency:
<dependency> <groupId>au.com.dius.pact.consumer</groupId> <artifactId>junit5</artifactId> <version>4.4.1</version> <scope>test</scope> </dependency>
📦 Java Build-Tool Integration
Maven Surefire Plugin
Was es ist: Standard Maven-Plugin das JUnit-Tests ausführt
Einfach gesagt: mvn test führt deine Java-Tests aus
Config:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M9</version> <configuration> <includes> <include>**/*Test.java</include> <include>**/*Tests.java</include> </includes> </configuration> </plugin>
Gradle Test Task
Was es ist: Gradle-Task der JUnit-Tests ausführt
Einfach gesagt: gradle test für Gradle-Projekte
Config:
test { useJUnitPlatform() // Für JUnit 5 testLogging { events "passed", "skipped", "failed" } }
🎯 Java Test-Naming-Conventions
Test-Klassen-Naming:
Calculator.java
→CalculatorTest.java
OrderService.java
→OrderServiceTest.java
UserController.java
→UserControllerTest.java
Test-Methoden-Naming:
class OrderServiceTest { @Test void shouldCreateOrderWhenValidRequest() { } @Test void shouldThrowExceptionWhenInvalidPayment() { } @Test void shouldReturnEmptyListWhenNoOrdersExist() { } }
Pattern: should{ExpectedBehavior}When{Condition}
🏗️ Java Test-Struktur-Patterns
AAA in Java:
@Test void shouldCalculateDiscountForPremiumCustomers() { // Arrange (Given) Customer premiumCustomer = new Customer("John", CustomerType.PREMIUM); Order order = new Order(new BigDecimal("1000")); DiscountService discountService = new DiscountService(); // Act (When) BigDecimal discount = discountService.calculateDiscount(premiumCustomer, order); // Assert (Then) assertThat(discount).isEqualByComparingTo(new BigDecimal("100")); // 10% discount }
Test Data Builder Pattern (Java):
public class OrderTestDataBuilder { private String customerId = "CUST-DEFAULT"; private BigDecimal amount = new BigDecimal("100.00"); private OrderStatus status = OrderStatus.PENDING; public OrderTestDataBuilder withCustomer(String customerId) { this.customerId = customerId; return this; } public OrderTestDataBuilder withAmount(BigDecimal amount) { this.amount = amount; return this; } public Order build() { return new Order(customerId, amount, status); } public static OrderTestDataBuilder anOrder() { return new OrderTestDataBuilder(); } } // Verwendung in Tests: @Test void shouldApplyVipDiscount() { Order vipOrder = anOrder() .withCustomer("VIP-CUSTOMER") .withAmount(new BigDecimal("5000.00")) .build(); // Test logic... }
🚨 Java-spezifische Testing-Fallstricke
BigDecimal Testing
❌ Falsch:
assertThat(price).isEqualTo(new BigDecimal("19.99")); // Kann fehlschlagen wegen Scale!
✅ Richtig:
assertThat(price).isEqualByComparingTo(new BigDecimal("19.99")); // Scale-unabhängig
Date/Time Testing
❌ Falsch:
assertThat(order.getCreatedAt()).isEqualTo(LocalDateTime.now()); // Timing-Problem!
✅ Richtig:
assertThat(order.getCreatedAt()).isCloseTo(LocalDateTime.now(), within(1, ChronoUnit.SECONDS));
Exception Testing
❌ Falsch:
@Test(expected = IllegalArgumentException.class) // JUnit 4 Style void shouldThrowException() { service.processInvalidData("invalid"); }
✅ Richtig (JUnit 5):
@Test void shouldThrowExceptionForInvalidData() { assertThatThrownBy(() -> service.processInvalidData("invalid")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Data cannot be invalid"); }
📊 Java Testing Cheat-Sheet
Tool/Framework | Zweck | Maven Dependency |
---|---|---|
JUnit 5 | Test-Framework | junit-jupiter |
AssertJ | Fluent Assertions | assertj-core |
Mockito | Mocking | mockito-core |
JaCoCo | Coverage | jacoco-maven-plugin |
Testcontainers | Docker in Tests | testcontainers |
jqwik | Property Testing | jqwik |
PIT | Mutation Testing | pitest-maven |
Pact | Contract Testing | pact-jvm-junit5 |
Wichtige Maven Commands:
mvn test # Tests ausführen mvn test -Dtest=Calculator # Nur CalculatorTest ausführen mvn jacoco:report # Coverage Report mvn org.pitest:pitest-maven:mutationCoverage # Mutation Testing
Wichtige Gradle Commands:
gradle test # Tests ausführen gradle test --tests *Calculator* # Nur Calculator-Tests gradle jacocoTestReport # Coverage Report
🎯 Java Testing Best Practices
Package-Struktur:
src/ ├── main/java/com/company/ │ ├── service/OrderService.java │ └── model/Order.java └── test/java/com/company/ ├── service/OrderServiceTest.java └── model/OrderTest.java
Test Resource Files:
src/test/resources/ ├── application-test.properties ├── test-data.json └── schema.sql
Spring Profile für Tests:
# src/test/resources/application-test.properties spring.profiles.active=test spring.datasource.url=jdbc:h2:mem:testdb spring.jpa.hibernate.ddl-auto=create-drop logging.level.org.springframework.web=DEBUG
Jetzt sollten alle Java Testing-Posts perfekt verständlich sein! ☕🎯
Das Glossar ist speziell für Java-Entwickler – mit echten Tools, Dependencies und Code-Beispielen!
Tags: #Java #Testing #JUnit #SpringBoot #Maven #AssertJ #Mockito #TestingBasics #JavaDeveloper
🎯 Basis-Begriffe – Das Fundament
Test
Was es ist: Ein Stück Code, das prüft ob anderer Code funktioniert
Einfach gesagt: „Wenn ich diese Funktion mit Input X aufrufe, erwarte ich Output Y“
Beispiel:
@Test void shouldAddTwoNumbers() { Calculator calc = new Calculator(); int result = calc.add(2, 3); assertThat(result).isEqualTo(5); // Erwartung: 2+3 = 5 }
Test Case (Test-Fall)
Was es ist: Ein einzelner Test für ein spezifisches Szenario
Einfach gesagt: Eine konkrete Situation die du testen willst
Beispiel: „Was passiert wenn ich zwei positive Zahlen addiere?“
Test Suite (Test-Sammlung)
Was es ist: Eine Gruppe von Tests die zusammen gehören
Einfach gesagt: Alle Tests für eine Klasse oder ein Feature zusammengefasst
Beispiel: Alle Tests für die Calculator-Klasse = Calculator-Test-Suite
📊 Coverage-Begriffe – „Wie viel wird getestet?“
Test Coverage (Test-Abdeckung)
Was es ist: Prozentsatz des Codes der von Tests ausgeführt wird
Einfach gesagt: „Welcher Anteil meines Codes wird überhaupt von Tests berührt?“
Beispiel: 80% Coverage = 80% deiner Code-Zeilen werden von Tests durchlaufen
Visualisierung:
public class Calculator { public int add(int a, int b) { return a + b; // ✅ Diese Zeile wird von Tests ausgeführt } public int subtract(int a, int b) { return a - b; // ❌ Diese Zeile wird NIE von Tests ausgeführt } } // Test Coverage = 50% (1 von 2 Methoden getestet)
Line Coverage (Zeilen-Abdeckung)
Was es ist: Prozentsatz der Code-Zeilen die von Tests ausgeführt werden
Einfach gesagt: „Wie viele Zeilen meines Codes werden getestet?“
Wichtig: Hohe Line Coverage ≠ gute Tests!
Branch Coverage (Zweig-Abdeckung)
Was es ist: Prozentsatz der if/else-Pfade die getestet werden
Einfach gesagt: „Teste ich alle möglichen Wege durch meinen Code?“
Beispiel:
public String checkAge(int age) { if (age >= 18) { return "adult"; // Pfad A } else { return "minor"; // Pfad B } } // 100% Branch Coverage = beide Pfade (A und B) werden getestet // 50% Branch Coverage = nur einer der Pfade wird getestet
🔬 Test-Arten – „Was wird wie getestet?“
Unit Test (Einheiten-Test)
Was es ist: Testet eine einzelne Klasse/Methode isoliert
Einfach gesagt: „Funktioniert diese eine Sache für sich alleine?“
Charakteristikum: Schnell, keine Datenbank, keine Netzwerk-Calls
@Test void shouldCalculateInterest() { LoanCalculator calc = new LoanCalculator(); BigDecimal interest = calc.calculateInterest(1000, 5.0); assertThat(interest).isEqualTo(new BigDecimal("50.00")); }
Integration Test (Integrations-Test)
Was es ist: Testet ob mehrere Komponenten zusammen funktionieren
Einfach gesagt: „Funktionieren diese Teile zusammen?“
Beispiel: Service + Datenbank + Controller zusammen testen
End-to-End Test (E2E-Test)
Was es ist: Testet die komplette Anwendung wie ein echter User
Einfach gesagt: „Funktioniert das ganze System aus User-Sicht?“
Beispiel: Browser-Test der eine komplette User-Journey simuliert
🏗️ Test-Struktur-Begriffe
AAA Pattern (Arrange-Act-Assert)
Was es ist: Standard-Struktur für Tests
Einfach gesagt:
- Arrange: Test-Daten vorbereiten
- Act: Die zu testende Aktion ausführen
- Assert: Prüfen ob das Ergebnis stimmt
@Test void shouldTransferMoney() { // Arrange - Vorbereitung Account fromAccount = new Account(1000); Account toAccount = new Account(500); // Act - Aktion transferService.transfer(fromAccount, toAccount, 200); // Assert - Prüfung assertThat(fromAccount.getBalance()).isEqualTo(800); assertThat(toAccount.getBalance()).isEqualTo(700); }
Test Data (Test-Daten)
Was es ist: Daten die für Tests verwendet werden
Einfach gesagt: Input-Werte und erwartete Output-Werte für Tests
Beispiel: Test-User, Test-Orders, Test-Payments
Mock (Schein-Objekt)
Was es ist: Fake-Version einer echten Komponente für Tests
Einfach gesagt: „Tu so als wärst du die Datenbank/API/Service“
Warum: Tests sollen schnell sein und nicht von externen Systemen abhängen
@Mock private PaymentService paymentService; // Fake PaymentService @Test void shouldCreateOrder() { // Mock konfigurieren when(paymentService.processPayment(any())).thenReturn(PaymentResult.success()); // Test ausführen Order order = orderService.createOrder(orderRequest); assertThat(order.getStatus()).isEqualTo(OrderStatus.CONFIRMED); }
🎯 Assertions – „Was wird geprüft?“
Assertion (Behauptung)
Was es ist: Eine Aussage die in einem Test wahr sein muss
Einfach gesagt: „Ich behaupte dass X gleich Y ist“
Beispiel: assertThat(result).isEqualTo(expectedResult)
AssertJ vs. Standard Assertions
Standard (schwer lesbar):
assertEquals(5, calculator.add(2, 3)); assertTrue(user.isActive());
AssertJ (gut lesbar):
assertThat(calculator.add(2, 3)).isEqualTo(5); assertThat(user.isActive()).isTrue();
📈 Qualitäts-Metriken
Test Quality (Test-Qualität)
Was es ist: Wie gut deine Tests tatsächlich Bugs finden
Einfach gesagt: „Sind meine Tests nützlich oder nur Zeitverschwendung?“
Problem: Hohe Coverage ≠ hohe Quality!
Mutation Score (Mutations-Punktzahl)
Was es ist: Prozentsatz der Code-Mutationen die von Tests erkannt werden
Einfach gesagt: „Wie viele künstliche Bugs erkennen meine Tests?“
Beispiel: 90% Mutation Score = Tests erkennen 90% aller eingebauten Fehler
So funktioniert’s:
// Original Code: if (age >= 18) return "adult"; // Mutation (künstlicher Bug): if (age > 18) return "adult"; // >= wurde zu > // Guter Test würde diesen Bug erkennen // Schlechter Test würde ihn übersehen
Flaky Test (Wackeliger Test)
Was es ist: Test der manchmal grün, manchmal rot ist (ohne Code-Änderung)
Einfach gesagt: „Test-Roulette – niemand weiß ob er durchgeht“
Ursachen: Timing-Probleme, zufällige Daten, externe Dependencies
🔧 Test-Tools & Frameworks
JUnit
Was es ist: Das Standard-Test-Framework für Java
Einfach gesagt: Die Grundausstattung zum Testen in Java
Erkennungszeichen: @Test Annotation
AssertJ
Was es ist: Bibliothek für lesbare Test-Assertions
Einfach gesagt: Macht Test-Prüfungen verständlicher
Erkennungszeichen: assertThat().isEqualTo()
Mockito
Was es ist: Framework zum Erstellen von Mock-Objekten
Einfach gesagt: Hilft beim Erstellen von Fake-Objekten für Tests
Erkennungszeichen: @Mock
, when().thenReturn()
Testcontainers
Was es ist: Echte Docker-Container in Tests verwenden
Einfach gesagt: „Starte eine echte Datenbank für meine Tests“
Vorteil: Realistischere Tests als mit Mocks
🧪 Advanced Testing-Begriffe
Property-Based Testing
Was es ist: Tests mit automatisch generierten Test-Daten
Einfach gesagt: „Test nicht ein Beispiel, sondern hunderte automatisch“
Tool: jqwik für Java
Beispiel: Statt „teste add(2,3)“ → „teste add() mit 1000 zufälligen Zahlen-Paaren“
Contract Testing
Was es ist: Tests die API-Verträge zwischen Services prüfen
Einfach gesagt: „Stelle sicher dass API-Changes andere Services nicht brechen“
Tool: Pact
Test Data Builder
Was es ist: Pattern zum eleganten Erstellen von Test-Objekten
Einfach gesagt: „Fluent API für Test-Daten-Erstellung“
// Statt mühsam: User user = new User("John", "Doe", "john@test.com", true, 25, Address.builder()...); // Elegant: User user = anUser() .withName("John", "Doe") .withEmail("john@test.com") .aged(25) .build();
Chaos Engineering
Was es ist: Absichtlich Probleme in Tests einbauen
Einfach gesagt: „Was passiert wenn die Datenbank langsam wird?“
Ziel: Production-Probleme in Tests simulieren
📊 Test-Pyramide
Test Pyramid (Test-Pyramide)
Was es ist: Empfohlene Verteilung verschiedener Test-Arten
Einfach gesagt: „Viele schnelle Tests, wenige langsame Tests“
/\ / \ E2E Tests (10%) / \ - Langsam, teuer /______\ - Browser/UI Tests / \ / \ Integration Tests (20%) / \- API Tests, Service Tests /______________\ Unit Tests (70%) - Schnell, billig, isoliert
Warum diese Verteilung:
- Unit Tests: Schnell, einfach zu debuggen, günstig
- Integration Tests: Mittlere Geschwindigkeit, testen Zusammenspiel
- E2E Tests: Langsam, komplex, aber realistisch
🚨 Häufige Missverständnisse
„100% Coverage = Perfekte Tests“
❌ Falsch! Coverage misst nur „wurde Code ausgeführt“, nicht „wurde sinnvoll getestet“
Beispiel für nutzlose 100% Coverage:
@Test void testEverything() { Calculator calc = new Calculator(); calc.add(1, 2); // Code wird ausgeführt calc.subtract(5, 3); // Code wird ausgeführt calc.multiply(2, 4); // Code wird ausgeführt // ABER: Keine einzige Assertion! Test ist nutzlos! }
„Unit Tests sind immer besser als Integration Tests“
❌ Falsch! Beide haben ihre Berechtigung:
- Unit Tests: Gut für Algorithmus-Logic, Validation
- Integration Tests: Gut für Workflow-Testing, API-Testing
„Mehr Tests = Bessere Software“
❌ Falsch! Qualität > Quantität. 10 gute Tests > 100 schlechte Tests.
💡 Praktische Tipps
Wann welcher Test-Typ:
Unit Tests für:
- Business Logic (Berechnungen, Validierungen)
- Algorithmus-Testing
- Edge-Case-Testing
Integration Tests für:
- API-Endpoints
- Service-Zusammenspiel
- Datenbank-Interaktionen
E2E Tests für:
- Critical User Journeys
- Happy-Path-Szenarien
- Business-Critical-Workflows
Red Flags bei Tests:
- Tests ohne Assertions: Nutzlos
- Tests die nie fehlschlagen: Verdächtig
- Tests die bei jeder Code-Änderung brechen: Zu spezifisch
- Tests die 10+ Minuten dauern: Zu komplex
📚 Glossar-Cheat-Sheet
Begriff | Kurzerklärung | Beispiel-Tool |
---|---|---|
Unit Test | Testet eine Komponente isoliert | JUnit |
Mock | Fake-Objekt für Tests | Mockito |
Coverage | Prozent des getesteten Codes | JaCoCo |
Assertion | Prüfung im Test | AssertJ |
AAA | Arrange-Act-Assert Struktur | – |
Mutation Score | Qualität der Tests messen | PIT |
Property Test | Automatisch generierte Test-Daten | jqwik |
Contract Test | API-Verträge prüfen | Pact |
Chaos Test | Probleme simulieren | Chaos Monkey |
Test Pyramid | Empfohlene Test-Verteilung | – |
Jetzt sollten Dr. Cassian’s Testing-Posts viel verständlicher sein! 🎯
Fehlt ein Begriff? Schreib’s in die Kommentare!
Tags: #Testing #Glossary #JUnit #TestingBasics #Beginner #Java #TestCoverage #UnitTesting