最近,我在用Python开发GUI应用程序时一直在试验TDD.我发现让测试验证我的代码的功能非常令人放心,但遵循TDD的一些推荐做法却很棘手.也就是说,首先编写测试很难.而且我发现很难让我的测试可读(由于大量使用模拟库).
我选择了一个名为mocker的模拟库.我使用它很多,因为我正在测试的大部分代码调用(a)我的应用程序中依赖于系统状态的其他方法或(b)没有事件循环时不能存在的ObjC/Cocoa对象等.
无论如何,我有很多看起来像这样的测试:
def test_current_window_controller(): def test(config): ac = AppController() m = Mocker() ac.iter_window_controllers = iwc = m.replace(ac.iter_window_controllers) expect(iwc()).result(iter(config)) with m: result = ac.current_window_controller() assert result == (config[0] if config else None) yield test, [] yield test, [0] yield test, [1, 0]
请注意,这实际上是三个测试; 都使用相同的参数化测试功能.这是正在测试的代码:
def current_window_controller(self): try: # iter_window_controllers() iterates in z-order starting # with the controller of the top-most window # assumption: the top-most window is the "current" one wc = self.iter_window_controllers().next() except StopIteration: return None return wc
一个我所用嘲笑者注意到的事情是,它更容易第二先写的应用程序代码,然后回去写测试,因为大部分的时间,我嘲笑许多方法调用和写嘲笑的语法调用比应用程序代码更冗长(因此更难编写).编写应用程序代码然后对其进行建模测试代码会更容易.
我发现使用这种测试方法(以及一些规则),我可以轻松地编写具有100%测试覆盖率的代码.
我想知道这些测试是否是好的测试?当我终于发现编写好测试的秘诀时,我会后悔这样做吗?
我是否违反了TDD的核心原则,以至于我的测试是徒劳的?
如果您在编写代码并通过测试后编写测试,那么您就不会使用TDD(也没有获得测试优先或测试驱动开发的任何好处..查看有关TDD权威书籍的SO问题)
我在使用mocker时注意到的一件事是,首先编写应用程序代码然后再返回并编写第二个测试更容易,因为大部分时间我都在模拟许多方法调用和编写模拟的语法调用比应用程序代码更冗长(因此更难编写).编写应用程序代码然后对其进行建模测试代码会更容易.
当然,它更容易,因为你只是通过用特定类型的画笔绘制它来测试天空是橙色的.这是改造测试(为了自我保证).模拟很好,但你应该知道如何以及何时使用它们 - 就像俗话说的那样'当你有一把锤子时,一切看起来像钉子'这也很容易写出一大堆不可读的,而不是有用的. - 测试.花在理解测试内容上的时间是可以用来修复损坏的时间.
重点是:
读Mocks不是存根 - Martin Fowler如果你还没有.谷歌出了一些好的ModelViewPresenter图形化GUI的记录实例(如有必要,伪造/模拟UI).
研究你的选择并明智地选择.我会扮演你左肩上有光环的家伙,说"不要这样做".根据我的理由阅读这个问题- 圣贾斯汀就在你的右肩上.我相信他也有话要说:)