How does the unittest library determine whether to run a decorated method?

Gregory Nisbet

Tested with Python 2.7.12 on Linux.

I am trying to write a simple function that decorates a test_* method in unittest.TestCase. I know that methods that do not begin with test_ are not considered actual tests and are not invoked directly when the test is run. I then wondered what you happen if you took a test_ method and applied a naive decorator to it that made no attempt to preserve the name. I was expecting my test to be ignored and to have to modify my decorator to make sure that the function has a name beginning with test_. I was very, very surprised when the test ran anyway.

Here's the directory layout of the example

.
|-- add.py
|-- print_args.py
|-- test_add.py
`-- test_add_decorated.py

0 directories, 4 files

add.py is the library we are testing. It adds two things.

def add(x, y):
    return x + y

print_args.py is a library containing a decorator that prints the args and kwargs of a function as a side effect. It is written as naively as possible and makes no attempt to preserve the name of the function.

def print_args(wrapped):
    def wrapper(*args, **kwargs):
        print [args, kwargs]
        return apply(wrapped, args, kwargs)

    return wrapper

Here is test_add.py which imports add.py and tests that 4 + 5 = 9. The __repr__ method of TestAdd is not directly relevant to this example, but will be in the next one.

import unittest
import add


class TestAdd(unittest.TestCase):
    def __repr__(self):
        return "I am a unittest.TestCase! Fear me!"

    def test_add(self):
        self.assertEqual(add.add(4, 5), 9)


if __name__ == "__main__":
    unittest.main()

When we run test_add.py, we can see that one test ran and it passed.

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Now we apply the decorator to the test_add method in test_add_decorated.py.

import unittest
import print_args
import add


class TestAdd(unittest.TestCase):
    def __repr__(self):
        return "I am a unittest.TestCase! Fear me!"

    @print_args.print_args
    def test_add(self):
        self.assertEqual(add.add(4, 5), 9)


if __name__ == "__main__":
    unittest.main()

Before I ran this, I was expecting to see no errors, but an indication that zero tests had run, since the test_add method's name should now be wrapper.

That is not what happened. The print_args decorator worked fine, we can see the args and kwargs in an array and an indication that one test ran successfully.

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
[(I am a unittest.TestCase! Fear me!,), {}]

So, my question is ... how did the unittest library figure out that it was supposed to run my decorated method?

user2357112 supports Monica

The wrapper function's __name__ might be wrapper, but it's still TestAdd.test_add. As in, if you look at the TestAdd class's __dict__, you'll find the wrapper function bound to key 'test_add', and if you wanted to call the method, you would use the name test_add, not wrapper.

When unittest uses method names to determine whether a method is a test, it doesn't look at the __name__. It looks at what attribute name the method is associated with, and the decorator doesn't affect that.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Python unittest does not run tests

From Python

How does this if statement determine whether num%2 is true or false

From

How does Rust know whether to run the destructor during stack unwind?

From Dev

How to determine whether Task.Run is completed within a loop

From Dev

How does angular determine whether jQuery is present?

From Dev

How does scanf determine whether to block?

From Dev

How do I override a decorated method in Python?

From Dev

How does Python determine whether to represent a number using scientific notation or not?

From Dev

How does this method determine the greatest common divisor?

From Dev

How does VBA determine whether the default property is implicitly used or not?

From Dev

How does the Where method run?

From Dev

Java polymorphism - How to determine whether superclass vs subclass method will be called and superclass variable vs subclass variable?

From Dev

How does evdev determine whether or not to move the x11 cursor?

From Dev

Spring AOP - Determine whether method was invoked by @Scheduled

From Dev

How does `lseek` help determine whether a file is empty?

From Dev

How can my script determine whether it's being run by bash or dash?

From Dev

How should one determine whether to release a Haskell library as one package or many?

From Dev

How to determine if a class is decorated with a PostSharp aspect at build or run time

From Dev

How to inject a datasource with autocommit on or off whether a method is run inside a transaction or not

From Dev

Faster Method to determine whether an element with a class exists?

From Dev

How to UnitTest this method properly?

From Dev

How to determine whether a script is run at startup or manually?

From Dev

Determine whether Android method is static in an automated fashion

From Dev

How does CPython determine whether a user supplied an optional argument?

From Dev

How to patch a method decorated with `flask - route` in testing?

From Dev

How to run a unittest method with Unicode characters in the name in IDEA?

From Dev

Determine whether programs run on Powershell or CMD

From Dev

How to run unittest in parallel?

From Dev

How does std::set determine whether to include a new insert?

Related Related

  1. 1

    Python unittest does not run tests

  2. 2

    How does this if statement determine whether num%2 is true or false

  3. 3

    How does Rust know whether to run the destructor during stack unwind?

  4. 4

    How to determine whether Task.Run is completed within a loop

  5. 5

    How does angular determine whether jQuery is present?

  6. 6

    How does scanf determine whether to block?

  7. 7

    How do I override a decorated method in Python?

  8. 8

    How does Python determine whether to represent a number using scientific notation or not?

  9. 9

    How does this method determine the greatest common divisor?

  10. 10

    How does VBA determine whether the default property is implicitly used or not?

  11. 11

    How does the Where method run?

  12. 12

    Java polymorphism - How to determine whether superclass vs subclass method will be called and superclass variable vs subclass variable?

  13. 13

    How does evdev determine whether or not to move the x11 cursor?

  14. 14

    Spring AOP - Determine whether method was invoked by @Scheduled

  15. 15

    How does `lseek` help determine whether a file is empty?

  16. 16

    How can my script determine whether it's being run by bash or dash?

  17. 17

    How should one determine whether to release a Haskell library as one package or many?

  18. 18

    How to determine if a class is decorated with a PostSharp aspect at build or run time

  19. 19

    How to inject a datasource with autocommit on or off whether a method is run inside a transaction or not

  20. 20

    Faster Method to determine whether an element with a class exists?

  21. 21

    How to UnitTest this method properly?

  22. 22

    How to determine whether a script is run at startup or manually?

  23. 23

    Determine whether Android method is static in an automated fashion

  24. 24

    How does CPython determine whether a user supplied an optional argument?

  25. 25

    How to patch a method decorated with `flask - route` in testing?

  26. 26

    How to run a unittest method with Unicode characters in the name in IDEA?

  27. 27

    Determine whether programs run on Powershell or CMD

  28. 28

    How to run unittest in parallel?

  29. 29

    How does std::set determine whether to include a new insert?

HotTag

Archive