Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3757 from mozilla/1239380-pytest
Browse files Browse the repository at this point in the history
Fix bug 1239380: Switch to py.test
  • Loading branch information
willkg committed Jan 15, 2016
2 parents 75b0fd4 + dc01f40 commit 460f0ec
Show file tree
Hide file tree
Showing 61 changed files with 293 additions and 264 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,6 +2,7 @@
*.pyo
*.sw?
.vagrant
.cache
kuma.box
/settings_local.py
pip-log.txt
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -7,7 +7,7 @@ endif

# Note: these targets should be run from the kuma vm
django-tests: in_vagrant
python manage.py test
py.test

performance-tests: in_vagrant
locust -f tests/performance/smoke.py --host=https://developer.allizom.org
Expand Down
101 changes: 73 additions & 28 deletions docs/tests.rst
Expand Up @@ -20,49 +20,67 @@ Running the Test Suite
If you followed the steps in :doc:`the installation docs <installation>`,
then all you should need to do to run the test suite is::

./manage.py test
py.test

However, that doesn't provide the most sensible defaults. Here is a good
command to alias to something short::

./manage.py test -s --noinput --logging-clear-handlers
Default options for running the test are in ``pytest.ini``. This is a
good set of defaults.

The ``-s`` flag is important if you want to be able to drop into PDB from
within tests.
If you ever need to change the defaults, you can do so at the command
line.

Some tests will fail. See `Running a Subset`_ below for running the subset
that is expected to pass.
Helpful command-line arguments:

Some other helpful flags are:

``-x``:
Fast fail. Exit immediately on failure. No need to run the whole test suite
if you already know something is broken.
``--pdb``:
Drop into PDB on an uncaught exception. (These show up as ``E`` or errors in
the test results, not ``F`` or failures.)
``--pdb-fail``:
Drop into PDB on a test failure. This usually drops you right at the
assertion.
Drop into pdb on test failure.

``--create-db``:
Create a new test database.

``--showlocals``:
Shows local variables in tracebacks on errors.

``--exitfirst``:
Exits on the first failure.

See ``./py.test --help`` for more arguments.


Running subsets of tests and specific tests
-------------------------------------------

There are a bunch of ways to specify a subset of tests to run:

* only tests marked with the 'spam' marker::

py.test -m spam

* all the tests but those marked with the 'spam' marker::

py.test -m "not spam"

* all the tests but the ones in ``kuma/core``::

py.test --ignore kuma/core

* all the tests that have "foobar" in their names::

Running a Subset
----------------
py.test -k foobar

You can run part of the test suite by specifying the apps you want to run,
like::
* all the tests that don't have "foobar" in their names::

./manage.py test kuma
py.test -k "not foobar"

You can also exclude tests that match a regular expression with ``-e``::
* tests in a certain directory::

./manage.py test -e "search"
py.test kuma/wiki/

To run the subset of tests that should pass::
* specific test::

./manage.py test kuma
py.test kuma/wiki/tests/test_views.py::RedirectTests::test_redirects_only_internal

See the output of ``./manage.py test --help`` for more arguments.

See http://pytest.org/latest/usage.html for more examples.


The Test Database
Expand All @@ -72,6 +90,33 @@ The test suite will create a new database named ``test_%s`` where ``%s`` is
whatever value you have for ``settings.DATABASES['default']['NAME']``. Make
sure the user has ``ALL`` on the test database as well.


Markers
=======

See::

py.test --markers


for the list of available markers.

To add a marker, add it to the ``pytest.ini`` file.

To use a marker, add a decorator to the class or function. Examples::

import pytest

@pytest.mark.spam
class SpamTests(TestCase):
...

class OtherSpamTests(TestCase):
@pytest.mark.spam
def test_something(self):
...


Adding Tests
============

Expand Down
4 changes: 1 addition & 3 deletions kuma/attachments/tests/test_models.py
@@ -1,9 +1,7 @@
from nose.tools import ok_

from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType

from kuma.core.tests import KumaTestCase
from kuma.core.tests import KumaTestCase, ok_
from kuma.users.tests import user
from ..utils import allow_add_attachment_by

Expand Down
8 changes: 4 additions & 4 deletions kuma/attachments/tests/test_templates.py
@@ -1,11 +1,11 @@
import pytest
from constance import config
from nose.plugins.attrib import attr
from nose.tools import eq_, ok_
from pyquery import PyQuery as pq

from kuma.core.tests import eq_, ok_
from kuma.core.urlresolvers import reverse
from kuma.users.tests import UserTestCase
from kuma.wiki.tests import revision, WikiTestCase
from kuma.core.urlresolvers import reverse

from ..models import Attachment
from ..utils import make_test_file
Expand All @@ -22,7 +22,7 @@ def tearDown(self):
super(AttachmentTests, self).tearDown()
config.WIKI_ATTACHMENT_ALLOWED_TYPES = self.old_allowed_types

@attr('security')
@pytest.mark.security
def test_xss_file_attachment_title(self):
title = '"><img src=x onerror=prompt(navigator.userAgent);>'
# use view to create new attachment
Expand Down
2 changes: 1 addition & 1 deletion kuma/attachments/tests/test_views.py
Expand Up @@ -5,10 +5,10 @@
from django.core.files import temp as tempfile
from django.core.files.base import ContentFile
from django.utils.http import parse_http_date_safe
from nose.tools import eq_, ok_

from kuma.core.urlresolvers import reverse
from kuma.core.utils import urlparams
from kuma.core.tests import eq_, ok_
from kuma.users.tests import UserTestCase
from kuma.wiki.models import Document, DocumentAttachment
from kuma.wiki.tests import WikiTestCase, document, revision
Expand Down
8 changes: 4 additions & 4 deletions kuma/authkeys/tests/test_decorators.py
@@ -1,12 +1,12 @@
import base64

import pytest

from django.contrib.auth.models import AnonymousUser
from django.test import TestCase
from django.http import HttpRequest

from nose.tools import eq_, ok_
from nose.plugins.attrib import attr

from kuma.core.tests import eq_, ok_
from kuma.users.tests import user

from ..models import Key
Expand All @@ -15,7 +15,7 @@

class KeyDecoratorsTest(TestCase):

@attr('current')
@pytest.mark.current
def test_key_auth_decorator(self):

u = user(username="test23", email="test23@example.com", save=True)
Expand Down
8 changes: 4 additions & 4 deletions kuma/authkeys/tests/test_models.py
@@ -1,16 +1,16 @@
from django.test import TestCase
import pytest

from nose.tools import ok_
from nose.plugins.attrib import attr
from django.test import TestCase

from kuma.core.tests import ok_
from kuma.users.tests import user

from ..models import Key


class KeyViewsTest(TestCase):

@attr('current')
@pytest.mark.current
def test_secret_generation(self):
"""Generated secret should be saved as a hash and pass a check"""
u = user(username="tester23",
Expand Down
2 changes: 1 addition & 1 deletion kuma/authkeys/tests/test_views.py
@@ -1,10 +1,10 @@
from nose.tools import eq_, ok_
from pyquery import PyQuery as pq

from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.test import TestCase

from kuma.core.tests import eq_, ok_
from kuma.core.urlresolvers import reverse
from kuma.users.tests import user

Expand Down
29 changes: 20 additions & 9 deletions kuma/core/tests/__init__.py
Expand Up @@ -8,14 +8,31 @@
from django.test.client import Client
from django.utils.translation import trans_real

from nose import SkipTest
from nose.tools import eq_

from ..cache import memcache
from ..exceptions import FixtureMissingError
from ..urlresolvers import split_path


def eq_(first, second, msg=None):
"""Rough reimplementation of nose.tools.eq_
Note: This should be removed as soon as we no longer use it.
"""
msg = msg or '%r != %r' % (first, second)
assert first == second, msg


def ok_(pred, msg=None):
"""Rough reimplementation of nose.tools.ok_
Note: This should be removed as soon as we no longer use it.
"""
msg = msg or '%r != True' % pred
assert pred, msg


def attrs_eq(received, **expected):
"""Compares received's attributes with expected's kwargs."""
for k, v in expected.iteritems():
Expand Down Expand Up @@ -108,8 +125,6 @@ class KumaTestMixin(object):

@classmethod
def setUpClass(cls):
if cls.skipme:
raise SkipTest
if cls.localizing_client:
cls.client_class = LocalizingClient
super(KumaTestMixin, cls).setUpClass()
Expand Down Expand Up @@ -140,7 +155,3 @@ class KumaTestCase(KumaTestMixin, TestCase):

class KumaTransactionTestCase(KumaTestMixin, TransactionTestCase):
pass


class SkippedTestCase(KumaTestCase):
skipme = True
4 changes: 1 addition & 3 deletions kuma/core/tests/test_anonymous_middleware.py
@@ -1,10 +1,8 @@
from nose.tools import eq_

from django.http import HttpResponse
from django.conf import settings
from django.test import RequestFactory

from kuma.core.tests import KumaTestCase
from kuma.core.tests import KumaTestCase, eq_

from ..anonymous import AnonymousIdentityMiddleware

Expand Down
10 changes: 4 additions & 6 deletions kuma/core/tests/test_commands.py
@@ -1,8 +1,6 @@
from django.core.management import call_command, CommandError
from django.utils.six import StringIO

from nose.tools import eq_

from kuma.users.tests import user, UserTestCase


Expand All @@ -13,21 +11,21 @@ def test_help(self):
call_command('ihavepower', stdout=out)

commanderror = commanderror_cm.exception
eq_(commanderror.message, 'Error: too few arguments')
assert commanderror.message == 'Error: too few arguments'

def test_user_doesnt_exist(self):
out = StringIO()
with self.assertRaises(CommandError) as commanderror_cm:
call_command('ihavepower', 'fordprefect', stdout=out)

commanderror = commanderror_cm.exception
eq_(commanderror.message, 'User fordprefect does not exist.')
assert commanderror.message == 'User fordprefect does not exist.'

def test_user_exists(self):
out = StringIO()
user(username='fordprefect', save=True)
call_command('ihavepower', 'fordprefect', stdout=out)

ford = self.user_model.objects.get(username='fordprefect')
eq_(ford.is_staff, True)
eq_(ford.is_superuser, True)
assert ford.is_staff is True
assert ford.is_superuser is True
3 changes: 1 addition & 2 deletions kuma/core/tests/test_decorators.py
Expand Up @@ -2,13 +2,12 @@
from django.http import HttpResponse

from django.test import RequestFactory
from nose.tools import eq_, ok_

from kuma.core.decorators import (block_user_agents, logout_required,
login_required, never_cache,
permission_required)

from kuma.core.tests import KumaTestCase
from kuma.core.tests import KumaTestCase, eq_, ok_
from kuma.users.tests import UserTestCase


Expand Down
4 changes: 1 addition & 3 deletions kuma/core/tests/test_form_fields.py
@@ -1,8 +1,6 @@
from django.utils import translation

from nose.tools import eq_

from kuma.core.tests import KumaTestCase
from kuma.core.tests import KumaTestCase, eq_

from ..form_fields import _format_decimal

Expand Down
3 changes: 1 addition & 2 deletions kuma/core/tests/test_forms.py
@@ -1,9 +1,8 @@
from django import forms

from nose.tools import eq_
from pyquery import PyQuery as pq

from kuma.core.tests import KumaTestCase
from kuma.core.tests import KumaTestCase, eq_

from ..form_fields import StrippedCharField

Expand Down

0 comments on commit 460f0ec

Please sign in to comment.