Opened 12 days ago

Last modified 12 days ago

#28869 assigned Bug

Django.test.tag Inconsistent Inheritance

Reported by: William Ayd Owned by: William Ayd
Component: Testing framework Version: 1.11
Severity: Normal Keywords: testing, tag
Cc: Hrishikesh Barman Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Hrishikesh Barman)

When subclassing test cases, decorated tags are inherited ONLY when the subclass does not provide its own tag decorator. If the subclass provides its own decorator(s) then the parent's tags are ignored.

If you use the attached file, running:

python manage.py test

yields two test cases as expected. However, running

python manage.py test --tag=foo-tests

OR

python manage.py test --tag=baz-tests

Will each only run one test a piece. I would expect that the former would run both test cases, given all of the test cases in the attached file are inherited from a class which is decorated with that tag.

Attachments (1)

test_foo.py (268 bytes) - added by William Ayd 12 days ago.
test_foo.py

Download all attachments as: .zip

Change History (9)

Changed 12 days ago by William Ayd

Attachment: test_foo.py added

test_foo.py

comment:1 Changed 12 days ago by Hrishikesh Barman

Description: modified (diff)

comment:2 in reply to:  description Changed 12 days ago by Hrishikesh Barman

Replying to William Ayd:

When subclassing test cases, decorated tags are inherited ONLY when the subclass does not provide its own tag decorator. If the subclass provides its own decorator(s) then the parent's tags are ignored.
Will each only run one test a piece. I would expect that the former would run both test cases, given all of the test cases in the attached file are inherited from a class which is decorated with that tag.

I am a new contributor, I might be completely wrong but I think this is how the tag decorator is supposed to work. When a parameter is explitcitly passed into the tag decorator, the function should use that tag and if the need is to specify another tag it should be done by separating by commas.

 @tag('slow', 'core')
 def test_slow_but_core(self):
   pass

docs: https://docs.djangoproject.com/en/1.11/topics/testing/tools/#tagging-tests

If this is a confirmed bug, I'd like to work on it if you let me. :)

comment:3 Changed 12 days ago by Hrishikesh Barman

Cc: Hrishikesh Barman added

comment:4 Changed 12 days ago by William Ayd

Hi Hrishikesh,

My point was that it's strange that FooBar inherits the tag from it's parent while FooBaz does not, simply because the latter adds another tag of its own. Either neither class should inherit the tag from its parent, or both of them should (I think both inheriting would be preferred).

From what I see this can be easily fixed changing the tag function in Django.tests.util from:

def tag(*tags):
    """
    Decorator to add tags to a test class or method.
    """
    def decorator(obj):
        setattr(obj, 'tags', set(tags))
        return obj
    return decorator

To

def tag(*tags):
    """
    Decorator to add tags to a test class or method.
    """
    def decorator(obj):
        if hasattr(obj, 'tags'):
            obj.tags = obj.tags | set(tags)
        else:
            setattr(obj, 'tags', set(tags))
        return obj
    return decorator

So that subclasses can inherit any existing tags from their parents

comment:5 Changed 12 days ago by Simon Charette

Triage Stage: UnreviewedAccepted

The proposed fix looks appropriate.

Please submit a PR with your proposed patch and a regression test in tests/test_runner/test_discover_runner.py based on the structure introduced by d4dc775620fc57e962165eab98a77264e3dd16b2.

comment:6 Changed 12 days ago by Hrishikesh Barman

Hello William,

I understand it now. thanks. :)

comment:7 Changed 12 days ago by William Ayd

Owner: changed from nobody to William Ayd
Status: newassigned

comment:8 Changed 12 days ago by William Ayd

Has patch: set

Please note that I have fixed this and included regression tests in branch ticket_28869 available in my GitHub repo

https://github.com/WillAyd/django/tree/ticket_28869

Note: See TracTickets for help on using tickets.
Back to Top