1

The last days I have tested some technics in python to automate unittest, like TestCase in C#.

I know that some frameworks supports this technics, but I will learn python more in detail and so I would like to understand this.

For me the the following post has a great answer (from Xavier Decoret) and so I tried it out and the result was very good, but I can not stack the decorators without exception.

Python unittest: Generate multiple tests programmatically?

In short my two pieces of code, the resulting exception and the environment:

import sys

def for_examples(*parameters):

  def tuplify(x):
    if not isinstance(x, tuple):
      return (x,)
    return x

  def decorator(method, parameters=parameters):
    for parameter in (tuplify(x) for x in parameters):

      def method_for_parameter(self, method=method, parameter=parameter):
        method(self, *parameter)
      args_for_parameter = ",".join(repr(v) for v in parameter)
      name_for_parameter = method.__name__ + "(" + args_for_parameter + ")"
      frame = sys._getframe(1)  # pylint: disable-msg=W0212
      frame.f_locals[name_for_parameter] = method_for_parameter
    return None
  return decorator
import unittest

# some magic code will be added here later
from params import for_examples


    class DummyTest(unittest.TestCase):
      @for_examples(1, 2)
      @for_examples(3, 4)
      def test_is_smaller_than_four(self, value):
        self.assertTrue(value < 4)

      @for_examples((1,2),(2,4),(3,7))
      def test_double_of_X_is_Y(self, x, y):
        self.assertEqual(2 * x, y)

    if __name__ == "__main__":
      unittest.main()
AttributeError: 'NoneType' object has no attribute '__name__'
Launching unittests with arguments python -m unittest test.DummyTest.test_double_of_X_is_Y in D:\rené\PycharmProjects\params
Windws 10 Home 64-bit
PyCharm Community Edition 2017.1.1
Python 3.6.1

Hopefully somebody can help me to understand my issue and we can find a stackable solution.

l33tHax0r
  • 1,384
  • 1
  • 15
  • 31

1 Answers1

0

The decorator you copied isn't designed to be used like that.

The cause is this line:

return None

Usually, decorators are expected to return the decorated function, not None. In this case, however, the decorator purposely doesn't return a function so that unittest doesn't consider it a test case.

The good thing is that isn't a problem at all, because

@for_examples(1, 2)
@for_examples(3, 4)

is equivalent to

@for_examples(1, 2, 3, 4)
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • Yes I have tested it with only one decorator, but for my understanding I will known why is it not possible with two decorators. What must be changed that is running twice. I have tested some variations with the return type without a satisfying result. When I use the `method_for_parameter` as return type nothing will be executed from the test framework. –  Apr 23 '17 at 16:40
  • @rené The "correct" return value would be `method`. But then you'll have an additional test case that will always fail because it receives no parameters. – Aran-Fey Apr 23 '17 at 16:59