diff --git a/.github/workflows/run-checks.yml b/.github/workflows/run-checks.yml index 298d118..79034ac 100644 --- a/.github/workflows/run-checks.yml +++ b/.github/workflows/run-checks.yml @@ -17,22 +17,14 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - include: - - environment: "py36" - python: "3.6" - - environment: "py37" - python: "3.7" - - environment: "py38" - python: "3.8" + python: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - name: Install tox - run: | - python -m pip install --upgrade pip - python -m pip install tox + run: pip install tox - name: Run tox run: tox -e py diff --git a/README.md b/README.md index d7f536c..4b17ce5 100644 --- a/README.md +++ b/README.md @@ -47,21 +47,21 @@ There you go - you just created a minimal pytest plugin: pytest-awesome/ ├── LICENSE ├── README.rst -├── docs -│   └── index.md -├── mkdocs.yml -├── pytest_awesome.py -├── setup.py +├── pyproject.toml +├── src +│ └── pytest_awesome +│ ├── __init__.py +│ └── plugin.py ├── tests -│   ├── conftest.py -│   └── test_awesome.py +│ ├── conftest.py +│ └── test_awesome.py └── tox.ini ``` ## Features -- Installable [PyPI] package featuring a `setup.py`. +- Installable [PyPI] package featuring a `pyproject.toml`. - Test suite running [tox] and [pytest] that makes sure your plugin is working as expected - Working example code for a fixture, a cli option, as well as a pytest.ini @@ -78,15 +78,13 @@ pytest-awesome/ If you plan on submitting your plugin to the [pytest-dev organization] you need to meet the following requirements: -- PyPI presence with a setup.py that contains a license, pytest- +- PyPI presence with a pyproject.toml that contains a license, pytest- prefixed, version number, authors, short and long description. - a tox.ini for running tests using tox. - a README describing how to use the plugin and on which platforms it runs. -- a LICENSE file or equivalent containing the licensing information, - with matching info in setup.py. -- an issue tracker unless you rather want to use the core pytest - issue tracker. +- a LICENSE file or equivalent containing the licensing information. +- an issue tracker Please see the official guidelines at [Submit a Plugin]. diff --git a/cookiecutter.json b/cookiecutter.json index 8c19c77..61cbb8e 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -6,7 +6,7 @@ "module_name": "{{ cookiecutter.plugin_name|lower|replace('-', '_') }}", "short_description": "A simple plugin to use with pytest", "version": "0.1.0", - "pytest_version": "3.5.0", + "pytest_version": "6.2.0", "docs_tool": [ "mkdocs", "sphinx", diff --git a/docs/user-guide/publish-plugin.md b/docs/user-guide/publish-plugin.md index 8f2cc88..7900805 100644 --- a/docs/user-guide/publish-plugin.md +++ b/docs/user-guide/publish-plugin.md @@ -6,8 +6,7 @@ Essentially pytest plugins are not different from any other Python Package, so you may want to create a distribution and submit it to the Python Package Index ([PyPI]). -By doing so, enables your users to easily install via ``easy-install`` or -``pip``. +By doing so, enables your users to easily install via ``pip``. ## Python Package Index @@ -24,15 +23,13 @@ Please see the official [Python Packaging User Guide] for detailed information. If you plan on submitting your plugin to the [pytest-dev organization] you need to meet the following requirements: -- PyPI presence with a setup.py that contains a license, pytest- +- PyPI presence with a pyproject.toml that contains a license, pytest- prefixed, version number, authors, short and long description. - a tox.ini for running tests using tox. - a README describing how to use the plugin and on which platforms it runs. -- a LICENSE file or equivalent containing the licensing information, - with matching info in setup.py. -- an issue tracker unless you rather want to use the core pytest - issue tracker. +- a LICENSE file or equivalent containing the licensing information. +- an issue tracker. Please see the official guidelines at [Submit a Plugin]. diff --git a/docs/user-guide/quickstart.md b/docs/user-guide/quickstart.md index 6848698..197fd96 100644 --- a/docs/user-guide/quickstart.md +++ b/docs/user-guide/quickstart.md @@ -53,11 +53,14 @@ Once you answered to the questions, Cookiecutter renders the the project: pytest-awesome/ ├── LICENSE ├── README.rst -├── pytest_awesome.py -├── setup.py +├── pyproject.toml +├── src +│ └── pytest_awesome +│ ├── __init__.py +│ └── plugin.py ├── tests -│   ├── conftest.py -│   └── test_awesome.py +│ ├── conftest.py +│ └── test_awesome.py └── tox.ini ``` diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index a300dd3..e93cf0c 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import logging import os diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index 6f61736..283d67e 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- import logging import re diff --git a/pytest-{{cookiecutter.plugin_name}}/MANIFEST.in b/pytest-{{cookiecutter.plugin_name}}/MANIFEST.in deleted file mode 100644 index 1ade348..0000000 --- a/pytest-{{cookiecutter.plugin_name}}/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include LICENSE -include README.rst - -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] diff --git a/pytest-{{cookiecutter.plugin_name}}/appveyor.yml b/pytest-{{cookiecutter.plugin_name}}/appveyor.yml index 61bdd15..f22b384 100644 --- a/pytest-{{cookiecutter.plugin_name}}/appveyor.yml +++ b/pytest-{{cookiecutter.plugin_name}}/appveyor.yml @@ -1,40 +1,20 @@ -# What Python version is installed where: -# https://www.appveyor.com/docs/build-environment/#python +# https://www.appveyor.com/docs/lang/python/ +--- +image: + - Visual Studio 2019 environment: matrix: - - PYTHON: "C:\\Python35" - TOX_ENV: "py35" + - TOXENV: "py38" + - TOXENV: "py39" + - TOXENV: "py310" + - TOXENV: "py311" + - TOXENV: "py312" - - PYTHON: "C:\\Python36" - TOX_ENV: "py36" - - - PYTHON: "C:\\Python37" - TOX_ENV: "py37" - - - PYTHON: "C:\\Python38" - TOX_ENV: "py38" - -init: - - "%PYTHON%/python -V" - - "%PYTHON%/python -c \"import struct;print( 8 * struct.calcsize(\'P\'))\"" +build: false install: - - "%PYTHON%/Scripts/easy_install -U pip" - - "%PYTHON%/Scripts/pip install tox" - - "%PYTHON%/Scripts/pip install wheel" - -build: false # Not a C# project, build stuff at the test step instead. + - py -m pip install tox test_script: - - "%PYTHON%/Scripts/tox -e %TOX_ENV%" - -after_test: - - "%PYTHON%/python setup.py bdist_wheel" - - ps: "ls dist" - -artifacts: - - path: dist\* - -#on_success: -# - TODO: upload the content of dist/*.whl to a public wheelhouse + - py -m tox diff --git a/pytest-{{cookiecutter.plugin_name}}/docs_sources/sphinx/conf.py b/pytest-{{cookiecutter.plugin_name}}/docs_sources/sphinx/conf.py index c334c03..4cb65f7 100644 --- a/pytest-{{cookiecutter.plugin_name}}/docs_sources/sphinx/conf.py +++ b/pytest-{{cookiecutter.plugin_name}}/docs_sources/sphinx/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # pytest-{{cookiecutter.plugin_name}} documentation build configuration file, created by # sphinx-quickstart on Thu Oct 1 00:43:18 2015. # diff --git a/pytest-{{cookiecutter.plugin_name}}/pyproject.toml b/pytest-{{cookiecutter.plugin_name}}/pyproject.toml new file mode 100644 index 0000000..c48c057 --- /dev/null +++ b/pytest-{{cookiecutter.plugin_name}}/pyproject.toml @@ -0,0 +1,53 @@ +[build-system] +requires = [ + "setuptools>=61.0.0", +] +build-backend = "setuptools.build_meta" + +[project] +name = "pytest-{{cookiecutter.plugin_name}}" +description = "{{cookiecutter.short_description}}" +version = "{{cookiecutter.version}}" +readme = "README.rst" +requires-python = ">=3.8" +authors = [ + { name = "{{cookiecutter.full_name}}", email = "{{cookiecutter.email}}" }, +] +maintainers = [ + { name = "{{cookiecutter.full_name}}", email = "{{cookiecutter.email}}" }, +] +license = {file = "LICENSE"} +classifiers = [ + "Framework :: Pytest", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Topic :: Software Development :: Testing", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + {% if cookiecutter.license == "MIT" -%} + "License :: OSI Approved :: MIT License", + {%- elif cookiecutter.license == "BSD-3" -%} + "License :: OSI Approved :: BSD License", + {%- elif cookiecutter.license == "GNU GPL v3.0+" -%} + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + {%- elif cookiecutter.license == "Apache Software License 2.0" -%} + "License :: OSI Approved :: Apache Software License", + {%- elif cookiecutter.license == "Mozilla Public License 2.0" -%} + "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", + {%- endif %} +] +dependencies = [ + "pytest>={{cookiecutter.pytest_version}}", +] +[project.urls] +Repository = "https://github.com/{{cookiecutter.github_username}}/pytest-{{cookiecutter.plugin_name}}" +[project.entry-points.pytest11] +django = "pytest_{{cookiecutter.module_name}}.plugin" diff --git a/pytest-{{cookiecutter.plugin_name}}/setup.py b/pytest-{{cookiecutter.plugin_name}}/setup.py deleted file mode 100644 index efa9ee6..0000000 --- a/pytest-{{cookiecutter.plugin_name}}/setup.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import os -import codecs -from setuptools import setup - - -def read(fname): - file_path = os.path.join(os.path.dirname(__file__), fname) - return codecs.open(file_path, encoding='utf-8').read() - - -setup( - name='pytest-{{cookiecutter.plugin_name}}', - version='{{cookiecutter.version}}', - author='{{cookiecutter.full_name}}', - author_email='{{cookiecutter.email}}', - maintainer='{{cookiecutter.full_name}}', - maintainer_email='{{cookiecutter.email}}', - license='{{cookiecutter.license}}', - url='https://github.com/{{cookiecutter.github_username}}/pytest-{{cookiecutter.plugin_name}}', - description='{{cookiecutter.short_description}}', - long_description=read('README.rst'), - py_modules=['pytest_{{cookiecutter.module_name}}'], - python_requires='>=3.5', - install_requires=['pytest>={{cookiecutter.pytest_version}}'], - classifiers=[ - 'Development Status :: 4 - Beta', - 'Framework :: Pytest', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Testing', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy', - 'Operating System :: OS Independent', - {% if cookiecutter.license == "MIT" -%} - 'License :: OSI Approved :: MIT License', - {%- elif cookiecutter.license == "BSD-3" -%} - 'License :: OSI Approved :: BSD License', - {%- elif cookiecutter.license == "GNU GPL v3.0+" -%} - 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', - {%- elif cookiecutter.license == "Apache Software License 2.0" -%} - 'License :: OSI Approved :: Apache Software License', - {%- elif cookiecutter.license == "Mozilla Public License 2.0" -%} - 'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)', - {%- endif %} - ], - entry_points={ - 'pytest11': [ - '{{cookiecutter.plugin_name}} = pytest_{{cookiecutter.module_name}}', - ], - }, -) diff --git a/pytest-{{cookiecutter.plugin_name}}/src/pytest_{{cookiecutter.module_name}}/__init__.py b/pytest-{{cookiecutter.plugin_name}}/src/pytest_{{cookiecutter.module_name}}/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pytest-{{cookiecutter.plugin_name}}/pytest_{{cookiecutter.module_name}}.py b/pytest-{{cookiecutter.plugin_name}}/src/pytest_{{cookiecutter.module_name}}/plugin.py similarity index 94% rename from pytest-{{cookiecutter.plugin_name}}/pytest_{{cookiecutter.module_name}}.py rename to pytest-{{cookiecutter.plugin_name}}/src/pytest_{{cookiecutter.module_name}}/plugin.py index 4b95f95..48bce20 100644 --- a/pytest-{{cookiecutter.plugin_name}}/pytest_{{cookiecutter.module_name}}.py +++ b/pytest-{{cookiecutter.plugin_name}}/src/pytest_{{cookiecutter.module_name}}/plugin.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import pytest diff --git a/pytest-{{cookiecutter.plugin_name}}/tests/test_{{cookiecutter.module_name}}.py b/pytest-{{cookiecutter.plugin_name}}/tests/test_{{cookiecutter.module_name}}.py index 6fcfb4b..1600368 100644 --- a/pytest-{{cookiecutter.plugin_name}}/tests/test_{{cookiecutter.module_name}}.py +++ b/pytest-{{cookiecutter.plugin_name}}/tests/test_{{cookiecutter.module_name}}.py @@ -1,17 +1,14 @@ -# -*- coding: utf-8 -*- - - -def test_bar_fixture(testdir): +def test_bar_fixture(pytester): """Make sure that pytest accepts our fixture.""" # create a temporary pytest test module - testdir.makepyfile(""" + pytester.makepyfile(""" def test_sth(bar): assert bar == "europython2015" """) # run pytest with the following cmd args - result = testdir.runpytest( + result = pytester.runpytest( '--foo=europython2015', '-v' ) @@ -25,8 +22,8 @@ def test_sth(bar): assert result.ret == 0 -def test_help_message(testdir): - result = testdir.runpytest( +def test_help_message(pytester): + result = pytester.runpytest( '--help', ) # fnmatch_lines does an assertion internally @@ -36,13 +33,13 @@ def test_help_message(testdir): ]) -def test_hello_ini_setting(testdir): - testdir.makeini(""" +def test_hello_ini_setting(pytester): + pytester.makeini(""" [pytest] HELLO = world """) - testdir.makepyfile(""" + pytester.makepyfile(""" import pytest @pytest.fixture @@ -53,7 +50,7 @@ def test_hello_world(hello): assert hello == 'world' """) - result = testdir.runpytest('-v') + result = pytester.runpytest('-v') # fnmatch_lines does an assertion internally result.stdout.fnmatch_lines([ diff --git a/pytest-{{cookiecutter.plugin_name}}/tox.ini b/pytest-{{cookiecutter.plugin_name}}/tox.ini index e99d0b0..19d93be 100644 --- a/pytest-{{cookiecutter.plugin_name}}/tox.ini +++ b/pytest-{{cookiecutter.plugin_name}}/tox.ini @@ -1,12 +1,12 @@ # For more information about tox, see https://tox.readthedocs.io/en/latest/ [tox] -envlist = py35,py36,py37,py38,pypy3,flake8 +envlist = py38,py39,py310,py311,py312,pypy3,flake8 [testenv] -deps = pytest>=3.0 +deps = pytest>={{cookiecutter.pytest_version}} commands = pytest {posargs:tests} [testenv:flake8] skip_install = true deps = flake8 -commands = flake8 pytest_{{cookiecutter.module_name}}.py setup.py tests +commands = flake8 src tests diff --git a/tests/test_create_template.py b/tests/test_create_template.py index cce4f46..55fb6a1 100644 --- a/tests/test_create_template.py +++ b/tests/test_create_template.py @@ -1,11 +1,3 @@ -# -*- coding: utf-8 -*- - -""" -test_create_template --------------------- -""" - - import os import pytest import subprocess @@ -16,12 +8,12 @@ def run_tox(plugin): try: subprocess.check_call([ 'tox', - plugin, + '--workdir', plugin, '-c', os.path.join(plugin, 'tox.ini'), - '-e', 'py' + '-e', 'py', ]) except subprocess.CalledProcessError as e: - pytest.fail(e) + pytest.fail(str(e)) def test_run_cookiecutter_and_plugin_tests(cookies): @@ -30,9 +22,10 @@ def test_run_cookiecutter_and_plugin_tests(cookies): assert result.exit_code == 0 assert result.exception is None - assert result.project.basename == 'pytest-foo-bar' - assert result.project.isdir() - assert result.project.join('pytest_foo_bar.py').isfile() - assert result.project.join('tests', 'test_foo_bar.py').isfile() + assert result.project_path.name == 'pytest-foo-bar' + assert result.project_path.is_dir() + assert result.project_path.joinpath('src', 'pytest_foo_bar', '__init__.py').is_file() + assert result.project_path.joinpath('src', 'pytest_foo_bar', 'plugin.py').is_file() + assert result.project_path.joinpath('tests', 'test_foo_bar.py').is_file() - run_tox(str(result.project)) + run_tox(str(result.project_path)) diff --git a/tox.ini b/tox.ini index 2021d1f..c63d876 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] recreate = true skipsdist = true -envlist = py35, py36, py37, py38, pypy3 +envlist = py38, py39, py310, py311, py312, pypy3 [testenv] deps = pytest