코가 동적으로 생성 된 테스트 케이스를 발견하게하려면 어떻게해야합니까?
-
19-08-2019 - |
해결책
코에는 이와 같은 것들을위한 "테스트 생성기"기능이 있습니다. Args와 함께 실행하려는 각 "테스트 케이스"기능을 생성하는 발전기 기능을 작성합니다. 이전 예제에 따라 별도의 테스트에서 각 기능을 확인할 수 있습니다.
import unittest
import numpy
from somewhere import the_functions
def test_matrix_functions():
for function in the_functions:
yield check_matrix_function, function
def check_matrix_function(function)
matrix1 = numpy.ones((5,10))
matrix2 = numpy.identity(5)
output = function(matrix1, matrix2)
assert matrix1.shape == output.shape, \
"%s produces output of the wrong shape" % str(function)
다른 팁
코는 정적으로 테스트를 스캔하지 않으므로 ~할 수 있다 메타 클래스 마법을 사용하여 코가 찾은 테스트를합니다.
어려운 부분은 표준 메타 클래스 기술이 func_name 속성을 올바르게 설정하지 않는다는 것입니다. 이는 클래스의 메소드가 테스트인지 확인할 때 코가 찾는 것입니다.
간단한 메타 클래스가 있습니다. 그것은 func dict를 통해보고 그것을 찾은 모든 방법에 대한 새로운 메소드를 추가하여 발견 된 방법에 docstring이 있다고 주장합니다. 이 새로운 합성 방법에는 이름이 부여됩니다 "test_%d" %i
.
import new
from inspect import isfunction, getdoc
class Meta(type):
def __new__(cls, name, bases, dct):
newdct = dct.copy()
for i, (k, v) in enumerate(filter(lambda e: isfunction(e[1]), dct.items())):
def m(self, func):
assert getdoc(func) is not None
fname = 'test_%d' % i
newdct[fname] = new.function(m.func_code, globals(), fname,
(v,), m.func_closure)
return super(Meta, cls).__new__(cls, 'Test_'+name, bases, newdct)
이제이 메타 클라스를 사용하는 새로운 클래스를 만들어 봅시다.
class Foo(object):
__metaclass__ = Meta
def greeter(self):
"sdf"
print 'Hello World'
def greeter_no_docstring(self):
pass
런타임에 Foo
실제로 이름이 지정됩니다 Test_Foo
그리고 가질 것입니다 greeter
, greeter_no_docstring
, test_1
그리고 test_2
그 방법으로. 내가 달릴 때 nosetests
이 파일에는 다음은 출력입니다.
$ nosetests -v test.py
test.Test_Foo.test_0 ... FAIL
test.Test_Foo.test_1 ... ok
======================================================================
FAIL: test.Test_Foo.test_0
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/rmcgibbo/Desktop/test.py", line 10, in m
assert getdoc(func) is not None
AssertionError
----------------------------------------------------------------------
Ran 2 tests in 0.002s
FAILED (failures=1)
이 메타 클라스는 그대로 유용하지 않지만 대신 사용하는 경우 Meta
적절한 메타 클라스가 아니라 기능적 메타 클라스 (즉, 클래스를 인수로 받아들이고 새로운 클래스를 반환합니다. ~이다 유용한. 이 접근법을 사용하여 Docstrings가 코 테스트 스위트의 일부로 Numpy 표준에 부착되도록 자동 테스트했습니다.
또한 New.Function과 함께 작동하는 적절한 폐쇄를 얻는 데 많은 어려움이 있었기 때문에이 코드가 사용하는 이유입니다. m(self, func)
어디 func
기본 인수로 만들어졌습니다. 폐쇄를 사용하는 것이 더 자연 스러울 것입니다. value
, 그러나 그것은 작동하지 않는 것 같습니다.
type ()로 테스트 케이스 클래스를 생성 할 수 있습니다.
class UnderTest_MixIn(object):
def f1(self, i):
return i + 1
def f2(self, i):
return i + 2
SomeDynamicTestcase = type(
"SomeDynamicTestcase",
(UnderTest_MixIn, unittest.TestCase),
{"even_more_dynamic":"attributes .."}
)
# or even:
name = 'SomeDynamicTestcase'
globals()[name] = type(
name,
(UnderTest_MixIn, unittest.TestCase),
{"even_more_dynamic":"attributes .."}
)
코가 test_module을 가져 오려고 시도 할 때 생성되어야합니다.
이 접근법의 장점은 많은 테스트 조합을 동적으로 만들 수 있다는 것입니다.