商业应用的TDD示例

我理解关于单元测试的一般想法,并且已经在系统中发生复杂交互的场景中使用它,但我仍然对所有这些原则汇总的问题有疑问.

我们被警告不要测试框架或数据库.良好的UI设计不适合非人体测试.一般来说,UI交互在MVC框架中被排除.在许多应用程序中还剩下什么? 37signals讨论了广泛的单元测试,但在像Basecamp或Backpack这样的应用程序中,通过适当的单元测试测试的内容究竟是什么类型? 100%的代码覆盖率在那种情况下意味着什么?

编辑:我没有拆掉像背包这样的应用程序 – 它们很棒,但是工作似乎更多地涉及设计和交互,而不是复杂的逻辑(事实上,他们支持这个想法).在该应用程序的那些区域中,CRUD和哪个对象的层次结构几乎涵盖了它,单元测试的适当数量是零吗?在这种情况下,测试点是否是验证代码的另一个副本(必需,正则表达式等)?

解决方法

商业应用程序的TDD就是这样的.

>写下业务要求.
>记下该要求的测试.
>编写通过测试的代码.

诀窍是有许多不需要大量测试的垃圾非业务需求.

>“保存到数据库”不是业务要求.这是技术性的.
>“在某些情况下激活GUI上的按钮”不是业务要求,它是界面的一部分.
>“备份”不是业务要求;它的安全性或业务连续性等等.

考虑一个具体的例子.

要求 – “在你支付罚款之前,你不能借书.”

试验.

>尝试罚款借书.
>尝试借书没有罚款.

码.

class FinesNotPaid( unittest.TestCase ):
    def setUp( self ):
        # load some fixtures with users,books and fines outstanding.
    def test_should_not_checkout_book( self ):
        x = TheCheckoutClass()
        x.checkoutBook( someBook )
        self.fail( "Should have thrown error" )

class FinesPaid( unittest.TestCase ):
    def setUp( self ):
        # load some fixtures with users,books and fines paid.
    def test_should_not_checkout_book( self ):
        x = TheCheckoutClass()
        x.checkoutBook( someBook )
        self.success(  )

class NoFines( unittest.TestCase ):
    etc.

这些是由与数据库和GUI分开的类实现的业务规则.这些是应用程序域层中的类.

您的CRUD规则是业务规则.你需要测试它们.但是,您无需测试每个与数据库相关的功能.你需要一些“我可以创建和持久化对象吗?”试验.您必须相信ORM,数据访问层和数据库实际上是可行的.您不会编写测试来详尽地测试ORM的内置功能.

代码覆盖率(100%或80%或10%)在很大程度上毫无意义.具有80%代码覆盖率的测试的软件实际上更有可能失败20%吗?它不起作用.测试每行代码并不涵盖所有逻辑路径,因此请不要担心并开始测试.

测试业务用例.如果它们通过并且有未经测试的代码,那么 – 也许 – 你写了太多的代码.

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...