如何为无参数方法自动生成测试用例?
how to auto generate test cases for parameter-less methods?
为了减少样板代码,我想到了在 class 测试器中为所有无参数方法生成测试用例的想法。
在运行py.test上,它只识别静态编写的测试用例(test_a,test_b),但不识别使用setattr(Tester,'test_' + name, member)
动态创建个测试用例
也许 py.test 在调用 setUpClass 之前已经检查了 class Tester 是否有 'test_*' 的方法?任何提示如何得到这个 运行?
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()
============================= 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 2 items
sandbox.py::Tester::test_a PASSED sandbox.py::Tester::test_b PASSED
========================== 2 passed in 0.03 seconds ===========================
编辑:如果我将 setupClass 中的代码移动到全局范围(class 之外),那么 py.test 会检测并运行自动生成的测试用例。
为了详细说明我的 'EDIT',一种选择是这样。我对该解决方案不满意,因为全局代码执行会对 side-effects 和其他细微错误开放。关于如何将其纳入 class Tester
范围的任何建议?
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 ===========================
为了减少样板代码,我想到了在 class 测试器中为所有无参数方法生成测试用例的想法。
在运行py.test上,它只识别静态编写的测试用例(test_a,test_b),但不识别使用setattr(Tester,'test_' + name, member)
也许 py.test 在调用 setUpClass 之前已经检查了 class Tester 是否有 'test_*' 的方法?任何提示如何得到这个 运行?
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()
============================= 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 2 items
sandbox.py::Tester::test_a PASSED sandbox.py::Tester::test_b PASSED
========================== 2 passed in 0.03 seconds ===========================
编辑:如果我将 setupClass 中的代码移动到全局范围(class 之外),那么 py.test 会检测并运行自动生成的测试用例。
为了详细说明我的 'EDIT',一种选择是这样。我对该解决方案不满意,因为全局代码执行会对 side-effects 和其他细微错误开放。关于如何将其纳入 class Tester
范围的任何建议?
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 ===========================