~netlandish/django-wiki

6fa4c5558e989477067ca0b71a97e0885ea51ef0 — Benjamin Bach 6 years ago 9c38174 + c2cadaa
Merge pull request #781 from azaghal/pytest-tox-improvements-issue-644

Improved test dependency handling, removal of wrapper testing script, and fixes for running pytest directly (issue #644)
9 files changed, 77 insertions(+), 102 deletions(-)

M MANIFEST.in
M Makefile
M docs/development/environment.rst
M docs/development/index.rst
M docs/development/testing.rst
D runtests.py
M setup.cfg
M setup.py
M tox.ini
M MANIFEST.in => MANIFEST.in +0 -1
@@ 1,7 1,6 @@
include COPYING
include README.rst
include setup.cfg
include runtests.py
recursive-include src *.html *.txt *.png *.js *.css *.gif *.less *.mo *.po *.otf *.svg *.woff *.woff2 *.eot *.ttf
prune src/wiki/attachments
prune src/wiki/images

M Makefile => Makefile +1 -1
@@ 51,7 51,7 @@ lint:  ## Check python code conventions
	flake8 src/wiki tests/

test:  ## Run automated test suite
	./runtests.py
	pytest

test-all:  ## Run tests on all supported Python environments
	tox

M docs/development/environment.rst => docs/development/environment.rst +2 -3
@@ 7,6 7,5 @@ Setting up a development environment
* Install the requirements::

    $ pip install --upgrade pip setuptools
    $ pip install -e .
    $ pip install pytest pytest-django pytest-pythonpath pytest-cov mock django-functest

    $ pip install -e .[devel]
    $ pip install tox

M docs/development/index.rst => docs/development/index.rst +19 -8
@@ 70,7 70,7 @@ Ready to contribute? Here's how to set up `django-wiki` for local development.

    $ mkvirtualenv django-wiki
    $ cd django-wiki/
    $ python setup.py develop
    $ pip install -e .[devel]

4. Create a branch for local development::



@@ 78,21 78,30 @@ Ready to contribute? Here's how to set up `django-wiki` for local development.

   Now you can make your changes locally.

5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox::
5. As you are making changes you may want to verify that changes are
   passing all the relevant styling and functional/unit tests::

    $ tox -e lint
    $ py.test  # Run tests in current environment
    $ tox
    $ flake8
    $ pytest

6. When you're done making changes, perform one final round of
   testing, and also ensure relevant tests pass with all supported
   Python versions with tox::

    $ flake8
    $ pytest
    $ tox -e lint # Runs linter within isolated environment
    $ tox # Runs all tests that pytest would run, just with various Python/Django combinations

   To get flake8 and tox, just pip install them into your virtualenv.

6. Commit your changes and push your branch to GitHub::
7. Commit your changes and push your branch to GitHub::

    $ git add .
    $ git commit -m "Your detailed description of your changes."
    $ git push origin name-of-your-bugfix-or-feature

7. Submit a pull request through the GitHub website.
8. Submit a pull request through the GitHub website.

Pull Request Guidelines
-----------------------


@@ 112,7 121,9 @@ Tips

To run a subset of tests::

    $ py.test tests.test_django-wiki
    $ pytest tests/core/test_basic.py # All tests from a single file.
    $ pytest tests/core/test_basic.py::URLPathTests # All tests from a single class.
    $ pytest tests/core/test_basic.py::URLPathTests::test_manager # Just one test.


Roadmap

M docs/development/testing.rst => docs/development/testing.rst +17 -6
@@ 4,19 4,30 @@ Tests
Running tests
-------------

To run django-wiki's tests, run ``make test`` or ``./runtests.py``
To run django-wiki's tests, run ``make test`` or ``pytest``

If you want to test for more **environments**, install "tox"
(``pip install tox``) and then just run ``tox`` to run the test
suite on multiple environments.

To run **specific tests**, see ``./runtests.py --help``.
To run **specific tests**, see ``pytest --help``.

To include Selenium tests, you need to install `chromedriver
<https://sites.google.com/a/chromium.org/chromedriver/>`_ and run
``./runtests.py --include-selenium``. For tox, do::
To include Selenium tests, you need to have ``Xvfb`` installed
(usually via system-provided package manager), `chromedriver
<https://sites.google.com/a/chromium.org/chromedriver/>`_ and set the
environment variable ``INCLUDE_SELENIUM_TESTS=1``. For example, run
tests with (depending on whether you want to test directly or via
tox)::

    INCLUDE_SELENIUM_TESTS=1 tox
  INCLUDE_SELENIUM_TESTS=1 pytest
  INCLUDE_SELENIUM_TESTS=1 tox

If you wish to also show the browser window while running the
functional tests, set the environment variable
``SELENIUM_SHOW_BROWSER=1`` in *addition* to
``INCLUDE_SELENIUM_TESTS=1``, for example::

  INCLUDE_SELENIUM_TESTS=1 SELENIUM_SHOW_BROWSER=1 pytest


Writing tests

D runtests.py => runtests.py +0 -58
@@ 1,58 0,0 @@
#!/usr/bin/env python
from __future__ import print_function, unicode_literals

import argparse
import os
import signal
import subprocess
import sys


class RuntestsArgumentParser(argparse.ArgumentParser):
    def print_help(self):
        super(RuntestsArgumentParser, self).print_help()
        print("\n")
        print("All other arguments will be passed to pytest, \n"
              "which has the following options:\n")
        subprocess.call(["pytest", "--help"])

parser = RuntestsArgumentParser(usage="./runtests.py [args] [tests to run]\n\n"
                                "Individual tests can be run using pytest syntax e.g.\n\n"
                                "  ./runtests.py ./tests/core/test_views.py::ArticleViewViewTests::test_article_list_update\n")
parser.add_argument("--include-selenium", action='store_true',
                    help="Include Selenium tests, which are skipped by default. Requires chromedriver")
parser.add_argument("--show-browser", action='store_true',
                    help="Show browser window when running Selenium tests")


def main():
    known_args, remaining_args = parser.parse_known_args()
    cmd = ["pytest"] + remaining_args
    if known_args.include_selenium:
        # It is easier to use environment variables than to use 'pytest -k',
        # because the user might want to use that option.
        os.environ['INCLUDE_SELENIUM_TESTS'] = "1"
    if known_args.show_browser:
        os.environ['SELENIUM_SHOW_BROWSER'] = "1"

    # Signal handling to ensure the right thing happens
    # when Ctrl-C is pressed.
    SIGINT_RECEIVED = False

    def signal_handler(sig, f):
        global SIGINT_RECEIVED
        SIGINT_RECEIVED = True
        # No other action, just allow child to exit.


    signal.signal(signal.SIGINT, signal_handler)

    retcode = subprocess.call(cmd)

    if SIGINT_RECEIVED:
        sys.exit(1)
    else:
        sys.exit(retcode)

if __name__ == '__main__':
    main()

M setup.cfg => setup.cfg +4 -1
@@ 5,7 5,10 @@ universal = 1
ignore = E501
max-line-length = 160
max-complexity = 10
exclude = */*migrations
exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg,*/*migrations,testproject

[metadata]
description-file = README.rst

[aliases]
test=pytest
\ No newline at end of file

M setup.py => setup.py +29 -3
@@ 23,7 23,7 @@ def get_path(fname):
    return os.path.join(os.path.dirname(__file__), fname)


requirements = [
install_requirements = [
    "Django>=1.11,<2.0",
    "bleach>=1.5,<2",
    "Pillow",


@@ 34,6 34,30 @@ requirements = [
    "Markdown>=2.6,<2.7",
]

test_requirements = [
    'django-functest>=1.0,<1.1',
    'mock>=2.0,<2.1',
    'pytest>=3.4,<3.5',
    'pytest-django>=3.1,<3.2',
    'pytest-cov>=2.4,<2.5',
    'pytest-pythonpath>=0.7,<0.8',
]

test_lint_requirements = [
    'flake8>=3.5,<3.6',
]

setup_requirements = [
    'pytest-runner',
]

development_requirements = test_requirements + test_lint_requirements

extras_requirements = {
    'devel': development_requirements,
    'test': test_requirements,
    'testlint': test_lint_requirements,
}

setup(
    name="wiki",


@@ 49,7 73,7 @@ setup(
    py_modules=[os.path.splitext(os.path.basename(path))[0] for path in glob('src/*.py')],
    long_description=open('README.rst').read(),
    zip_safe=False,
    install_requires=requirements,
    install_requires=install_requirements,
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',


@@ 68,5 92,7 @@ setup(
        'Topic :: Software Development :: Libraries :: Application Frameworks',
    ],
    include_package_data=True,
    test_suite='runtests',
    setup_requires=setup_requirements,
    tests_require=test_requirements,
    extras_require=extras_requirements,
)

M tox.ini => tox.ini +5 -21
@@ 28,29 28,13 @@ commands =
  # Test that there are no migrations needed -- on Django 1.11, we can
  # use --check and remove the '!' which likely doesn't work on Windows
  sh -c '! testproject/manage.py makemigrations --dry-run --exit --noinput'
  {toxinidir}/runtests.py --basetemp={envtmpdir} --ds=tests.settings --cov=src/wiki --cov-config .coveragerc {posargs}
  pytest --basetemp={envtmpdir} --ds=tests.settings --cov={envsitepackagesdir}/wiki --cov-config .coveragerc {posargs}

usedevelop = true
usedevelop = false

deps =
  coverage
  pytest==3.0.7
  pytest-django==3.1.2
  pytest-pythonpath==0.7.1
  pytest-cov==2.4.0
  Pillow==2.3.0
  django-classy-tags==0.4
  mock>=2.0
  Markdown==2.6.7
  django_nyt==1.0
  bleach==1.5.0
  django111: Django==1.11
  django-mptt==0.8.6
  django-sekizai==0.10.0
  sorl-thumbnail==12.3
  django-functest==1.0.2
  django-webtest==1.9.2
  WebTest==2.0.28
  .[test]
  django111: Django>=1.11,<2.0

basepython =
  py34: python3.4


@@ 60,7 44,7 @@ basepython =

[testenv:lint]
basepython = python3.4
deps = flake8
deps = .[testlint]
commands =
  flake8 src/wiki
  flake8 tests/