2010-02-19 63 views
14

在此寻找一些实用建议以及人们在类似情况下遇到的任何体验。TDD:“仅测试”方法

我们使用BDD/TDD sytle方法来构建我们的软件(相当大/复杂的应用程序)最终结果是从业务需求导出的行为规范(Given/When/Then style),反映这些行为的单元测试和反映测试要求的代码。但是,最近我们的测试部门已经开始运行集成测试,并且可以理解,他们想要使用我们(已经通过)的​​业务逻辑代码来设置和拆除测试状态(而不是直接与数据库打交道),作为他们主要关注通过应用程序的UI进行测试,并且不希望花费整天的时间来讨论数据库。

问题是,一些实体存储库没有删除方法,因为目前还没有业务需求。许多已经存档/恢复/备份等(并且可能在待办事项上有待删除)。

所以现在我们有一个测试部门。要求删除(但与商业用户故事冲突)

所以....我的问题是...如果我要添加方法专门为测试部门...处理的最佳方式是什么这些。我知道这在“TDD乌托邦”中被普遍认为是不正确的做法,但实际上,您是如何处理这种冲突的?

的第一个想法我有或者是使用命名...

void TestOnly_Delete(Guid id){} 

... ...属性

[TestOnly] 
void Delete(Guid id){} 

...或编译器指令...

#if TESTBUILD 
void Delete(Guid id){} 
#endif 

所以至少开发人员可以知道不要调用TestOnly方法,并且最大程度上不会在生产版本中部署测试方法。

...或只是欺骗并添加一个用户故事来管理它的方式;-)

任何经验或建议,衷心感谢?

在此先感谢。

回答

4

您首先应该关注的是确实增加了这个功能增强或者恶化了当前的API吗? TDD中的一个典型场景是,一个类成员(最初)只是为了可测试性原因而需要,但它符合所有正常的API设计准则,所以它不会造成任何伤害(并且通常随后会成为生产代码中有价值的补充以及)。

当这是真的,那么通过一切手段只需添加它如果你可以这样做很容易

然而,有时候情况恰恰相反。在这种情况下,您必须抵制添加成员的冲动。但是,通常您可以按照Open/Closed Principle的说法打开您的API,以便其他人可以添加所需的功能。 Testability is really just another word for the Open/Closed Principle

就你而言,最简单的解决方案可能仅仅是确保所讨论的类未被封装,然后要求测试部门从这些类派生并自行实现这些功能。如果他们没有这种能力,那么你可以为他们做,而仍然保持子类只进行测试。

1

在我的代码,我创建一个子类:例如,如果我有一个DataLayer类具有所有的公共方法来访问数据层,那么我会用Test_DataLayer子类,它继承自DataLayer和方法,它的子类它进一步实现了你可能想要的其他方法,如Delete,其实现可以访问基类的内部或受保护的方法。

1

我通常最终得到一个“只测试”的项目/库,它包含我测试所需的任何模拟/辅助类。在这个模拟库中添加必要的类/方法(不包括在生产代码中)看起来很适合这种需求。如果你还没有这样一个库,并且不想创建一个库,那么我会标记 - 如果可能的话 - 这些方法是内部的,只能将它们暴露给测试框架。您不指定平台,但我知道这对于C#/ .NET是可能的,我经常使用此功能为我的测试提供访问库之外不可用的方法的权限。

另一方面,我会说测试人员与实际客户一样,是您需求分析的一部分。就像我们有一些纯粹满足我们开发需求的要求一样,我们也有一些测试要求。正如你所发现的,诀窍就是要尽可能地满足利益相关者需要的全部的开发代码。当需求冲突时,我们尝试尽可能使用最佳折中方案。国际海事组织(IMO)允许从测试专用库中删除与客户对数据安全(不删除)需求的合理妥协。

0

这是一个有趣的问题。我有一些想法,但不知道它是否会成为你的问题的答案。

我将亲自创建一个继承自您已经拥有的实体的显式接口集合,例如IIntTest_Customer:ICustomer,并在那里定义删除方法。如果可能的话,试图将所有这些接口放在单独的项目中,这样开发人员甚至不会从通常的项目中引用它,并避免意外使用它们。然后测试部门将使用此特定的内部测试接口进行测试。

要做到这一点,你也许不得不重构你当前的代码,改变实体,实现这些内部测试接口来代替,而与继承层次结构的所有现有的代码应该仍然工作是指基本接口。

0

我永远不会将删除或其他清理方法添加到我的代码中来支持自动化测试。

有很多选择,从智能事务管理到数据库自动恢复。