Меню Закрити

Десять простих кроків для створення успішного Python-проекту

Як додати тести, CI та багато іншого розповідає Jeff Hale

У цій статті ми розглянемо покриття коду тестами та організацію неперервної інтеграції для прискорення розробки, поліпшення якості та цілістності коду.

Ось план із десяти кроків:

  1. Встановити Black.
  2. Створити .pycache.
  3. Встановити pytest.
  4. Створити тести.
  5. Зареєструватися на Travis CI.
  6. Створити .travis.yaml.
  7. Тестувати Travis CI.
  8. Додати звіт про покриття коду тестами.
  9. Додати Coveralls.
  10. Додати PyUp.

Всі дії були проведені і перевірені на MacOS із Python 3.7. Але для інших версій середовища все повинно працювати аналогічно.

Крок 1. Встановити Black

 

Код пакета повинен відповідати загальним вимогам стилю. Black — це пакет Python, який автоматично форматує код, щоб він відповідав PEP 8. Black ще є бетою, але вже має понад мільйон завантажень. Його використання швидко стало передовою практикою в програмуванні на Python. Ось непоганий посібник із Black.

Я використовую Atom в якості редактора коду, тому додав програмний пакет Python-Black до Atom, інформація про встановлення тут. Тепер, коли ви зберігаєте файл, Atom переформатує код.

Поки ми працюємо над цим, додаймо Black до середовища розробки для наших співробітників. Зрештою,

Додайте black==18.9b0 в requirements_dev.txt і запустіть pip install -r requirements_dev.txt. щоб кожен, хто працює над проектом, дотримувався єдиного стилю.

У Black довжина лінії за замовчуванням становить 88 символів. Деякі посібники та програми вимагають 79 символів, наприклад посібник зі Sphinx style. У пакеті Black Atom можна встановити максимальну довжину.

Крок 2. Створити .pypirc

Коли ми використовуємо twine, щоб вигрузити наші поточні версії програм до TestPyPI і PyPI, нам потрібно вручну вводити дані для входу. Автоматизуймо цей процес.

Twine матиме вигляд файлу з ім’ям .pypirc у нашій домашній директорії. Під час вигрузки нашого пакету він подбає про наш URL, логін і пароль.

Створіть ваш файл .pypirc у домашній директорії за допомогою:

touch ~/.pypirc

Додайте такий вміст до файлу .pypirc:

[distutils]
index-servers =
    pypi
    testpypi

[testpypi]
repository: https://test.pypi.org/legacy
username = your_username
password = your_pypitest_password

[pypi]
username = your_username
password = your_pypi_password

Замініть ім’я користувача та паролі на свої. Переконайтеся, що цей файл збережено у вашій домашній директорії, а не в поточній робочій. Якщо хочете бути певними, що інші користувачі на вашому комп’ютері не одержать доступу до цього файлу, можна змінити його дозволи з командного рядка:

chmod 600 ~/.pypirc

Тепер ви можете вигрузити свій пакет у TestPyPI за допомогою такої команди:

twine upload -r testpypi dist/*

Продакшен версію можна вигрузити так:

twine upload dist/*

Тепер додамо тести, щоб переконатися, що наш пакет працює.

Крок 3. Встановити та налаштувати pytest

Pytest – найпопулярніша бібліотека для тестування Python-коду. У цьому прикладі ми додамо прості тести до проекту.

Додайте файл pytest у ваш файл requirements_dev.txt

pytest==4.3.0

Запустіть pip install requirements_dev.txt

Потім виконайте такі дії, щоб pytest міг знайти ваш пакет:

pip install -e .

Якщо вимкнути віртуальне середовище, потрібно знову запустити обидві pip команди, щоб запустити тести.

Крок 4. Створіть тести

Додайте папку tests у корінь вашого проекту. Додайте в неї файл з ім’ям test_your_package_name.py. Мій файл називається test_notebookc.py. Якщо ім’я файлу починається з test_ він автоматично запускається з pytest.

У test_notebookc.pyя додав такий тест, щоб перевірити, чи правильне ім’я друкується як частина функції виводу. Замініть на власні імена файлів і функцій відповідно.

"""Tests for `notebookc` package."""
import pytest
from notebookc import notebookc
def test_convert(capsys):
      """Correct my_name argument prints"""
      notebookc.convert("Jill")
      captured = capsys.readouterr()
      assert "Jall" in captured.out

Що тут відбувається?

Спочатку імпортуємо наш модуль. Потім ми створюємо функцію з іменем за шаблоном test_my_function_name. Ця угода про іменування (коли тестова функція починається зі слова test, а далі за роздільником нижного підкреслення йде назва функції що тестується) буде зрозуміла усім тим, хто буде працювати з вашим кодом.

Потім ми викликаємо нашу функцію з аргументом Jill. Після цього зафіксуємо результат. Наша функція convert є дуже простою — вона приймає параметр my_name і виводить рядок:

print(f”I’ll convert a notebook for you some day, {my_name}.”)

Pytest перевіряє, чи є рядок “Jall” у виведеному результаті. Він не повинен там бути, тому що ми передали у функцію “Jill”.

Запустіть тест, ввівши pytest в командному рядку. Тест має вийти із червоним текстом.

Це дасть змогу переконатися, що ваші тести провалилися, коли й мають. Не пишіть їх так, щоб вони одразу стали зеленими. Інакше ваші тести можуть тестувати не те, що вам потрібно.😉

Після того, як ми одержали невдалий тест, зможемо змінити очікуваний результат від Jallдо Jill, і наші тести мають забарвитися в зелений колір.

Так, усе добре. Тепер ми маємо тест, який гарантує, що коли хтось передає значення нашій функції, це значення виводиться на екран.

Додамо тест, щоб переконатися, що до нашої функції може бути передано лише рядок. Якщо передається щось, окрім рядка, слід ініцювати TypeError. Ось хороший посібник про винятки та обробку помилок у Python.

Коли ми пишемо тест до написання коду, ми здійснюємо розробку через тестування (TDD). TDD — це перевірений метод написання коду з меншою кількістю помилок. Ось добра стаття про TDD.

Крок 5. Зареєструйтеся у Travis CI та Configure

Travis CI — це “сервіс неперервної інтеграції, який використовується для побудови та тестування програмного забезпечення”. Нещодавно її придбала компанія Idera. Є й інші варіанти CI, але Travis CI популярна, опенсорсна й добре документована.

Travis CI дає можливість упевнитися, що у ваш проект інтегровано лише код, який передає ваші тести та стандарти. Дізнайтеся більше про Travis CI і більше про неперервну інтеграцію.

Зареєструйтеся на сайті travis-ci.org. Натисніть Review and add your authorized organizations на сторінці профілю Travis CI. Вам буде запропоновано ввести пароль GitHub. Натисніть Grant  біля Organization access..

Мені довелося синхронізувати мій обліковий запис notebooktoall, щоб показати його як організацію й щоб з’явився репозиторій notebookc. Зазвичай потрібна хвилина або більше, щоб дані почали передаватися. Потім перемкніть репозиторій на on (положення ввімкнення).

Натисніть settings (налаштування). Ви можете вибрати, чи хочете, щоб Travis створював  pushed pull requests (запити на включення коду) та/або pushed branches.

Тепер нам потрібно зробити локальні налаштування.

Крок 6. Створити .travis.yml

У корінь проекту додайте файл .travis.yml із таким вмістом:

dist: xenial
language: python
python: 3.7.2
install:
  - pip install -r requirements_dev.txt
  - pip install -e .
script:
  - pytest

dist: xenialпотрібний для вказівки, що Travis має використовувати Ubuntu Xenial 16.04 для свого віртуального середовища. Xenial повинен бути вказаний для тестування коду Python 3.7. Більше інформації тут.

Розділ install забезпечує встановлення наших пакетів для розробки. pip install -e . встановлює ваш пакет у віртуальному середовищі Travis. Тоді Travis знайде ваш пакет, коли він запустить pytest.

Крок 7. Тестувати Travis CI

Внесіть свої зміни, натисніть GitHub та зробіть pull request. Travis має запрацювати автоматично протягом кількох секунд.

Ось що робить Travis.

Travis повідомить вам, якщо ваш PR невдалий.

Зауважте, якщо pull request невдалий, ви можете натиснути на ту ж гілку й Travis автоматично перезавантажиться.

Перейдіть на вашу сторінку  репозиторія Travis і ознайомтесь з нею. Напевно, у майбутньому ви будете часто відвідувати цей сайт, намагаючись зрозуміти, чому ваша збірка не пройшла. 😄

Припускаємо, що все зелене, та рухаємося далі!

Якщо ви не бачите ні червоного, ні зеленого кольору, натисніть меню More options (Додаткові параметри) та виберіть Requests у меню, що розкривається. Якщо бачите червоний, перегляньте повідомлення про помилки. Якщо бачите помилку Build configuration file, то Travis не знаходить ваш файл .travis.yml на GitHub. Переконайтеся, що він міститься у вашому GitHub репозиторії.  😉

Travis надсилає вам повідомлення електронною поштою, щоб сповістити про невдалу збірку.

Крок 8. Додайте звіт про покриття коду тестами

Звіт про покриття коду показує, який відсоток коду має покриття тестами. Ми додамо пакет pytest-cov для створення звіту.

Додайте такий рядок до requirements_dev.txt:

pytest-cov==2.6.1

Запустіть за допомогою команди pytest --cov=my_project_name

 

Мій результат pytest --cov=notebookc має такий вигляд:

Дорогенькі, увесь наш код покритий! Якщо у вас є лише кілька рядків, це не високе досягнення. 😄 Але нам не потрібно розповідати про це світові — покажемо їм, що в нас є покриття!

Крок 9. Додайте Coveralls

Coveralls дають можливість усьому світові бачити історію покриття вашого коду.

 

Перейдіть до https://coveralls.io/ та зареєструйте обліковий запис, використовуючи дані вашого акаунта GitHub. Додайте свою організацію та ввімкніть репозиторій, коли з’явиться.

У requirements_dev.txt додайте coveralls==1.6.0. Ваші requirements_dev.txt тепер повинні мати такий вигляд:

pip==19.0.3
wheel==0.33.0
twine==1.13.0
pytest==4.3.0
pytest-cov==2.6.1
coveralls==1.6.0

Змініть файл .travis.yml так, щоб у нього був такий вигляд (підставляючи ім’я вашого пакета):

dist: xenial
language: python
python: 3.7.2
install:
  — pip install -r requirements_dev.txt
  — pip install -e .
script:
  — pytest --cov=my_package_name
after_success:
  — coveralls

Тепер, коли Travis будує ваш проект, він встановить потрібні пакети, запустить тести й створить звіт про покриття. Потім він надсилає звіт про покриття для coveralls.

Створюйте, натискайте на GitHub і дивіться, як відбувається магія. Це може тривати кілька хвилин, поки звіт про покриття надійде, тому наберіться терпіння.

Тепер coveralls показує у ваших PR checks. Круто!

На веб-сторінці “Coveralls” ми повинні показати 100% покриття.

Гаразд, додамо ще один інструмент до нашого набору.

Крок 10. Додайте PyUp

PyUpo дає змогу дізнатися, коли залежності пакетів застаріли або мають уразливості безпеки. Він автоматично робить запит (pull request) для оновлення пакета на GitHub.

Перейдіть на сторінку https://pyup.io/, зареєструйтеся через GitHub та підключіть вашу організацію.

Коли ви додаєте репозиторій, я пропоную вам увімкнути Update Schedules на щотижневе оновлення (Every week). Тоді ви не одержите велику кількість запитів (pull requests), якщо у вас є багато залежностей пакетів.

Ось приклад репозиторій на PyUp, який показує деякі застарілі пакети.

Тепер ви знатимете, коли пакет оновлено, а знання — це половина битви. Автоматизовані запити (pull requests) повинні бути іншою половиною, чи не так?  😏

Підсумки

Із цієї статті ви дізналися, як додати та налаштувати Black, pytest, Travis CI, Coveralls та PyUp. Ми створили основу для безпечнішого коду з більш узгодженим стилем. Це досить класно!

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

0

Повідомити про помилку

Текст, який буде надіслано нашим редакторам: