最近,我在用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

我在使用mocker时注意到的一件事是,首先编写应用程序代码然后再返回并编写第二个测试更容易,因为大部分时间我都在模拟许多方法调用和编写模拟的语法调用比应用程序代码更冗长(因此更难编写)。 编写应用程序代码然后对其进行建模测试代码会更容易。

我发现使用这种测试方法(以及一些规则),我可以轻松地编写具有100%测试覆盖率的代码。

我想知道这些测试是否是好的测试? 当我终于发现编写好测试的秘诀时,我会后悔这样做吗?

我是否违反了TDD的核心原则,以至于我的测试是徒劳的?

===============>>#1 票数:7

如果您在编写代码并通过测试后编写测试,那么您就不会使用TDD (也没有获得测试优先或测试驱动开发的任何好处..查看有关TDD权威书籍的SO问题)

我在使用mocker时注意到的一件事是,首先编写应用程序代码然后再返回并编写第二个测试更容易,因为大部分时间我都在模拟许多方法调用和编写模拟的语法调用比应用程序代码更冗长(因此更难编写)。 编写应用程序代码然后对其进行建模测试代码会更容易。

当然,它更容易,因为你只是通过用特定类型的画笔绘制它来测试天空是橙色的。 这是改造测试(为了自我保证)。 模拟很好,但你应该知道如何以及何时使用它们 - 就像俗话说的那样'当你有一把锤子时,一切看起来像钉子'这也很容易写出一大堆不可读的,而不是有用的。 - 测试。 花在理解测试内容上的时间是可以用来修复损坏的时间。

重点是:

  • Mocks不是存根 - Martin Fowler如果你还没有。 谷歌出了一些好的ModelViewPresenter图形化GUI的记录实例(如有必要,伪造/模拟UI)。
  • 研究你的选择并明智地选择。 我会扮演你左肩上有光环的家伙,说“不要这样做”。 根据我的理由阅读这个问题 - 圣贾斯汀就在你的右肩上。 我相信他也有话要说:)

===============>>#2 票数:-2

重构代码时,单元测试非常有用(即完全重写或移动模块)。 只要您在进行重大更改之前进行单元测试,您就会有信心在完成任务时忘记移动或包含某些内容。

===============>>#3 票数:-3

请记住,TDD不是灵丹妙药。 这很难,它应该很难,而且“提前”写出模拟测试特别困难。

所以我会说 - 做对你有用的事情。 即使它不是“经过认证的TDD”。 我基本上做同样的事情。

您可能希望为控制器代码和GUI库代码之间的GUI提供自己的GUI。 这可能更容易模拟,或者你甚至可以添加一些测试钩子。

最后但同样重要的是,您的代码看起来并不太难以理解。 使用模拟的代码通常难以理解。 幸运的是,在Python中,模拟比其他语言更容易和更清晰。

  ask by millerdev translate from so

未解决问题?本站智能推荐:

4回复

在测试基于MVC的UI时,您会进行多少测试设置?

我正在尝试测试基于WebForms(asp.net)的简单UI,并遵循MVP模式以使UI更具可测试性。 在遵循TDD方法进行后端算法时,我发现有些单元测试重构是按照DRY原则(不要重复自己)的精神进行的。 当我尝试使用Rhino Mocks将其应用于UI来验证我的交互时,在设置视图或模型
7回复

单元测试MFC UI应用程序?

如何对大型MFC UI应用程序进行单元测试? 我们有一些大型MFC应用程序已经开发多年,我们使用一些标准的自动化QA工具来运行基本脚本来检查基础,文件打开等。这些由QA小组在每日构建后发布。 但我们想介绍一些过程,以便各个开发人员可以在将代码提交到每日构建之前,根据对话框,菜单和应用
2回复

我应该如何在Python中使用Mocks进行测试?

我可以看到两种不同的方法将mocks注入到我想要测试的python代码中: 依赖注入: 允许协作类传递到被测对象的构造函数中,并传入模拟对象(以及必要时的工厂,如Java) 猴子补丁: 使用模拟对象工厂来锁定被测模块中的协作类(以便构建协作类实际上创建了一个模拟对象)。
2回复

是否应该为包装第三方代码的方法编写测试用例?

在我的应用程序中,我有验证CIDR地址的方法。 它所做的只是包装ipv4 validate_cidr方法: 我个人不喜欢它。 我宁愿将验证检查放在main() 。 我这样做的唯一原因是因为我编写测试以验证CIDR地址: 有必要编写这样的测试吗?
1回复

如何测试此代码

我正在尝试TDD和单元测试,从未真正做过任何严肃的事情。 我有一个从程序输出的XML文件。 我想将其转换为JSON。 我发现xmltodict所以我想做的是: 我该如何测试? 我应该将它分成3个功能并分别测试吗? 我应该针对错误的文件名进行“防御性”编码吗? 那么解析和转
3回复

有一个单元测试,主要是模拟验证气味?

我有一个连接其他三个服务的类,专门用于实现其他服务更加模块化,但我的单元测试逻辑的大部分是模拟验证。 有没有办法重新设计以避免这种情况? Python示例: 然后我必须模拟输入,输出和查找器。 即使我做了另一个抽象并从Correlator.run()返回一些东西,它仍然需要作为
5回复

为“ assertEqual”和“ assertNotEqual”编写测试:我应该打扰吗?

我有一个Coordinate类,它具有一个add(Coordinate)方法。 在为此类编写单元测试时,我有一些测试来assertEqual结果: 我可以很容易地“伪造”这个: 这是测试失败的最简单解决方案。 下一步是编写第二个测试,以防止我以这种方式伪造它。 我可以:
1回复

Django测试:如何测试类似代码

假设我有4个以这种方式自定义的Django模型字段: Q1 :我测试4个自定义字段,还是仅测试mixin? 我的猜测是4个字段,因为我要测试功能(如最终结果:我想要带有rs_serial-argument等的小数字段),而不是实现。 我可以为每种自定义字段类型和每个参数创建单独的
3回复

我应该如何表明尚未在Python中编写测试?

我正在使用Python和unittest模块进行TDD。 在NUnit中,您可以Assert.Inconclusive("This test hasn't been written yet") 。 到目前为止,我还没有在Python中找到类似的东西来表示“这些测试只是占位符,我需要回来并
1回复

应该测试tdd的静态文本,例如电子邮件主题?

我不确定是否应该为TDD测试静态文本,例如电子邮件主题 例如我有下一段代码是否有必要添加一个包含适当主题的测试? 还是适当的“来自”参数?