{"meta":{"title":"Написание тестов с помощью GitHub Copilot","intro":"Используйте Copilot для создания модульных и интеграции тестов и повышения качества кода.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ru/copilot","title":"GitHub Copilot"},{"href":"/ru/copilot/tutorials","title":"Учебники"},{"href":"/ru/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* A [GitHub Copilot подписочный план](/ru/copilot/about-github-copilot/subscription-plans-for-github-copilot).\n* Visual Studio, Visual Studio Codeили любой интегрированной среды разработки JetBrains.\n* Расширение [GitHub Copilot](/ru/copilot/managing-copilot/configure-personal-settings/installing-the-github-copilot-extension-in-your-environment) установлено в вашем IDE.\n\n## Написание модульных тестов с помощью Копилот Чат\n\nВ этом разделе мы рассмотрим, как использовать Чат GitHub Copilot для создания модульных тестов для класса 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### Создание модульных тестов с помощью Копилот Чат\n\nВы можете запросить Copilot с запросом на запись тестов, охватывающих ряд сценариев. Будьте конкретными с требованиями к тесту, чтобы получить наилучшие результаты. Ниже приведен пример запроса, который можно использовать для создания модульных `BankAccount` тестов для класса.\n\n```\n          **Запрос.**_Разработка комплексного набора модульных тестов для функции BankAccount() в Python. Создание нескольких методов тестирования, охватывающих широкий спектр сценариев, включая пограничные случаи, обработку исключений и проверку данных._\n```\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```\n          **Prompt:**_\"How do I запускать эти модульные тесты на Python с использованием фреймворка unittest?\"_\n```\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 с полезным контекстом, открыв один или несколько существующих файлов тестов на смежных вкладках в редакторе. 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```\n          `BankAccount` Обновите класс в файле с помощью следующего `bank_account.py` фрагмента кода.\n```\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```\n          **Запрос:**_\"Написание тестов интеграции для функции в `deposit` классе. Используйте макеты для `BankAccount` имитации `NotificationSystem` и проверки правильности вызова после депозита\"._\n```\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```\n          **Запрос:**_\"Добавьте тестовый случай для недопустимых сумм депозита, чтобы убедиться, что функция вызывает правильные исключения и не `NotificationService` вызывается\"._\n```\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```\n          **Запрос:**_\"Какие дополнительные тесты следует включить, чтобы обеспечить полное покрытие интеграции между классом `BankAccount` и `NotificationSystem`?\"_\n```\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## Использование Пространства второпилотов для улучшения вариантов тестирования\n\nПространства второпилотов — это функция, которая позволяет упорядочивать и предоставлять общий доступ к контексту для конкретной задачи с помощью Copilot. Это поможет улучшить релевантность получаемых предложений. Предоставив Copilot больше контекста о вашем project, вы сможете получить лучшие рекомендации по тестированию.\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Для получения дополнительной информации об использовании Пространства второпилотов см. [О GitHub Copilot Spaces](/ru/copilot/using-github-copilot/copilot-spaces/about-organizing-and-sharing-context-with-copilot-spaces)."}