当应用程序是100%CRUD时应用TDD

时间:2009-05-09 01:39:15

标签: tdd

我经常遇到这个问题,我不知道如何克服这个障碍。我真的想开始学习和应用测试驱动开发(或BDD,或其他),但似乎我想要应用的每个应用程序,它几乎只是标准的数据库CRUD的东西,我不知道如何去应用它。除了被持久化到数据库之外,这些对象几乎不做任何事情;没有需要测试的复杂逻辑。有一个网关,我最终需要测试第三方服务,但我想首先完成应用程序的核心。

每当我尝试编写测试时,我最终只会测试我可能不应该首先测试的基本内容(例如getter / setter),但它看起来不像对象有其他任何东西。我想我可以测试持久性,但这对我来说似乎不对,因为你不应该真正打到数据库,但如果你嘲笑它然后你真的没有测试任何东西,因为你控制了吐回来的数据;就像我已经看到很多例子,其中有一个模拟存储库通过循环和创建已知值列表来模拟数据库,并且测试验证“存储库”可以撤回某个值...我是没有看到这样的测试点,因为“存储库”当然会返回该值;它在课堂上硬编码!好吧,我从纯TDD的角度看待它(也就是说你需要测试一下你的存储库需要一个GetCustomerByName方法或其他什么才能编写方法本身),但这看起来好像遵循了教条,除了它的“ “ - 除了证明一种方法之外,测试似乎没有做任何有用的事情。

我是否认为这是错误的方式?

例如,运行工厂联系人管理应用程序。我们有联系人,让我们说我们可以向联系人发送消息。因此,我们有两个实体:ContactMessage,每个实体都具有共同属性(例如,名字,姓氏,联系电子邮件,主题和正文以及消息日期)。如果这些对象都没有任何实际行为或需要执行任何逻辑,那么在设计这样的应用程序时如何应用TDD?该应用程序的唯一目的基本上是拉出联系人列表并在页面上显示它们,显示表单以发送消息等。我在这里没有看到任何有用的测试 - 我可以想到一些测试,但它们几乎是为了说“看,我有测试!”的测试。而不是实际测试某种逻辑(虽然Ruby on Rails很好地利用它,我并不认为测试验证是一个“有用的”测试,因为它应该是框架为你照顾的东西)

9 个答案:

答案 0 :(得分:14)

“该应用程序的唯一目的基本上是提取联系人列表”

好。测试一下。 “拉”是什么意思?这听起来像“逻辑”。

“在页面上显示它们”

好。测试一下。正确的显示?那里有什么?

“显示表单以发送消息”,

好。测试一下。正确的领域?输入的验证都有效吗?

“之类的。”

好。测试一下。查询是否有效?找到合适的数据?显示正确的数据?验证输入?为无效输入生成正确的错误消息?

答案 1 :(得分:6)

我正在研究纯CRUD应用程序 但我看到单元测试用例有很多好处(注意 - 我没说TDD)

我首先编写代码然后然后测试用例 - 但是从来没有分开 - 尽快

我还测试了CRUD操作 - 对数据库的持久性。

当我完成持久性 - 并继续进入UI层 - 我将有相当大的信心,我的服务\持久层是好的 - 然后我可以在那一刻专注于UI。

所以恕我直言 - TDD \单元测试总是有好处的(无论你怎么称呼它取决于你对它的看法有多么极端) - 即使对于CRUD应用程序也是如此 您只需要为您的应用找到正确的策略

只是使用常识....你会没事的。

答案 2 :(得分:5)

我觉得我们将TDD与单元测试混淆了。

单元测试是测试行为单元的特定测试。这些测试通常包含在集成构建中。 S.Lott为这些类型的测试描述了一些优秀的候选人。

TDD用于设计。我经常发现,当我使用TDD时,我写的测试要么被丢弃,要么演变为单元测试。这背后的原因是当我正在进行TDD时我正在测试我的设计,而我正在设计我的应用程序,类,方法,域等...

为了回应您的情况,我同意S.Lott所暗示的是,您需要的是一套用于测试应用程序中特定行为的单元测试。

答案 3 :(得分:4)

在我看来,一个简单的CRUD应用程序就像在吉他上练习音阶一样 - 你可能会认为只是为了发现你的演奏提高了多少才是乏味和乏味的。在开发方面 - 您可能会编写更少耦合的代码 - 更易于测试。此外,您更有可能从代码消费者的角度看问题 - 您实际上将使用它。这可能会产生很多有趣的副作用,例如更直观的API,更好的隔离关注等等。虽然有脚手架生成器可以为你做基本的CRUD,它们确实有一个特别用于原型设计的地方,但是它们通常与框架相关联各种各样的。为什么不首先关注核心领域,推迟框架/ UI /数据库决策,直到你更好地了解所需的核心功能--TDD也可以帮助你做到这一点。 在您的示例中:您希望消息是队列还是分层树等? 你想让它们实时加载吗?排序/搜索怎么样?你需要支持JSON还是只支持html?使用BDD / TDD可以更容易地看到这些问题。如果您正在进行TDD,您可以在不使用框架的情况下测试核心逻辑(并等待一分钟加载/运行)

答案 4 :(得分:3)

略过一下。一切都会好的。我相信你有一个截止日期。 (/讽刺)

下个月,我们可以根据用户反馈返回并优化查询。打破我们不知道的事情我们不应该打破。

如果您认为该项目将持续2周,然后再也不会重新开放,那么自动化测试可能是浪费时间。否则,如果您拥有“拥有”此代码几个月的既得利益,并且其活跃,则构建一些测试。用你的判断来判断风险最大的地方。更糟糕的是,如果你计划在公司工作几年,并让其他队友轮流攻击系统的各个部分,并且可能在一年之后再次轮到你,建立一些测试。

不要过度,但要“在其中插入一些引脚”,这样如果事情开始“移动”,你就会有一些警报来引起对事物的注意。

我的大部分测试都是JUnit或批量“差异”类型测试,以及几年前我写的一个基本的屏幕刮板类型工具(编写一些正则表达式+ wget / curl类型的东西)。我听说Selenium应该是一个很好的Web应用程序UI测试工具,但还没有尝试过。任何人都有可用于本地GUI应用程序的工具???

答案 5 :(得分:2)

只是一个想法......

获取CRUD的要求,使用watijwatirAutoIt等工具创建测试用例。开始创建UI以传递测试用例。一旦你完成UI并传递可能只是一个测试,开始为该测试编写逻辑层,然后编写db层。

对于大多数用户来说,UI就是系统。请记住为您正在构建的每个新层编写测试用例。因此,不是从db到app到ui层,而是从相反的方向开始。

在一天结束时,你可能会积累一套强大的回归测试集,让你有信心安全地进行重构。

这只是一个想法...

答案 6 :(得分:1)

我看到你在说什么,但最终你的模型将变得足够先进,以至于它们需要(或通过自动化测试得到极大的增强)。如果没有,你实际开发的是一个已经为你开发的电子表格。

既然你提到了Rails,我会说对每个属性做一个标准的创建/读取/更新/删除测试是一个好主意,特别是因为你的测试应该注意权限(我认为这是巨大的)。这也可以确保您的迁移按预期工作。

答案 7 :(得分:1)

我正在研究CRUD应用程序。我现在正在做的是在我的Repository对象上编写单元测试并测试CRUD功能是否正常工作。我发现这本身就已经对实际的数据库代码进行了单元测试。我们通过这种方式在数据库代码中发现了很多错误。所以我建议你继续前进,继续进行单元测试。我知道在CRUD应用程序上应用TDD并不像你在博客或杂志中看到的那样引人入胜,但它正在服务于它的目的,当你处理更复杂的应用程序时,你会更好。

答案 8 :(得分:1)

现在除了UI之外,你不需要为CRUD应用程序编写太多手工编写的代码,因为有101个框架可以生成数据库和数据访问代码。

所以我会考虑减少手写代码的数量,并自动化UI的测试。然后我会使用需要手写的奇数位逻辑的TDD。