Как интегрировать проверку readme в pytest
Я использую pytest
в своем .Трэвис.в формате YML чтобы проверить мой код.
Я хотел бы проверить README.и первый тоже.
нашел readme_renderer через этот StackO ответ
теперь я спрашиваю себя, как интегрировать это в мой текущий тесты.
документы readme_renderer предлагают это, но я не знаю, как интегрировать это в мою настройку:
python setup.py check -r -s
4 ответов
Я думаю, что самый простой и надежный вариант-написать плагин pytest, который реплицирует то, что команда distutils вы упомянули в своем ответе.
Это может быть как простой, как conftest.py в тестовом реж. Или если вы хотите автономный плагин, который распространяется для всех нас, чтобы извлечь выгоду из того, что есть хороший шаблон cookiecutter.
Ofc по своей сути нет ничего плохого в вызове проверки вручную ваш раздел сценария после вызова pytest.
Я проверяю это так:
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals, print_function
import os
import subx
import unittest
class Test(unittest.TestCase):
def test_readme_rst_valid(self):
base_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
subx.call(cmd=['python', os.path.join(base_dir, 'setup.py'), 'check', '--metadata', '--restructuredtext', '--strict'])
источник:https://github.com/guettli/reprec/blob/master/reprec/tests/test_setup.py
поэтому я реализовал что-то, но это требует некоторых изменений. Вам нужно изменить свой setup.py
ниже
from distutils.core import setup
setup_info = dict(
name='so1',
version='',
packages=[''],
url='',
license='',
author='tarun.lalwani',
author_email='',
description=''
)
if __name__ == "__main__":
setup(**setup_info)
тогда вам нужно создать символическую ссылку, чтобы мы могли импортировать этот пакет в тест
ln -s setup.py setup_mypackage.py
и затем вы можете создать тест, как показано ниже
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals, print_function
import os
import unittest
from distutils.command.check import check
from distutils.dist import Distribution
import setup_mypackage
class Test(unittest.TestCase):
def test_readme_rst_valid(self):
dist = Distribution(setup_mypackage.setup_info)
test = check(dist)
test.ensure_finalized()
test.metadata = True
test.strict = True
test.restructuredtext = True
global issues
issues = []
def my_warn(msg):
global issues
issues += [msg]
test.warn = my_warn
test.check_metadata()
test.check_restructuredtext()
if len(issues) > 0:
assert len(issues) == 0, "\n".join(issues)
запуск теста, то я получаю
...
AssertionError: missing required meta-data: version, url
missing meta-data: if 'author' supplied, 'author_email' must be supplied too
Ran 1 test in 0.067s
FAILED (failures=1)
Это один из возможных обходных путей, который я могу придумать
Upvoted, потому что проверка консистенции readme-хорошая вещь, которую я никогда не интегрировал в свои собственные проекты. Сделаем теперь!
я думаю, ваш подход с вызовом check
команда в порядке, хотя она будет проверять больше, чем разметка readme. check
проверит полные метаданные вашего пакета, включая readme, если у вас есть readme_renderer
установлен.
если вы хотите написать модульный тест, который делает только проверку разметки и ничего больше, я бы пошел с явный вызов readme_renderer.rst.render
:
import pathlib
from readme_renderer.rst import render
def test_markup_is_generated():
readme = pathlib.Path('README.rst')
assert render(readme.read_text()) is not None
на None
проверка является самым основным тестом: если render
возвращает None
, это означает, что readme содержит ошибки, препятствующие его переводу в HTML. Если вам нужны более мелкие тесты, работайте с возвращенной строкой HTML. Например, я ожидаю, что мой readme будет содержать слово "extensions", которое будет подчеркнуто:
import pathlib
import bs4
from readme_renderer.rst import render
def test_extensions_is_emphasized():
readme = pathlib.Path('README.rst')
html = render(readme.read_text())
soup = bs4.BeautifulSoup(html)
assert soup.find_all('em', string='extensions')
редактировать: если вы хотите увидеть напечатанные предупреждения, использовать дополнительный :
from io import StringIO
def test_markup_is_generated():
warnings = StringIO()
with open('README.rst') as f:
html = render(f.read(), stream=warnings)
warnings.seek(0)
assert html is not None, warnings.read()
пример вывода:
tests/test_readme.py::test_markup_is_generated FAILED
================ FAILURES ================
________ test_markup_is_generated ________
def test_markup_is_generated():
warnings = StringIO()
with open('README.rst') as f:
html = render(f.read(), stream=warnings)
warnings.seek(0)
> assert html is not None, warnings.read()
E AssertionError: <string>:54: (WARNING/2) Title overline too short.
E
E ----
E fffffff
E ----
E
E assert None is not None
tests/test_readme.py:10: AssertionError
======== 1 failed in 0.26 seconds ========