Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| modul:m450:learningunits:lu16:aufgaben:behave [2025/10/23 08:18] – angelegt kmaurizi | modul:m450:learningunits:lu16:aufgaben:behave [2025/10/23 09:11] (aktuell) – [Ausführung] kmaurizi | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | ====== | + | ====== |
| <WRAP center round todo 60%> | <WRAP center round todo 60%> | ||
| Erstelle mit **Behave** zwei kleine BDD-Übungen inkl. Feature-Dateien und Schrittdefinitionen. | Erstelle mit **Behave** zwei kleine BDD-Übungen inkl. Feature-Dateien und Schrittdefinitionen. | ||
| - | Arbeite | + | **Wichtig: |
| + | Arbeite in der üblichen | ||
| </ | </ | ||
| Zeile 10: | Zeile 11: | ||
| behave_project/ | behave_project/ | ||
| | | ||
| - | | + | |
| - | | + | |
| | | ||
| - | ├── temperature.feature | + | ├── temperature.feature |
| - | ├── login.feature | + | ├── login.feature |
| └── steps/ | └── steps/ | ||
| - | | + | |
| - | | + | |
| </ | </ | ||
| + | |||
| + | **Hinweise allgemein: | ||
| + | * '' | ||
| + | * Schrittdefinitionen befinden sich in '' | ||
| + | * Gemeinsame Daten im Szenario könnt ihr im '' | ||
| + | * Hardcodierte Zahlen in Szenarien sind ok für den Einstieg (z. B. 0°C → 32°F). Später könnt ihr '' | ||
| ---- | ---- | ||
| ===== Auftrag 1 – Temperatur-Umrechnung (Celsius ↔ Fahrenheit) ===== | ===== Auftrag 1 – Temperatur-Umrechnung (Celsius ↔ Fahrenheit) ===== | ||
| - | **Ziel: | + | **Ziel:** BDD-Tests für eine Umrechnungsfunktion. |
| - | Teste korrekte Werte und Fehlerverhalten (z. B. ungültige Eingaben). | + | |
| - | ==== Feature-Datei ==== | + | ==== Feature-Datei |
| **Datei:** '' | **Datei:** '' | ||
| < | < | ||
| + | # HINWEIS: Verwende klare, messbare Erwartungen (z. B. exakte Zahlen). | ||
| + | # Du kannst später Toleranzen im Code prüfen (z. B. |result-expected| < 1e-6). | ||
| + | |||
| Feature: Temperaturumrechnung | Feature: Temperaturumrechnung | ||
| Damit ich Temperaturwerte standardisiert anzeigen kann | Damit ich Temperaturwerte standardisiert anzeigen kann | ||
| Zeile 44: | Zeile 53: | ||
| Scenario: Ungültige Eingabe (String) | Scenario: Ungültige Eingabe (String) | ||
| + | # HINWEIS: Strings oder None sollen eine Exception auslösen | ||
| Given eine ungültige Eingabe " | Given eine ungültige Eingabe " | ||
| When ich eine Umrechnung ausführe | When ich eine Umrechnung ausführe | ||
| Zeile 49: | Zeile 59: | ||
| </ | </ | ||
| - | ==== Schrittdefinitionen (Vorlage) ==== | + | ==== Schrittdefinitionen (Gerüst + Hinweise) ==== |
| **Datei:** '' | **Datei:** '' | ||
| <code python> | <code python> | ||
| + | # HINWEIS: Importiere deine Produktionsfunktionen aus app.converter | ||
| + | # from app.converter import c_to_f, f_to_c | ||
| + | |||
| from behave import given, when, then | from behave import given, when, then | ||
| - | from app.converter import c_to_f, f_to_c | ||
| @given(" | @given(" | ||
| def step_given_celsius(context, | def step_given_celsius(context, | ||
| - | context.input_c = c | + | |
| + | pass | ||
| @given(" | @given(" | ||
| def step_given_fahrenheit(context, | def step_given_fahrenheit(context, | ||
| - | context.input_f = f | + | |
| + | pass | ||
| @given(' | @given(' | ||
| def step_given_invalid(context, | def step_given_invalid(context, | ||
| - | context.invalid = text | + | |
| + | pass | ||
| @when(" | @when(" | ||
| def step_when_to_f(context): | def step_when_to_f(context): | ||
| - | | + | |
| + | # HINWEIS: beachte Datentypen (int/ | ||
| + | pass | ||
| @when(" | @when(" | ||
| def step_when_to_c(context): | def step_when_to_c(context): | ||
| - | | + | |
| + | pass | ||
| @when(" | @when(" | ||
| def step_when_convert_any(context): | def step_when_convert_any(context): | ||
| - | | + | |
| - | | + | |
| - | except Exception | + | pass |
| - | | + | |
| @then(" | @then(" | ||
| def step_then_f(context, | def step_then_f(context, | ||
| - | | + | |
| + | pass | ||
| @then(" | @then(" | ||
| def step_then_c(context, | def step_then_c(context, | ||
| - | | + | |
| + | pass | ||
| @then(" | @then(" | ||
| def step_then_error(context): | def step_then_error(context): | ||
| - | | + | |
| + | pass | ||
| </ | </ | ||
| - | ==== Produktivcode (Vorlage) ==== | + | ==== Produktivcode (Gerüst + Hinweise) ==== |
| **Datei:** '' | **Datei:** '' | ||
| <code python> | <code python> | ||
| + | # HINWEIS: Implementiere die beiden Funktionen gemäß Formeln: | ||
| + | # F = C * 9/5 + 32 | ||
| + | # C = (F - 32) * 5/9 | ||
| + | # Validiere Eingaben: akzeptiere nur int/float, sonst ValueError. | ||
| + | |||
| def c_to_f(celsius): | def c_to_f(celsius): | ||
| - | | + | |
| - | raise ValueError("celsius must be a number") | + | # TODO: Umrechnen und Rückgabe |
| - | return celsius * 9.0 / 5.0 + 32.0 | + | raise NotImplementedError("c_to_f ist noch nicht implementiert") |
| def f_to_c(fahrenheit): | def f_to_c(fahrenheit): | ||
| - | | + | |
| - | raise ValueError("fahrenheit must be a number") | + | # TODO: Umrechnen und Rückgabe |
| - | return (fahrenheit - 32.0) * 5.0 / 9.0 | + | raise NotImplementedError("f_to_c ist noch nicht implementiert") |
| </ | </ | ||
| Zeile 112: | Zeile 137: | ||
| ===== Auftrag 2 – Login/ | ===== Auftrag 2 – Login/ | ||
| - | **Ziel: | + | **Ziel:** BDD-Tests für einen sehr einfachen Login-Workflow. |
| - | Teste: erfolgreicher Login, falsches Passwort, unbekannter Benutzer. | + | |
| - | ==== Feature-Datei ==== | + | ==== Feature-Datei |
| **Datei:** '' | **Datei:** '' | ||
| < | < | ||
| + | # HINWEIS: Nutze Background, um einen Startzustand für alle Szenarien zu definieren. | ||
| + | |||
| Feature: Benutzer-Login | Feature: Benutzer-Login | ||
| Um den Zugang zu schützen | Um den Zugang zu schützen | ||
| Zeile 138: | Zeile 164: | ||
| </ | </ | ||
| - | ==== Schrittdefinitionen (Vorlage) ==== | + | ==== Schrittdefinitionen (Gerüst + Hinweise) ==== |
| **Datei:** '' | **Datei:** '' | ||
| <code python> | <code python> | ||
| + | # HINWEIS: Importiere deinen AuthService aus app.auth | ||
| + | # from app.auth import AuthService | ||
| + | |||
| from behave import given, when, then | from behave import given, when, then | ||
| - | from app.auth import AuthService | ||
| @given(' | @given(' | ||
| def step_given_user_exists(context, | def step_given_user_exists(context, | ||
| - | | + | |
| - | | + | |
| + | pass | ||
| @when(' | @when(' | ||
| def step_when_login(context, | def step_when_login(context, | ||
| - | | + | |
| + | pass | ||
| @then(" | @then(" | ||
| def step_then_logged_in(context): | def step_then_logged_in(context): | ||
| - | | + | |
| + | pass | ||
| @then(" | @then(" | ||
| def step_then_denied(context): | def step_then_denied(context): | ||
| - | | + | |
| + | pass | ||
| </ | </ | ||
| - | ==== Produktivcode (Vorlage) ==== | + | ==== Produktivcode (Gerüst + Hinweise) ==== |
| **Datei:** '' | **Datei:** '' | ||
| <code python> | <code python> | ||
| + | # HINWEIS: Minimaler AuthService ohne externe Abhängigkeiten. | ||
| + | # - _users als In-Memory-Dict | ||
| + | # - register(username, | ||
| + | # - login(username, | ||
| + | |||
| class AuthService: | class AuthService: | ||
| def __init__(self): | def __init__(self): | ||
| - | self._users = {} | + | |
| + | | ||
| def register(self, | def register(self, | ||
| - | | + | |
| - | raise ValueError("username and password required") | + | # TODO: Benutzer speichern |
| - | self._users[username] = password | + | |
| def login(self, username, password): | def login(self, username, password): | ||
| - | | + | |
| - | | + | # Rückgabe: True bei Erfolg, sonst False |
| - | | + | |
| </ | </ | ||
| Zeile 189: | Zeile 227: | ||
| </ | </ | ||
| - | **Erwartung: | + | **Erwartung: |
| - | Erweitere optional | + | |
| + | **Optional: | ||
| ---- | ---- | ||