파이썬으로 단위 테스트를 작성하는 경우 (unittest 모듈 사용) 실패한 테스트에서 데이터를 출력 할 수 있으므로 오류의 원인을 추론하는 데 도움이되도록 검사 할 수 있습니까? 일부 정보를 전달할 수있는 사용자 지정 메시지를 만드는 기능을 알고 있지만 때로는 문자열로 쉽게 표현할 수없는 더 복잡한 데이터를 처리 할 수 있습니다.
예를 들어, Foo 클래스가 있고 testdata라는 목록의 데이터를 사용하여 메서드 표시 줄을 테스트했다고 가정합니다.
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
테스트가 실패하면이 특정 데이터가 실패한 이유를 확인하기 위해 t1, t2 및 / 또는 f를 출력 할 수 있습니다. 출력에 따르면 테스트가 실행 된 후 다른 변수처럼 변수에 액세스 할 수 있습니다.
답변
저처럼 간단하고 빠른 답변을 찾기 위해 여기에 오는 사람에게는 매우 늦은 답변입니다.
Python 2.7에서는 추가 매개 변수 msg
를 사용하여 다음과 같은 오류 메시지에 정보를 추가 할 수 있습니다 .
self.assertEqual(f.bar(t2), 2, msg='{0}, {1}'.format(t1, t2))
여기에 공식 문서
답변
이를 위해 로깅 모듈을 사용합니다.
예를 들면 :
import logging
class SomeTest( unittest.TestCase ):
def testSomething( self ):
log= logging.getLogger( "SomeTest.testSomething" )
log.debug( "this= %r", self.this )
log.debug( "that= %r", self.that )
# etc.
self.assertEquals( 3.14, pi )
if __name__ == "__main__":
logging.basicConfig( stream=sys.stderr )
logging.getLogger( "SomeTest.testSomething" ).setLevel( logging.DEBUG )
unittest.main()
이를 통해 실패하고 추가 디버깅 정보가 필요한 특정 테스트에 대해 디버깅을 켤 수 있습니다.
그러나 내가 선호하는 방법은 디버깅에 많은 시간을 소비하는 것이 아니라 문제를 드러내 기 위해 더 세분화 된 테스트를 작성하는 데 소비하는 것입니다.
답변
간단한 print 문을 사용하거나 stdout에 쓰는 다른 방법을 사용할 수 있습니다. 테스트의 어느 곳에서나 Python 디버거를 호출 할 수도 있습니다.
nose 를 사용 하여 테스트를 실행 하는 경우 (권장) 각 테스트에 대한 stdout을 수집하고 테스트가 실패한 경우에만 표시하므로 테스트가 통과 할 때 복잡한 출력으로 살 필요가 없습니다.
nose는 또한 assert에 언급 된 변수를 자동으로 표시하거나 실패한 테스트에서 디버거를 호출하는 스위치를 가지고 있습니다. 예를 들어 -s
( --nocapture
)는 stdout 캡처를 방지합니다.
답변
나는 이것이 당신이 찾고있는 것이 아니라고 생각하지 않습니다. 실패하지 않는 변수 값을 표시하는 방법은 없지만 원하는 방식으로 결과를 출력하는 데 도움이 될 수 있습니다.
결과 분석 및 처리를 위해 TestRunner.run () 에서 반환 된 TestResult 개체를 사용할 수 있습니다 . 특히 TestResult.errors 및 TestResult.failures
TestResults 개체 정보 :
http://docs.python.org/library/unittest.html#id3
그리고 올바른 방향을 가리키는 코드 :
>>> import random
>>> import unittest
>>>
>>> class TestSequenceFunctions(unittest.TestCase):
... def setUp(self):
... self.seq = range(5)
... def testshuffle(self):
... # make sure the shuffled sequence does not lose any elements
... random.shuffle(self.seq)
... self.seq.sort()
... self.assertEqual(self.seq, range(10))
... def testchoice(self):
... element = random.choice(self.seq)
... error_test = 1/0
... self.assert_(element in self.seq)
... def testsample(self):
... self.assertRaises(ValueError, random.sample, self.seq, 20)
... for element in random.sample(self.seq, 5):
... self.assert_(element in self.seq)
...
>>> suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
>>> testResult = unittest.TextTestRunner(verbosity=2).run(suite)
testchoice (__main__.TestSequenceFunctions) ... ERROR
testsample (__main__.TestSequenceFunctions) ... ok
testshuffle (__main__.TestSequenceFunctions) ... FAIL
======================================================================
ERROR: testchoice (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 11, in testchoice
ZeroDivisionError: integer division or modulo by zero
======================================================================
FAIL: testshuffle (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 8, in testshuffle
AssertionError: [0, 1, 2, 3, 4] != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
----------------------------------------------------------------------
Ran 3 tests in 0.031s
FAILED (failures=1, errors=1)
>>>
>>> testResult.errors
[(<__main__.TestSequenceFunctions testMethod=testchoice>, 'Traceback (most recent call last):\n File "<stdin>"
, line 11, in testchoice\nZeroDivisionError: integer division or modulo by zero\n')]
>>>
>>> testResult.failures
[(<__main__.TestSequenceFunctions testMethod=testshuffle>, 'Traceback (most recent call last):\n File "<stdin>
", line 8, in testshuffle\nAssertionError: [0, 1, 2, 3, 4] != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n')]
>>>
답변
또 다른 옵션-테스트가 실패한 디버거를 시작합니다.
Testoob로 테스트를 실행 해보십시오 (변경없이 unittest 제품군을 실행합니다). 테스트가 실패 할 때 ‘–debug’명령 줄 스위치를 사용하여 디버거를 열 수 있습니다.
다음은 Windows의 터미널 세션입니다.
C:\work> testoob tests.py --debug
F
Debugging for failure in test: test_foo (tests.MyTests.test_foo)
> c:\python25\lib\unittest.py(334)failUnlessEqual()
-> (msg or '%r != %r' % (first, second))
(Pdb) up
> c:\work\tests.py(6)test_foo()
-> self.assertEqual(x, y)
(Pdb) l
1 from unittest import TestCase
2 class MyTests(TestCase):
3 def test_foo(self):
4 x = 1
5 y = 2
6 -> self.assertEqual(x, y)
[EOF]
(Pdb)
답변
제가 사용하는 방법은 정말 간단합니다. 경고로 기록하기 만하면 실제로 표시됩니다.
import logging
class TestBar(unittest.TestCase):
def runTest(self):
#this line is important
logging.basicConfig()
log = logging.getLogger("LOG")
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
log.warning(t1)
답변
나는 이것을 지나치게 생각한 것 같다. 제가 생각 해낸 한 가지 방법은 진단 데이터를 축적하는 전역 변수를 갖는 것입니다.
다음과 같이 :
log1 = dict()
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
if f.bar(t2) != 2:
log1("TestBar.runTest") = (f, t1, t2)
self.fail("f.bar(t2) != 2")
답장을 보내 주셔서 감사합니다. 그들은 파이썬에서 단위 테스트의 정보를 기록하는 방법에 대한 몇 가지 대안 아이디어를 제공했습니다.