summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--django/test/utils.py5
-rw-r--r--docs/spelling_wordlist1
-rw-r--r--docs/topics/testing/tools.txt19
-rw-r--r--tests/test_runner/test_discover_runner.py12
-rw-r--r--tests/test_runner_apps/tagged/tests_inheritance.py29
6 files changed, 66 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index b1fa5456b6..4f7ef379f6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -832,6 +832,7 @@ answer newbie questions, and generally made Django that much better:
Wiktor KoƂodziej <wiktor@pykonik.org>
Wiley Kestner <wiley.kestner@gmail.com>
Wiliam Alves de Souza <wiliamsouza83@gmail.com>
+ Will Ayd <william.ayd@icloud.com>
William Schwartz <wkschwartz@gmail.com>
Will Hardy <django@willhardy.com.au>
Wilson Miner <wminer@gmail.com>
diff --git a/django/test/utils.py b/django/test/utils.py
index 1a1b78f34d..cbefaf0e09 100644
--- a/django/test/utils.py
+++ b/django/test/utils.py
@@ -831,6 +831,9 @@ class isolate_apps(TestContextDecorator):
def tag(*tags):
"""Decorator to add tags to a test class or method."""
def decorator(obj):
- setattr(obj, 'tags', set(tags))
+ if hasattr(obj, 'tags'):
+ obj.tags = obj.tags.union(tags)
+ else:
+ setattr(obj, 'tags', set(tags))
return obj
return decorator
diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist
index 34754bde76..20508bcdfd 100644
--- a/docs/spelling_wordlist
+++ b/docs/spelling_wordlist
@@ -695,6 +695,7 @@ subviews
subwidget
subwidgets
superclass
+superclasses
superset
swappable
symlink
diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt
index d349efe7a0..65d1fb463b 100644
--- a/docs/topics/testing/tools.txt
+++ b/docs/topics/testing/tools.txt
@@ -1619,6 +1619,25 @@ You can also tag a test case::
class SampleTestCase(TestCase):
...
+Subclasses inherit tags from superclasses, and methods inherit tags from their
+class. Given::
+
+ @tag('foo')
+ class SampleTestCaseChild(SampleTestCase):
+
+ @tag('bar')
+ def test(self):
+ ...
+
+``SampleTestCaseChild.test`` will be labeled with ``'slow'``, ``'core'``,
+``'bar'``, and ``'foo'``.
+
+.. versionchanged:: 2.1
+
+ In older versions, tagged tests don't inherit tags from classes, and
+ tagged subclasses don't inherit tags from superclasses. For example,
+ ``SampleTestCaseChild.test`` is labeled only with ``'bar'``.
+
Then you can choose which tests to run. For example, to run only fast tests:
.. code-block:: console
diff --git a/tests/test_runner/test_discover_runner.py b/tests/test_runner/test_discover_runner.py
index d897344d16..5efcbe4f5d 100644
--- a/tests/test_runner/test_discover_runner.py
+++ b/tests/test_runner/test_discover_runner.py
@@ -198,3 +198,15 @@ class DiscoverRunnerTest(TestCase):
self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 0)
runner = DiscoverRunner(exclude_tags=['slow'])
self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 0)
+
+ def test_tag_inheritance(self):
+ def count_tests(**kwargs):
+ suite = DiscoverRunner(**kwargs).build_suite(['test_runner_apps.tagged.tests_inheritance'])
+ return suite.countTestCases()
+
+ self.assertEqual(count_tests(tags=['foo']), 4)
+ self.assertEqual(count_tests(tags=['bar']), 2)
+ self.assertEqual(count_tests(tags=['baz']), 2)
+ self.assertEqual(count_tests(tags=['foo'], exclude_tags=['bar']), 2)
+ self.assertEqual(count_tests(tags=['foo'], exclude_tags=['bar', 'baz']), 1)
+ self.assertEqual(count_tests(exclude_tags=['foo']), 0)
diff --git a/tests/test_runner_apps/tagged/tests_inheritance.py b/tests/test_runner_apps/tagged/tests_inheritance.py
new file mode 100644
index 0000000000..59e564202d
--- /dev/null
+++ b/tests/test_runner_apps/tagged/tests_inheritance.py
@@ -0,0 +1,29 @@
+from unittest import TestCase
+
+from django.test import tag
+
+
+@tag('foo')
+class FooBase(TestCase):
+ pass
+
+
+class Foo(FooBase):
+
+ def test_no_new_tags(self):
+ pass
+
+ @tag('baz')
+ def test_new_func_tag(self):
+ pass
+
+
+@tag('bar')
+class FooBar(FooBase):
+
+ def test_new_class_tag_only(self):
+ pass
+
+ @tag('baz')
+ def test_new_class_and_func_tags(self):
+ pass