{"meta":{"title":"GitHub Copilot을 사용하여 테스트 작성","intro":"단위 및 통합 테스트를 생성하고 코드 품질을 개선하는 데 사용합니다 Copilot .","product":"GitHub Copilot","breadcrumbs":[{"href":"/ko/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/ko/enterprise-cloud@latest/copilot/tutorials","title":"자습서"},{"href":"/ko/enterprise-cloud@latest/copilot/tutorials/write-tests","title":"테스트 작성"}],"documentType":"article"},"body":"# GitHub Copilot을 사용하여 테스트 작성\n\n단위 및 통합 테스트를 생성하고 코드 품질을 개선하는 데 사용합니다 Copilot .\n\n## 소개\n\nGitHub Copilot 는 테스트를 빠르게 개발하고 생산성을 향상시키는 데 도움이 될 수 있습니다. 이 문서에서는 단위 및 통합 테스트를 모두 작성하는 데 사용할 Copilot 수 있는 방법을 보여 줍니다. 기본 함수에 대한 테스트를 생성할 때는 성능이 좋지만 Copilot 복잡한 시나리오에는 보다 자세한 프롬프트와 전략이 필요합니다. 이 문서에서는 작업을 분석하고 코드 정확성을 확인하는 데 사용하는 Copilot 실제 예제를 안내합니다.\n\n## 필수 조건\n\n시작하기 전에 다음을 확인해야 합니다.\n\n* [\n  GitHub Copilot 구독 계획](/ko/enterprise-cloud@latest/copilot/get-started/plans)입니다.\n* Visual Studio, Visual Studio Code, 또는 JetBrains의 모든 IDE.\n* [\n  GitHub Copilot\n  ](/ko/enterprise-cloud@latest/copilot/how-tos/set-up/install-copilot-extension) IDE에 설치된 확장입니다.\n\n## Copilot Chat를 사용한 단위 테스트 작성\n\n이 섹션에서는 Python 클래스에 대한 단위 테스트를 생성하는 데 사용하는 GitHub Copilot Chat 방법을 살펴봅니다. 이 예제에서는 다음과 같은 Copilot클래스에 대한 단위 테스트를 만드는 데 사용할 `BankAccount` 수 있는 방법을 보여 줍니다. 테스트를 생성하고, 실행하고, 결과를 확인하는 프롬프트 Copilot 를 표시하는 방법을 보여 줍니다.\n\n### 예제 클래스: `BankAccount`\n\n계정의 잔액을 입금, 인출 및 가져오는 방법을 포함하는 클래스 `BankAccount`부터 시작해 보겠습니다.\n`bank_account.py` 리포지토리에 새 파일 GitHub을 만들고, 다음 `BankAccount` 클래스를 Python으로 추가합니다.\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### 를 사용하여 단위 테스트 생성 Copilot Chat\n\nCopilot에 다양한 시나리오를 포괄하는 테스트를 작성하라는 요청을 보낼 수 있습니다. 최상의 결과를 얻으려면 테스트 요구 사항을 구체적으로 설명합니다. 다음은 `BankAccount` 클래스에 대한 단위 테스트를 생성하는 데 사용할 수 있는 프롬프트 예제입니다.\n\n**프롬프트:***Python에서 BankAccount() 함수에 대한 포괄적인 단위 테스트 제품군을 개발합니다. 에지 사례, 예외 처리 및 데이터 유효성 검사를 포함하여 광범위한 시나리오를 다루는 여러 테스트 메서드를 작성합니다.*\n\n이 프롬프트는 다음과 같은 몇 가지 중요한 작업을 수행합니다.\n\n* **범위:** 다양한 잠재적 사용 사례를 포괄하는 Copilot 기본 테스트 이상을 생성하도록 포괄적인 단위 테스트 제품군을 명시적으로 요청합니다.\n* **시나리오**: 프롬프트는 테스트에 다음을 포함하도록 지정합니다.\n  * **에지 사례**: 경계 조건 테스트(예: 예금 또는 인출에 대한 음수 값, 사용 가능한 잔액보다 더 많이 인출).\n  * **예외 처리**: 특정 잘못된 작업이 발생할 때 발생해야 하는 오류에 대한 테스트(예: 사용 가능한 잔액보다 더 많은 금액을 인출하고 음수 금액을 입금).\n  * **데이터 유효성 검사**: 입력의 유효성을 올바르게 검사하고 메서드에서 처리하도록 합니다.\n\nCopilot 는 다음과 같은 응답을 제공합니다.\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### 테스트 사례 실행\n\n생성된 Copilot 테스트 도구 모음에는 프롬프트에 지정된 각 시나리오에 대한 테스트 사례가 포함됩니다.\n`BankAccount` 클래스에서 각 함수는 예금 및 인출과 같은 유효한 작업뿐만 아니라 음수 금액 및 사용 가능한 잔액보다 더 많은 인출 시도와 같은 에지 사례를 포함하여 다양한 조건에 대해 테스트됩니다.\n\nCopilot가 원하는 대로 테스트 스위트를 생성하면 해당 코드를 새 파일 `test_bank_account.py`에 추가합니다. 테스트를 실행하는 방법을 물어볼 수 있습니다.\n\n**Prompt:***\"unittest 프레임워크를 사용하여 Python에서 이러한 단위 테스트를 어떻게 실행하나요?\"*\n\nCopilot 는 다음 bash 명령을 제공합니다.\n\n```bash\npython -m unittest test_bank_account.py\n```\n\n테스트를 실행하면 터미널 또는 IDE에 출력이 표시됩니다. 모든 테스트가 통과하면 `BankAccount` 클래스가 예상대로 작동하는지 확신할 수 있습니다.\n\n#### 슬래시 명령\n\n또한 Copilot 슬래시 명령어를 사용해 `/tests`에게 전체 단위 테스트 모음을 작성하도록 프롬프트할 수 있습니다. 파일이 IDE의 현재 탭에서 열려 있는지 Copilot 확인하고 해당 파일에 대한 단위 테스트를 생성합니다. 생성되는 테스트는 Copilot 모든 시나리오를 다루지 않을 수 있으므로 항상 생성된 코드를 검토하고 필요할 수 있는 추가 테스트를 추가해야 합니다.\n\n> \\[!TIP] 단위 테스트에서 아직 다루지 않는 코드 파일에 대한 테스트를 작성하도록 요청하는 Copilot 경우 편집기에서 인접한 탭에서 하나 이상의 기존 테스트 파일을 열어 유용한 컨텍스트를 제공할 Copilot 수 있습니다.\n> Copilot 은 사용하는 테스트 프레임워크를 볼 수 있으며 기존 테스트와 일치하는 테스트를 작성할 가능성이 높습니다.\n\nCopilot 는 다음과 같은 단위 테스트 제품군을 생성합니다.\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## Copilot를 사용한 통합 테스트 작성\n\n통합 테스트는 결합 시 시스템의 다양한 구성 요소가 올바르게 작동하는지 확인하는 데 필수적입니다. 이 섹션에서는 외부 서비스 `BankAccount`와의 상호 작용을 포함하고 모의 항목을 사용하여 실제 연결 없이도 시스템 동작을 테스트하도록 `NotificationSystem` 클래스를 확장합니다. 통합 테스트의 목표는 `BankAccount` 클래스와 `NotificationSystem` 서비스 간의 상호 작용을 확인하여 올바르게 함께 작동하는지 확인하는 것입니다.\n\n### 예제 클래스: Notification Services가 있는 `BankAccount`\n\n사용자에게 알림을 보내는 `BankAccount`와(과) 같은 외부 서비스와의 상호 작용을 포함하도록 `NotificationSystem` 클래스를 업데이트 해보겠습니다.\n`NotificationSystem`은 테스트해야 하는 통합을 나타냅니다.\n\n다음 코드 조각을 사용하여 `BankAccount` 파일의 `bank_account.py` 클래스를 업데이트합니다.\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\n여기서는 클래스에 대한 Copilot 통합 테스트를 `BankAccount` 더 작고 관리하기 쉬운 조각으로 작성하라는 요청을 세분화합니다. 이렇게 하면 보다 정확하고 관련 있는 테스트를 생성하는 데 도움이 Copilot 됩니다.\n\n**프롬프트:**\\_ \"`deposit` 클래스의 `BankAccount` 함수에 대한 통합 테스트를 작성합니다. 모의 개체를 사용하여 `NotificationSystem`을(를) 시뮬레이션하고 입금 후에 올바르게 호출되는지 확인합니다.\"\\_\n\n이 프롬프트는 다음과 같은 몇 가지 중요한 작업을 수행합니다.\n\n* **범위**: 단위 테스트가 아니라 `deposit` 함수와 `NotificationSystem` 간의 상호 작용에 중점을 두고 통합 테스트를 지정합니다.\n* **모의 객체:** 외부 시스템과의 상호 작용을 실제 구현에 의존하지 않고 테스트하기 위해 `NotificationSystem`을(를) 모의 객체로 시뮬레이션하도록 명시적으로 요청합니다.\n* **확인**: 프롬프트는 `NotificationSystem`이 입금 후 올바르게 호출되는지 확인하여 구성 요소 간의 통합이 예상대로 작동하는지 확인합니다.\n* **특이성**: 프롬프트는 테스트할 메서드(`deposit`) 및 클래스(`BankAccount`)를 명확하게 표시합니다.\n\n> \\[!TIP] 잘못된 테스트를 생성하는 경우 Copilot 테스트하려는 함수에 대한 입력 및 출력의 예를 제공합니다. 이렇게 하면 함수의 예상 동작을 평가하는 데 도움이 됩니다 Copilot .\n\nCopilot 는 다음과 같이 테스트 도구 모음을 생성합니다.\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\n생성된 코드를 새 파일 `test_bank_account_integration.py`에 추가합니다.\n\n### 테스트 사례 개선\n\n위의 프롬프트는 `NotificationSystem`이(가) 유효한 입금이 이루어질 때 호출되는 것을 확인하는 단일 테스트 사례를 생성했습니다. 그러나 입금 중에 오류가 발생하는 경우는 다루지 않습니다. 이러한 시나리오에서는 `NotificationSystem`을(를) 호출하면 안 됩니다. 잘못된 예금을 처리하는 테스트 사례를 추가하고 알림 시스템이 트리거되지 않도록 해야 합니다.\n\n**프롬프트:***\"함수가 올바른 예외를 발생시키고 `NotificationService`이(가) 호출되지 않는지 확인하기 위해 잘못된 입금 금액에 대한 테스트 사례를 추가합니다.\"*\n\nCopilot 는 다음과 같은 테스트 사례를 생성합니다.\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### 개선 영역에 대한 질문\n\n이제 예금에 대한 통합 기능의 유효성을 검사하기 위해 테스트 사례를 작성했으므로 테스트 도구 모음 내에서 향상된 기능을 검색할 수 있는 좋은 기회입니다. 현재 테스트가 정상적으로 작동하더라도 Copilot에 코드 커버리지를 평가하고 개선이 필요한 부분을 제안하도록 요청할 수 있습니다.\n\n**프롬프트:***\"`BankAccount` 클래스와 `NotificationSystem` 간의 통합에 대한 전체 검사를 보장하기 위해 어떤 추가 테스트를 포함해야 하나요?\"*\n\n이 질문으로 Copilot에 메시지를 표시하면 간과되었을 수 있는 누락된 테스트 사례를 식별하는 데 도움이 될 수 있습니다.\n이 경우 유효하고 잘못된 예금을 테스트하는 동안 아직 인출 기능을 다루지 않았습니다.\n\nCopilot 는 다음과 같이 업데이트된 테스트 제품군을 생성합니다.\n\n<details>\n  <summary>전체 생성된 코드 예제를 확장하려면 클릭</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\nCopilot이 만족도에 맞게 테스트 제품군을 생성한 후에는 아래 명령을 사용하여 테스트를 실행하여 결과를 확인합니다.\n\n```bash\npython -m unittest test_bank_account_integration.py\n```\n\n## 테스트 제안을 개선하는 데 사용 Copilot Spaces\n\nCopilot Spaces 는 작업별 컨텍스트를 구성하고 공유할 수 있는 기능입니다 Copilot. 이렇게 하면 사용자가 받는 제안의 관련성을 개선하는 데 도움이 됩니다. 프로젝트에 대한 더 많은 컨텍스트를 Copilot 제공하면 더 나은 테스트 제안을 얻을 수 있습니다.\n\n예를 들어, 다음과 같은 항목을 포함하는 Space를 만들 수 있습니다.\n\n* 테스트 중인 모듈(예: `payments.js`)\n* 현재 테스트 도구 모음(예: `payments.test.js`)\n* 누락된 항목에 대한 테스트 검사 보고서 또는 메모\n\n이 공간에서 Copilot 다음과 같은 질문을 할 수 있습니다:\n\n> `payments.test.js`의 논리를 기반으로 `payments.js`에서 어떤 테스트 사례가 누락되었어?\n\n또는\n\n> 기존 테스트 도구 모음의 구조를 따르면서 `refund.js`의 환불 논리에 대한 단위 테스트를 작성해줘.\n\n사용에 Copilot Spaces대한 자세한 내용은 [GitHub Copilot 스페이스 정보](/ko/enterprise-cloud@latest/copilot/concepts/context/spaces)을 참조하세요."}