{"meta":{"title":"Schreiben von Tests mit GitHub Copilot","intro":"Wird Copilot verwendet, um Komponenten- und Integrationstests zu generieren und die Codequalität zu verbessern.","product":"GitHub Copilot","breadcrumbs":[{"href":"/de/copilot","title":"GitHub Copilot"},{"href":"/de/copilot/tutorials","title":"Anleitungen"},{"href":"/de/copilot/tutorials/write-tests","title":"Tests schreiben"}],"documentType":"article"},"body":"# Schreiben von Tests mit GitHub Copilot\n\nWird Copilot verwendet, um Komponenten- und Integrationstests zu generieren und die Codequalität zu verbessern.\n\n## Einführung\n\nGitHub Copilot kann Sie bei der schnellen Entwicklung von Tests und der Verbesserung der Produktivität unterstützen. In diesem Artikel zeigen wir, wie Sie mit Copilot sowohl Unit- als auch Integrationstests schreiben können. Während Copilot beim Generieren von Tests für grundlegende Funktionen gut abschneidet, erfordern komplexe Szenarien detailliertere Eingabeaufforderungen und Strategien. In diesem Artikel wird anhand praktischer Beispiele gezeigt, wie Copilot verwendet wird, um Aufgaben zu zerlegen und die Korrektheit von Code zu überprüfen.\n\n## Voraussetzungen\n\nBevor Sie beginnen, müssen Sie Folgendes haben:\n\n* Ein [GitHub Copilot Abonnementplan](/de/copilot/get-started/plans).\n* Visual Studio, Visual Studio Codeoder eine beliebige JetBrains-IDE.\n* Die in Ihrer IDE installierte [GitHub Copilot Erweiterung](/de/copilot/how-tos/set-up/install-copilot-extension).\n\n## Schreiben von Komponententests mit Copilot Chat\n\nIn diesem Abschnitt sehen wir uns an, wie Sie mit GitHub Copilot Chat Unit-Tests für eine Python-Klasse erstellen. Dieses Beispiel zeigt, wie Sie Copilot verwenden können, um Unit-Tests für eine Klasse wie `BankAccount` zu erstellen. Wir zeigen Ihnen, wie Sie Copilot anweisen, Tests zu generieren, auszuführen und die Ergebnisse zu überprüfen.\n\n### Beispielklasse: `BankAccount`\n\nAngenommen, du hast eine Klasse `BankAccount`, die Methoden zum Einzahlen, Auszahlen und Abrufen des Kontostands enthält. Erstellen Sie eine neue Datei `bank_account.py` in einem GitHub Repository, und fügen Sie die folgende `BankAccount` Klasse in Python hinzu.\n\n```python\nclass BankAccount:\n    def __init__(self, initial_balance=0):\n        if initial_balance < 0:\n            raise ValueError(\"Initial balance cannot be negative.\")\n        self.balance = initial_balance\n\n    def deposit(self, amount):\n        if amount <= 0:\n            raise ValueError(\"Deposit amount must be positive.\")\n        self.balance += amount\n\n    def withdraw(self, amount):\n        if amount <= 0:\n            raise ValueError(\"Withdrawal amount must be positive.\")\n        if amount > self.balance:\n            raise ValueError(\"Cannot withdraw more than the current balance.\")\n        self.balance -= amount\n\n    def get_balance(self):\n        return self.balance\n```\n\n### Generieren von Komponententests mit Copilot Chat\n\nDu kannst Copilot dazu auffordern, Tests zu schreiben, die verschiedene Szenarios abdecken. Achte auf spezifische Testanforderungen, um die besten Ergebnisse zu erzielen. Im Folgenden findest du einen Beispielprompt, mit dem du Komponententests für die `BankAccount`-Klasse generieren kannst.\n\n**Prompt:***„Schreibe eine umfassende Sammlung von Komponententests für die BankAccount()-Funktion in Python. Schreibe mehrere Testmethoden, die viele verschiedene Szenarios abdecken, einschließlich Grenzfällen, Ausnahmebehandlung und Datenüberprüfung.“*\n\nWichtige Aspekte dieses Prompts:\n\n* **Bereich:** Es fordert explizit eine umfassende Reihe von Komponententests, sodass Copilot mehr als nur grundlegende Tests generiert werden, die eine Vielzahl potenzieller Anwendungsfälle abdecken.\n* **Szenarios:** Der Prompt gibt an, dass die Tests Folgendes berücksichtigen sollen:\n  * **Grenzfälle**: Es wird auf Grenzbedingungen (z. B. negative Werte für Ein- oder Auszahlungen und Auszahlungen, die den verfügbaren Saldo übersteigen) getestet.\n  * **Ausnahmebehandlung:** Es wird auf Fehler getestet, die ausgelöst werden sollen, wenn bestimmte ungültige Aktionen auftreten (z. B. Auszahlungen, die den verfügbaren Saldo übersteigen und das Einzahlen negativer Beträge).\n  * **Datenüberprüfung:** Es wird sichergestellt, dass Eingaben von den Methoden korrekt validiert und verarbeitet werden.\n\nCopilot liefert Ihnen eine Antwort wie die folgende.\n\n```python\nimport unittest\nfrom bank_account import BankAccount\n\nclass TestBankAccount(unittest.TestCase):\n    def setUp(self):\n        self.account = BankAccount()\n\n    def test_initial_balance(self):\n        self.assertEqual(self.account.get_balance(), 0)\n\n    def test_deposit_positive_amount(self):\n        self.account.deposit(100)\n        self.assertEqual(self.account.get_balance(), 100)\n\n    def test_withdraw_within_balance(self):\n        self.account.deposit(100)\n        self.account.withdraw(50)\n        self.assertEqual(self.account.get_balance(), 50)\n\n    def test_deposit_negative_amount_raises_error(self):\n        with self.assertRaises(ValueError):\n            self.account.deposit(-100)\n\n    def test_withdraw_negative_amount_raises_error(self):\n        with self.assertRaises(ValueError):\n            self.account.withdraw(-50)\n\n    def test_withdraw_more_than_balance_raises_error(self):\n        self.account.deposit(100)\n        with self.assertRaises(ValueError):\n            self.account.withdraw(200)\n\n    def test_initial_balance_negative_raises_error(self):\n        with self.assertRaises(ValueError):\n            BankAccount(-100)\n\nif __name__ == '__main__':\n    unittest.main()\n```\n\n### Ausführen der Testfälle\n\nDie von Copilot generierte Testsuite enthält einen Testfall für jedes im Prompt angegebene Szenario. Jede Funktion in der `BankAccount`-Klasse wird auf verschiedene Bedingungen getestet, einschließlich gültiger Vorgänge wie Ein- und Auszahlungen sowie Grenzfälle wie negative Beträge und versuchte Auszahlungen, die den verfügbaren Saldo übersteigen.\n\nSobald Copilot die Test-Suite zu Ihrer Zufriedenheit generiert hat, fügen Sie den Code in eine neue Datei `test_bank_account.py` ein. Du kannst fragen, wie die Tests ausgeführt werden.\n\n**Prompt:***\"Wie führe ich diese Unit-Tests in Python mit dem unittest-Framework aus?\"*\n\nCopilot gibt Ihnen den folgenden Bash-Befehl.\n\n```bash\npython -m unittest test_bank_account.py\n```\n\nNach dem Ausführen der Tests wird dir die Ausgabe im Terminal oder in der IDE angezeigt. Wenn alle Tests erfolgreich abgeschlossen werden, kannst du sicher sein, dass deine `BankAccount`-Klasse erwartungsgemäß funktioniert.\n\n#### Slash-Befehl\n\nDarüber hinaus können Sie Copilot mit dem `/tests` Slash-Befehl anweisen, eine vollständige Suite von Unit-Tests zu schreiben. Stellen Sie sicher, dass Sie die Datei im aktuellen Tab Ihrer IDE geöffnet haben und Copilot Unit-Tests für diese Datei generiert. Die generierten Tests Copilot decken möglicherweise nicht alle Szenarien ab, daher sollten Sie immer den generierten Code überprüfen und zusätzliche Tests hinzufügen, die möglicherweise erforderlich sind.\n\n> \\[!TIP] Wenn Sie Copilot bitten, Tests für eine Codedatei zu schreiben, die noch nicht durch Unit-Tests abgedeckt ist, können Sie Copilot nützlichen Kontext liefern, indem Sie eine oder mehrere vorhandene Testdateien in nebeneinanderliegenden Tabs in Ihrem Editor öffnen.\n> Copilot kann das verwendete Testframework sehen und wird wahrscheinlicher einen Test schreiben, der mit ihren vorhandenen Tests konsistent ist.\n\nCopilot generiert eine Komponententestsuite wie die folgende.\n\n```python\nimport unittest\nfrom bank_account import BankAccount\n\nclass TestBankAccount(unittest.TestCase):\n    def setUp(self):\n        self.account = BankAccount()\n\n    def test_initial_balance(self):\n        self.assertEqual(self.account.get_balance(), 0)\n```\n\n## Schreiben von Integrationstests mit Copilot\n\nIntegrationstests sind unerlässlich, um sicherzustellen, dass die verschiedenen Komponenten deines Systems zusammen ordnungsgemäß funktionieren. In diesem Abschnitt wird die `BankAccount`-Klasse um Interaktionen mit einem externen Dienst `NotificationSystem` erweitert. Außerdem wird Systemverhalten mit Modelltests getestet, ohne dass echte Verbindungen erforderlich sind. Ziel der Integrationstests ist es, die Interaktion zwischen der `BankAccount`-Klasse und den `NotificationSystem`-Diensten zu prüfen und sicherzustellen, dass sie ordnungsgemäß zusammenarbeiten.\n\n### Beispielklasse: `BankAccount` mit Benachrichtigungsdiensten\n\nAktualisiere die `BankAccount`-Klasse, sodass Interaktionen mit einem externen Dienst einbezogen werden, z. B. ein `NotificationSystem`-Dienst, der Benachrichtigungen an Benutzer sendet.\n`NotificationSystem` stellt die Integration dar, die getestet werden muss.\n\nAktualisiere die `BankAccount`-Klasse in der `bank_account.py`-Datei mit dem folgenden Codeschnipsel.\n\n```python\nclass BankAccount:\n    def __init__(self, initial_balance=0, notification_system=None):\n        if initial_balance < 0:\n            raise ValueError(\"Initial balance cannot be negative.\")\n        self.balance = initial_balance\n        self.notification_system = notification_system\n\n    def deposit(self, amount):\n        if amount <= 0:\n            raise ValueError(\"Deposit amount must be positive.\")\n        self.balance += amount\n        if self.notification_system:\n            self.notification_system.notify(f\"Deposited {amount}, new balance: {self.balance}\")\n\n    def withdraw(self, amount):\n        if amount <= 0:\n            raise ValueError(\"Withdrawal amount must be positive.\")\n        if amount > self.balance:\n            raise ValueError(\"Cannot withdraw more than the current balance.\")\n        self.balance -= amount\n\n        if self.notification_system:\n            self.notification_system.notify(f\"Withdrew {amount}, new balance: {self.balance}\")\n\n    def get_balance(self):\n        return self.balance\n```\n\nHier werden wir unsere Anforderung Copilot zum Schreiben von Integrationstests für die `BankAccount` Klasse in kleinere, verwaltbare Teile unterteilen. Dies wird Copilot dabei helfen, genauere und relevantere Tests zu generieren.\n\n**Prompt:***„Schreibe Integrationstests für die `deposit`-Funktion in der `BankAccount`-Klasse. Verwende Modelltests, um `NotificationSystem` zu simulieren und zu überprüfen, ob der Dienst nach einer Einzahlung richtig aufgerufen wird.“*\n\nWichtige Aspekte dieses Prompts:\n\n* **Geltungsbereich:** Es spezifiziert Integrationstests, die sich auf die Interaktion zwischen der `deposit`-Funktion und `NotificationSystem` konzentrieren, anstelle von nur Einheitstests.\n* **Modelltests:** Er fordert explizit die Verwendung von Modelltests, um `NotificationSystem` zu simulieren und sicherzustellen, dass die Interaktion mit externen Systemen getestet wird, ohne dass diese tatsächlich implementiert werden müssen.\n* **Überprüfung:** Der Prompt fordert, dass das korrekte Aufrufen der `NotificationSystem`-Funktion nach einer Einzahlung überprüft werden muss, um sicherzustellen, dass die Integration zwischen den Komponenten erwartungsgemäß funktioniert.\n* **Genauigkeit:** Der Prompt gibt die zu testende Methode (`deposit`) und die zu testende Klasse (`BankAccount`) genau vor.\n\n> \\[!TIP] Wenn Copilot ungültige Tests erzeugt, geben Sie Beispiele für Ein- und Ausgaben der Funktion an, die Sie testen möchten. Dies wird Copilot dabei helfen, das erwartete Verhalten der Funktion zu bewerten.\n\nCopilot generiert eine Testsuite wie die folgende.\n\n```python\nimport unittest\nfrom unittest.mock import Mock\nfrom bank_account import BankAccount\n\nclass TestBankAccountIntegration(unittest.TestCase):\n    def setUp(self):\n        self.notification_system = Mock()\n\n    def test_deposit_with_notification(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        account.deposit(50)\n        self.assertEqual(account.get_balance(), 150)\n        self.notification_system.notify.assert_called_once_with(\"Deposited 50, new balance: 150\")\n\nif __name__ == '__main__':\n    unittest.main()\n```\n\nFüge den generierten Code in eine neue `test_bank_account_integration.py`-Datei ein.\n\n### Verbessern der Testfälle\n\nDer oben genannte Prompt hat einen einzigen Testfall generiert, der überprüft, ob `NotificationSystem` nach einer gültigen Einzahlung aufgerufen wird. Jedoch deckt es keine Fälle ab, in denen während der Einzahlung ein Fehler ausgelöst wird. In diesen Szenarios sollte `NotificationSystem` nicht aufgerufen werden. Daher sollte ein Testfall hinzugefügt werden, der ungültige Einzahlungen verarbeitet und sicherstellt, dass das Benachrichtigungssystem nicht ausgelöst wird.\n\n**Prompt:***„Füge einen Testfall für ungültige Einzahlungsbeträge hinzu, um sicherzustellen, dass die Funktion die richtigen Ausnahmen auslöst und dass `NotificationService` nicht aufgerufen wird.“*\n\nCopilot generiert einen Testfall, z. B. folgendes.\n\n```python\n    def test_deposit_negative_amount_raises_error(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        with self.assertRaises(ValueError):\n            account.deposit(0)\n        self.notification_system.notify.assert_not_called()\n```\n\n### Fragen zu Verbesserungspotenzialen\n\nDa wir nun Testfälle geschrieben haben, um die Integrationsfunktionalität für Einzahlungen zu überprüfen, ist dies eine großartige Gelegenheit, nach Verbesserungen innerhalb der Testreihe zu suchen. Während die aktuellen Tests funktionsfähig sind, können wir Copilot dazu auffordern, die Codeabdeckung zu bewerten und Verbesserungspotenziale vorzuschlagen.\n\n**Prompt:***„Welche zusätzlichen Tests sollten einbezogen werden, um die Integration zwischen der `BankAccount`-Klasse und `NotificationSystem` vollständig abzudecken?“*\n\nCopilot diese Frage zu stellen, kann dir helfen, fehlende Testfälle zu ermitteln, die möglicherweise übersehen wurden.\nIm vorliegenden Beispiel wurden zwar gültige und ungültige Einzahlungen getestet, jedoch nicht die Auszahlungsfunktion.\n\nCopilot generiert eine aktualisierte Testsuite wie die folgende.\n\n<details>\n  <summary>Klicke hier, um das vollständige generierte Codebeispiel anzuzeigen.</summary>\n\n```python\nimport unittest\nfrom unittest.mock import Mock\nfrom bank_account import BankAccount\n\nclass TestBankAccountIntegration(unittest.TestCase):\n    def setUp(self):\n        self.notification_system = Mock()\n\n    def test_deposit_with_notification(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        account.deposit(50)\n        self.assertEqual(account.get_balance(), 150)\n        self.notification_system.notify.assert_called_once_with(\"Deposited 50, new balance: 150\")\n\n    def test_deposit_negative_amount_raises_error(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        with self.assertRaises(ValueError):\n            account.deposit(-50)\n        self.notification_system.notify.assert_not_called()\n\n    def test_deposit_zero_amount_raises_error(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        with self.assertRaises(ValueError):\n            account.deposit(0)\n        self.notification_system.notify.assert_not_called()\n\n    def test_withdraw_with_notification(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        account.withdraw(30)\n        self.assertEqual(account.get_balance(), 70)\n        self.notification_system.notify.assert_called_once_with(\"Withdrew 30, new balance: 70\")\n\n    def test_withdraw_exceeding_balance_raises_error(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        with self.assertRaises(ValueError):\n            account.withdraw(150)\n        self.notification_system.notify.assert_not_called()\n\n    def test_withdraw_negative_amount_raises_error(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        with self.assertRaises(ValueError):\n            account.withdraw(-30)\n        self.notification_system.notify.assert_not_called()\n\n    def test_withdraw_zero_amount_raises_error(self):\n        account = BankAccount(initial_balance=100, notification_system=self.notification_system)\n        with self.assertRaises(ValueError):\n            account.withdraw(0)\n        self.notification_system.notify.assert_not_called()\n\n    def test_initial_negative_balance_raises_error(self):\n        with self.assertRaises(ValueError):\n            BankAccount(initial_balance=-100, notification_system=self.notification_system)\n\nif __name__ == '__main__':\n    unittest.main()\n```\n\n</details>\n\nWenn du mit der von Copilot generierten Testsammlung zufrieden bist, führe die Tests mit dem folgenden Befehl aus, um die Ergebnisse zu überprüfen.\n\n```bash\npython -m unittest test_bank_account_integration.py\n```\n\n## Verwenden von Copilot Spaces zur Verbesserung von Testvorschlägen\n\nCopilot Spaces ist eine Funktion, mit der Sie aufgabenspezifischen Kontext organisieren und mit Copilot teilen können. Dies kann dazu beitragen, die Relevanz der erhaltenen Vorschläge zu verbessern. Indem Sie Copilot mehr Kontext zu Ihrem Projekt bereitstellen, können Sie bessere Testvorschläge bekommen.\n\nDu kannst z. B. einen Raum erstellen, der Folgendes umfasst:\n\n* Das Modul, das du testest (z. B. `payments.js`)\n* Die aktuelle Testsuite (z. B. `payments.test.js`)\n* Ein Testabdeckungsbericht oder Hinweise zu fehlenden Aspekten\n\nIn diesem Bereich können Sie Copilot Fragen stellen wie:\n\n> Welche Testfälle fehlen in `payments.test.js` basierend auf der Logik in `payments.js`?\n\nOder:\n\n> Schreibe einen Komponententest für die Erstattungslogik in `refund.js`, nach der Struktur in der vorhandenen Testsuite.\n\nWeitere Informationen zur Verwendung Copilot Spacesfinden Sie unter [Über GitHub Copilot Spaces](/de/copilot/concepts/context/spaces)."}