{"meta":{"title":"Написание тестов с помощью GitHub Copilot","intro":"Используется Copilot для создания модульных и интеграции тестов и помогает улучшить качество кода.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ru/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/ru/enterprise-cloud@latest/copilot/tutorials","title":"Учебники"},{"href":"/ru/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Прежде чем getting started, у вас должны быть следующее:\n\n* [\n  GitHub Copilot Подписка](/ru/enterprise-cloud@latest/copilot/get-started/plans).\n* Visual Studio, Visual Studio Codeили любой интегрированной среды разработки JetBrains.\n* Расширение, установленное в интегрированной [GitHub Copilot](/ru/enterprise-cloud@latest/copilot/how-tos/set-up/install-copilot-extension) среде разработки.\n\n## Написание модульных тестов с помощью Copilot Chat\n\nВ этом разделе мы рассмотрим, как создавать GitHub Copilot Chat модульные тесты для класса Python. В этом примере показано, как можно использовать Copilot для создания модульных тестов для класса, например `BankAccount`. Мы покажем, как запрашивать Copilot создание тестов, выполнять их и проверять результаты.\n\n### Пример класса: `BankAccount`\n\nНачнем с класса `BankAccount` , содержащего методы для депозита, вывода и получения баланса учетной записи. Создайте файл `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\nВы можете запросить Copilot с запросом на запись тестов, охватывающих ряд сценариев. Будьте конкретными с требованиями к тесту, чтобы получить наилучшие результаты. Ниже приведен пример запроса, который можно использовать для создания модульных `BankAccount` тестов для класса.\n\n**Запрос.***Разработка комплексного набора модульных тестов для функции BankAccount() в Python. Создание нескольких методов тестирования, охватывающих широкий спектр сценариев, включая пограничные случаи, обработку исключений и проверку данных.*\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 тестового случая для каждого сценария, указанного в запросе. Каждая функция в `BankAccount` классе проверяется для ряда условий, включая допустимые операции, такие как депозиты и вывод, а также пограничные случаи, такие как отрицательные суммы и попытки снять больше, чем доступный баланс.\n\nПосле Copilot создания набора тестов для удовлетворения добавьте код в новый файл `test_bank_account.py`. Вы можете спросить его, как выполнить тесты.\n\n**Prompt:***\"How do I запускать эти модульные тесты на Python с использованием фреймворка unittest?\"*\n\nCopilot присвойте следующей команде bash.\n\n```bash\npython -m unittest test_bank_account.py\n```\n\nПосле выполнения тестов вы увидите выходные данные в терминале или интегрированной среде разработки. Если все тесты проходят, вы можете быть уверены, что ваш `BankAccount` класс работает должным образом.\n\n#### Команда с косой чертой\n\nКроме того, можно заставить Copilot написать полный набор модульных тестов с помощью команды косой `/tests` черты. Убедитесь, что файл открыт на текущей вкладке интегрированной среды разработки и 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### Пример класса: `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\nПосле того как Copilot создал набор тестов для удовлетворения, выполните тесты с помощью команды ниже, чтобы проверить результаты.\n\n```bash\npython -m unittest test_bank_account_integration.py\n```\n\n## Использование Copilot Spaces для улучшения вариантов тестирования\n\nCopilot Spaces — это функция, которая позволяет упорядочивать и предоставлять общий доступ к Copilotконтексту для конкретной задачи. Это поможет улучшить релевантность получаемых предложений. Предоставляя Copilot дополнительные сведения о проекте, вы можете получить лучшие варианты тестирования.\n\nНапример, можно создать пространство, включающее:\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 Spaces](/ru/enterprise-cloud@latest/copilot/concepts/context/spaces)."}