2017-01-16 12 views
3

Чтобы уменьшить код плиты котла, я пришел к идее генерировать тестовые примеры в тесте класса для всех без параметров.Как автоматически генерировать тестовые примеры для методов без параметров?

При управлении py.test, он признает только статический написанные тестовых случаев (test_a, test_b), но не динамически создаваемых тестовых случаев с помощью setattr(Tester,'test_' + name, member)

Возможно py.test уже осмотрел класс Tester для методов с 'test_ *' до вызова setUpClass? Любые подсказки, как это сделать?

import inspect 
import unittest 


class Testee: 
    def a(self): 
     print('a') 

    def b(self): 
     print('b')  

    #... 

    #... 
    def z(self): 
     print('z') 

class Tester(unittest.TestCase): 

    @classmethod 
    def setUpClass(cls): 
     testee = Testee() 
     for name, member in inspect.getmembers(object=testee, predicate=inspect.ismethod or inspect.iscoroutine): 
      if len(inspect.signature(member).parameters): 
       print(str(inspect.signature(member).parameters)) 
       setattr(Tester,'test_' + name, member) 
      if inspect.isfunction(member) or inspect.ismethod(member): 
       setattr(Tester,'test_' + name, member) 
      elif inspect.iscoroutinefunction(member): 
       setattr(Tester,'test_' + name, functools.partialmethod(TestInstrument.run_coro, member)) 
      else: 
       print(member) 
     return super().setUpClass() 

    def test_a(self): 
     Tester.testee.a() 

    def test_b(self): 
     Tester.testee.b() 

============================= тест сессия начинается ========= ==================== платформа win32 - Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 - c: \ программа файлы \ python35 \ python.exe CacheDir: .cache RootDir: C: \ тесты, INIFILE: собираемые 2 шт

sandbox.py::Tester::test_a ПРОШЛО sandbox.py::Tester::test_b PASSED

=================== 0 =============

EDIT: Если я переместить код в setupClass в глобальной области видимости (вне класса), затем py.test обнаруживает и запускает автоматически сгенерированных тестовых случаев.

+0

Можете ли вы разместить сообщение, где вы создаете тестовый класс? Кроме того, используйте 'cls' вместо' Tester' в вашем setattr. –

+0

@ Vincenzzzochi py.test делает для меня. – goldcode

ответ

0

Чтобы уточнить мой «РЕДАКТИРОВАТЬ», один из вариантов был бы таким. Я недоволен решением, потому что выполнение глобального кода будет открыто для побочных эффектов и других тонких ошибок. любые предложения о том, как получить это в классе Tester scope?

import inspect 
import unittest 
import functools 
def auto_generate_test_cases(Tester, Testee): 
    def run(self, fn): 
     fn(Tester._testee) 
    for name, member in inspect.getmembers(
     object=Testee, predicate=inspect.isfunction or inspect.iscoroutine): 
     if len(inspect.signature(member).parameters) == 1:    
      setattr(Tester,'test_' + name, functools.partialmethod(run, member)) 

class Testee: 
    def __init__(self): 
     self._a = 'a' 
    def a(self): 
     print(self._a) 
    def ab(self, a, b): 
     print('a') 
    def b(self): 
     print('b')  
    def h(self): 
     print('h')  
    async def q(self): 
     print('async q') 
    #... 

    #... 
    def z(self): 
     print('z') 

class Tester(unittest.TestCase): 
    _testee = Testee() 
auto_generate_test_cases(Tester, Testee) 

py.test. выход:

C:\tests>py.test sandbox.py --verbose 
============================= test session starts ============================= 
platform win32 -- Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 -- c:\program files\python35\python.exe 
cachedir: .cache 
rootdir: C:\\tests, inifile: 
collected 5 items 

sandbox.py::Tester::test_a PASSED 
sandbox.py::Tester::test_b PASSED 
sandbox.py::Tester::test_h PASSED 
sandbox.py::Tester::test_q PASSED 
sandbox.py::Tester::test_z PASSED 

========================== 5 passed in 0.07 seconds =========================== 

 Смежные вопросы

  • Нет связанных вопросов^_^