Как интегрировать проверку 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 ========