这是我最近的工具中的代码,我正在尝试编写unittest,我有一个idea of how to test a method that returns something但不明白我应该如何测试不喜欢下面的方法:
def buildUi(self):
self.label = QtGui.QLabel()
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.setCentralWidget(self.label)
def nextImage(self):
""" switch to next image or previous image
"""
if self._imagesInList:
if self._count == len(self._imagesInList):
self._count = 0
self.showImageByPath(
self._imagesInList[self._count])
if self.animFlag:
self._count += 1
else:
self._count -= 1
def showImageByPath(self, path):
if path:
image = QtGui.QImage(path)
pp = QtGui.QPixmap.fromImage(image)
self.label.setPixmap(pp.scaled(
self.label.size(),
QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation))
def playPause(self):
if not self._pause:
self._pause = True
self.updateTimer.start(2500)
return self._pause
else:
self._pause = False
self.updateTimer.stop()
def keyPressEvent(self, keyevent):
""" Capture key to exit, next image, previous image,
on Escape , Key Right and key left respectively.
"""
event = keyevent.key()
if event == QtCore.Qt.Key_Escape:
self.close()
if event == QtCore.Qt.Key_Left:
self.animFlag = False
self.nextImage()
if event == QtCore.Qt.Key_Right:
self.animFlag = True
self.nextImage()
if event == 32:
self._pause = self.playPause()
可以找到完整的查找代码here
可以测试上面的这些方法,还是我必须修改才能使它们可测试? 编辑:更新:
class TestSlideShow(unittest.TestCase):
""" docstring for TestSlideShow
"""
def setUp(self):
self.mox = mox.Mox()
self.imgLst = ['/folder/test/images/test1.jpg', '/folder/test/images/test2.JPG',
'/folder/test/images/test3.png', '/folder/test/images/test4.PNG']
app = QtGui.QApplication([])
self.show = slideShow.SlideShowPics(imgLst=self.imgLst, ui=False)
def tearDown(self):
self.mox.UnsetStubs()
self.mox.ResetAll()
def test_nextImage(self):
self.mox.StubOutWithMock(self.show, 'prepairWindow')
self.show.prepairWindow()
self.mox.StubOutWithMock(self.show, 'showImageByPath')
self.show.showImageByPath(self.imgLst[1])
self.show.nextImage()
# self.mox.ReplayAll()
self.assertEquals(1, self.show.count)
self.assertEquals(self.imgLst[1], self.show._imagesInList[1])
# self.mox.VerifyAll()
def test_nextImage_animFlag_False(self):
self.show.animFlag = False
self.show.count = 4
self.mox.StubOutWithMock(self.show, 'prepairWindow')
self.show.prepairWindow()
self.mox.StubOutWithMock(self.show, 'showImageByPath')
self.show.showImageByPath(self.imgLst[3])
print self.show.count
self.show.nextImage()
print self.show.count
# self.assertEquals(3, self.show.count)
self.assertEquals(self.imgLst[3], self.show._imagesInList[3])
if __name__ == '__main__':
unittest.main()
self.show.animFlag为True时的第一个测试工作正常,但是当我手动设置animFlag = False然后第二次测试失败时。
答案 0 :(得分:1)
这是在代码之后编写unittest的问题 - 然后你意识到你的代码很难测试。在代码之前编写测试(好吧,真的“沿着”代码 - 在开始编码之前你没有编写所有测试,但是在你测试它之前你仍然没有编写一行代码)确保你没有这样的问题。
现在即使使用“先测试”方法,您也必须测试不返回任何内容的方法。这样做的方法是测试预期的副作用。其中一些副作用很容易测试 - 在上述情况下,您可以在调用self._count
之前和之后测试nextImage
的值,具体取决于对象的状态(_imagesInList
和主要是animFlag
。如果你想测试nextImage
实际上是否使用正确的参数调用showImageByPath
,并且使用当前设计,唯一的方法就是monkeypatch showImageByPath
测试。测试showImageByPath
需要修补/模拟self.label.setPixmap()
等。
正如其他人已经指出的那样,有一些模拟/存根库可以提供帮助,但它们无法解决所有可能的可测试性问题,您可能不得不重新考虑您的设计以使事情变得更容易 - 就像没有硬编码调用{{ 1}}在QtGui.QLabel()
中,但有一些方法来“注入”所需的组件(buildUI()
或模拟)。作为一般规则,可测试代码具有非常少的硬编码依赖性,很少的副作用,以及许多具有短方法的小类(而不是具有长方法的大类)。