Questions tagged «tdd»

TDD代表测试驱动开发或测试驱动设计。这是在编写代码以使其满足要求之前编写单元测试的实践,即所谓的“红绿色重构周期”。

10
单元测试应用程序逻辑和不信任的语言构造之间的界线在哪里?
考虑这样的函数: function savePeople(dataStore, people) { people.forEach(person => dataStore.savePerson(person)); } 可以这样使用: myDataStore = new Store('some connection string', 'password'); myPeople = ['Joe', 'Maggie', 'John']; savePeople(myDataStore, myPeople); 让我们假设它Store具有自己的单元测试,或由供应商提供。无论如何,我们都相信Store。让我们进一步假设错误处理(例如,数据库断开错误)不是的责任savePeople。确实,让我们假设商店本身是一个神奇的数据库,它不可能以任何方式出错。 鉴于这些假设,问题是: 应该savePeople()进行单元测试,还是将这些测试等同于测试内置forEach语言结构? 当然,我们可以传递一个模拟dataStore并断言dataStore.savePerson()每个人都会被调用一次。您当然可以说这样的测试可提供针对实现更改的安全性的论据:例如,如果我们决定forEach用传统的for循环或某种其他迭代方法代替。因此,测试并非完全无关紧要。但是它似乎非常接近... 这是另一个可能更富有成效的例子。考虑一个仅协调其他对象或功能的功能。例如: function bakeCookies(dough, pan, oven) { panWithRawCookies = pan.add(dough); oven.addPan(panWithRawCookies); oven.bakeCookies(); oven.removePan(); } 假设您认为这样的功能应该如何进行单元测试?这是我很难想象任何种类的单元测试的不只是嘲笑dough,pan和oven,然后断言方法被调用它们。但是这样的测试无非是复制了该函数的确切实现。 无法以有意义的黑盒方式测试功能是否表明功能本身存在设计缺陷?如果是这样,如何改进? 为了更清楚地说明激发bakeCookies示例的问题,我将添加一个更现实的场景,该场景是我尝试向其添加代码并重构遗留代码时遇到的一种情况。 当用户创建新帐户时,需要做很多事情:1)需要在数据库中创建新用户记录2)需要发送欢迎电子邮件3)需要记录用户的IP地址以防欺诈目的。 因此,我们想创建一个将所有“新用户”步骤联系在一起的方法: function createNewUser(validatedUserData, emailService, dataStore) …

10
为什么敏捷只涉及测试驱动开发(TDD)而不是开发驱动测试(DDT)?
因此,我是敏捷的新手,但不是测试驱动的开发。我在大学里的教授都是关于测试的思想,然后是代码然后是测试。我不确定我理解为什么。从我的角度来看,随着代码的发展,很可能会改变很多前期成本。 这就是我对TDD的想象以及为什么让我感到困惑。如果我要作为TDD承包商来盖房子。 给我您所有的规格(故事)。 获得有关规格的批准。 将所有规格分解为我认为需要的检查(展望未来)。 打电话给检查员看一下这些要点,然后告诉我,我现在检查不及格(谢谢)。 开始盖房子。 每天召回检查员(通过2/100)。 抱歉,我的理解存在问题,现在我需要再添加9个检查并更改其中的27个。 呼叫检查员通过1/109。 该死的。检查员为什么不喜欢这个...哦,我更新了该方法名称... 建立更多。 UGGGGHHHH更多更改让我更新了该死的检查器。哦,我没有失败。 我做完了吗 好的,那可能有些古怪,但是直到我的代码在那里,我才看不到如何知道所有方法以及事情将如何工作。99%的时间我必须返回并以任何方式更新单元测试,并在添加时添加更多内容。似乎倒退了。 似乎更合适的是DDT或开发驱动的测试,这似乎是社区几乎忘却的事情。 据我了解,房屋的滴滴涕看起来像: 给我您所有的规格(故事)。 获得有关规格的批准并将其发布。 启动一个单元(基础)。 记下一些棘手的逻辑(注释)。 在开始下一个单元的最后,进行检查(创建测试)。 解决发现的所有问题,然后再次检查。 批准将本单元移至下一个。 如果我们都说实话,这听起来不是更人性化,而是集中在开发人员和业务上吗?似乎可以更快地进行更改,而且似乎不会产生开销的TDD。

7
编写现有代码的测试
假设其中一个程序比较大(例如,在C#中为900k SLOC),所有程序都已进行了注释/记录,内容井井有条,运作良好。整个代码库由一个不再在公司工作的高级开发人员编写。所有代码都可以按原样进行测试,并且在整个过程中都使用IoC -出于某些奇怪的原因,他们没有编写任何单元测试。现在,您的公司希望分支代码,并希望添加单元测试以检测更改何时破坏了核心功能。 添加测试是一个好主意吗? 如果是这样,一个人怎么会开始这样的事情? 编辑 好的,所以我没想到答案会得出相反的结论。无论如何,这个问题可能不在我的掌控之中。我也阅读了“重复的问题”,并且普遍的共识是“编写测试很好” ...是的,但是在这种特殊情况下不太有用。 在考虑为遗留系统编写测试时,我并不孤单。我将保留有关花费多少时间以及新测试发现问题的次数(以及没有发现问题的次数)的指标。我会回来,并从现在开始大约一年后用我的结果进行更新。 结论 因此,事实证明,基本上不可能将任何形式的正统测试都添加到现有代码中。代码正常工作后,您显然无法对测试进行红灯/绿灯测试,通常通常不清楚哪些行为对测试很重要,也不清楚不清楚从何处开始,当然也不清楚何时完成。真的,甚至问这个问题都错过了编写测试的重点。在大多数情况下,我发现使用TDD重写代码实际上比解密预期的功能和追溯添加单元测试要容易得多。解决问题或添加新功能时,情况有所不同,我认为现在是添加单元测试的时候了(如下所述)。最终,大多数代码都会被重写,通常比您预期的要早-我采用这种方法


7
使用验收和集成测试代替单元测试是否足够?
这个问题的简短介绍。我现在已经使用TDD,最近使用BDD已经超过一年了。我使用诸如嘲笑之类的技术来更有效地编写测试。最近,我开始了一个个人项目,为自己编写一个小小的资金管理程序。由于我没有遗留代码,因此从TDD开始是一个完美的项目。不幸的是,我没有体验到TDD的喜悦。它甚至破坏了我的乐趣,以至于我放弃了这个项目。 怎么了 好吧,我使用了类似TDD的方法来使测试/需求发展程序的设计。问题在于,超过一半的开发时间用于编写/重构测试。所以最后我不想实现任何其他功能,因为我需要重构并编写许多测试。 在工作中,我有很多遗留代码。在这里,我写了越来越多的集成和验收测试,以及更少的单元测试。这似乎不是一个坏方法,因为大多数错误是通过验收和集成测试检测到的。 我的想法是,最终我可以编写比单元测试更多的集成和验收测试。就像我说的那样,对于检测错误,单元测试并不比集成/验收测试好。单元测试也对设计有益。由于我曾经写过很多文章,所以我的类总是被设计为可测试的。此外,在大多数情况下,让测试/需求指导设计的方法可导致更好的设计。单元测试的最后一个优点是它们更快。我已经写了足够多的集成测试,知道它们可以和单元测试一样快。 在浏览网络后,我发现这里和那里提到的想法非常相似。您如何看待这个想法? 编辑 在一个例子中回答这个设计很好的例子,但是我需要对下一个需求进行大量重构: 首先,执行某些命令有一些要求。我编写了一个可扩展的命令解析器-从某种命令提示符下解析命令,并在模型上调用正确的命令。结果以视图模型类表示: 这里没有错。所有类都彼此独立,我可以轻松添加新命令,显示新数据。 下一个要求是,每个命令应具有其自己的视图表示形式-命令结果的某种预览。我重新设计了程序,以针对新要求实现更好的设计: 这也很好,因为现在每个命令都有自己的视图模型,因此也有自己的预览。 事实是,命令解析器已更改为使用基于令牌的命令解析,并且剥夺了其执行命令的能力。每个命令都有自己的视图模型,数据视图模型只知道当前的命令视图模型,而不知道必须显示的数据。 我现在想知道的是,新设计是否没有违反任何现有要求。我不必更改任何我的验收测试。我不得不重构或删除几乎每个单元测试,这是一大堆工作。 我想在这里展示的是在开发过程中经常发生的一种常见情况。旧的或新的设计都没有问题,它们只是随需求而自然变化-我的理解是,TDD的优点之一就是设计不断发展。 结论 感谢您的所有答案和讨论。在此讨论的总结中,我想到了一种方法,将在下一个项目中对其进行测试。 首先,我在像往常一样执行任何操作之前编写所有测试。 对于需求,我首先编写一些验收测试,以测试整个程序。然后,我为需要实现需求的组件编写了一些集成测试。如果有一个组件与另一个组件紧密协作以实现此要求,那么我还将编写一些集成测试,其中两个组件都需要一起测试。最后但并非最不重要的一点是,如果我必须编写一个具有高排列的算法或任何其他类(例如,序列化程序),我将为此特定类编写单元测试。所有其他类均未经测试,但未经任何单元测试。 对于错误,可以简化过程。通常,错误是由一个或两个组件引起的。在这种情况下,我将为测试该错误的组件编写一个集成测试。如果它与算法有关,我只会编写一个单元测试。如果不容易检测到发生错误的组件,我将编写验收测试以查找错误-这应该是一个例外。

7
在设计可测试性时如何处理静态实用程序类
我们正在尝试将我们的系统设计为可测试的,并在大多数零件中使用TDD进行开发。当前,我们正在尝试解决以下问题: 在各个地方,我们有必要使用静态辅助方法,例如ImageIO和URLEncoder(均为标准Java API)以及各种其他主要由静态方法组成的库(例如Apache Commons库)。但是,测试使用此类静态帮助程序类的方法极其困难。 我有一些解决此问题的想法: 使用可以模拟静态类的模拟框架(例如PowerMock)。这可能是最简单的解决方案,但感觉有点像放弃。 围绕所有这些静态实用程序创建实例化包装器类,以便可以将它们注入使用它们的类中。这听起来像是一个相对干净的解决方案,但是我担心我们最终将创建大量这些包装器类。 将对这些静态帮助器类的每个调用提取到一个可以重写的函数中,并测试我实际要测试的类的子类。 但是我一直认为这只是许多人在进行TDD时必须面对的问题-因此必须已经有解决此问题的方法。 使使用这些静态帮助器的类可测试的最佳策略是什么?

10
我们应该测试所有方法吗?
所以今天我和队友讨论了单元测试。当他问我“嘿,那堂课的考试在哪儿,我只看到一个?”时,整个事情开始了。整个类都是一个管理器(或服务,如果您喜欢这样称呼它),几乎所有方法都只是将东西委托给DAO,所以它类似于: SomeClass getSomething(parameters) { return myDao.findSomethingBySomething(parameters); } 一种没有逻辑的样板(或者至少我不认为像逻辑这样的简单委托),但是在大多数情况下(层分离等)很有用。我们进行了相当长时间的讨论,是否应该对它进行单元测试(我认为值得一提的是,我对DAO进行了完全单元测试)。他的主要论据是(显然)它不是TDD,并且有人可能希望查看测试以检查此方法的作用(我不知道它怎么可能更明显),或者将来有人可能希望更改该方法。实现并向其中添加新的(或更多类似“ any”的)逻辑(在这种情况下,我猜有人应该只测试该逻辑)。 不过,这让我思考。我们应该争取最高的测试覆盖率吗?还是仅仅是出于艺术的缘故?我根本看不出在进行以下测试之后有任何原因: getter和setter(除非他们实际上有一些逻辑) “样板”代码 显然,对这种方法(带有模拟)的测试将花费我不到一分钟的时间,但我想这仍然是浪费时间,并且每个CI都需要花费一毫秒以上的时间。 是否有任何合理/不“易燃”的理由来说明为什么要测试每一行(或尽可能多的行)代码?

5
促进可测试代码的设计原则是什么?(设计可测试代码与通过测试驱动设计)
我从事的大多数项目都将开发和单元测试隔离考虑,这使得以后编写单元测试成为噩梦。我的目标是在高级和低级设计阶段本身都牢记测试。 我想知道是否存在定义明确的设计原则来促进可测试的代码。我最近了解的一个这样的原理是通过依赖注入和控制反转的依赖反转。 我读过有一种叫做SOLID的东西。我想了解是否遵循SOLID原则间接导致了易于测试的代码?如果没有,是否存在任何明确的设计原则来促进可测试的代码? 我知道有些东西称为“测试驱动开发”。虽然,我对在设计阶段本身就考虑到测试的代码设计更感兴趣,而不是通过测试来推动设计。我希望这是有道理的。 与该主题相关的另一个问题是,为了能够为每个模块编写单元测试用例,是否可以重构现有产品/项目并更改代码和设计?

16
为什么在进行TDD时不一次编写所有测试?
TDD的红色-绿色-重构周期已经建立并被接受。我们编写一个失败的单元测试,并使其尽可能简单地通过。与为一个类编写许多失败的单元测试并使它们全部一次性通过相比,这种方法有什么好处。 测试套件仍可保护您避免在重构阶段编写错误的代码或犯错误,那么这有什么危害呢?有时,首先以“大脑转储”的形式首先编写一个类(或模块)的所有测试会更容易,以便一次编写所有预期的行为。

4
TDD-由内而外由内而外
使用TDD 构建应用程序Inside In与使用Inside Out构建应用程序有什么区别? 这些是我阅读的有关TDD和单元测试的书: 测试驱动开发:示例 测试驱动开发:实用指南:实用指南在Microsoft中开发 高质量PHP框架和应用程序的实际解决方案 。 NET xUnit测试模式:重构测试代码 单元测试的技巧:以.Net为例 ,以测试为指导的不断增长的面向对象软件中的示例 --->因为JAVA不是我的主要语言,所以这真的很难理解:) 通常,几乎所有的人都解释了TDD的基础知识和单元测试,但是很少提及构建应用程序的不同方式。 我注意到的另一件事是,这些书中的大多数(如果不是全部)在编写应用程序时都会忽略设计阶段。他们更多地专注于快速编写测试用例并让设计自行出现。 但是,我遇到了xUnit测试模式中的一段,该段讨论了人们处理TDD的方式。有2所学校在外面,在内部与内部。 遗憾的是,这本书没有对此进行详细说明。我想知道这两个案例的主要区别是什么。 什么时候应该使用它们中的每一个? 对于TDD初学者来说,哪个更容易掌握? 每种方法的缺点是什么? 有没有专门讨论该主题的材料?

14
TDD是否真的适用于复杂项目?
我问这个问题,关于我在TDD项目期间遇到的问题。在创建单元测试时,我注意到了以下挑战。 生成和维护模拟数据 维护大型模拟数据既困难又不切实际。当数据库结构发生变化时,这甚至变得更加困难。 测试GUI 即使具有MVVM和测试GUI的能力,也需要大量代码来重现GUI场景。 测试业务 我的经验是,如果将TDD限于简单的业务逻辑,则它会很好地工作。但是,由于测试组合(测试空间)的数量非常大,因此很难测试复杂的业务逻辑。 需求矛盾 实际上,很难捕获正在分析和设计中的所有需求。由于项目很复杂,很多情况下一个便笺的要求会导致矛盾。在实施阶段的后期发现了矛盾。TDD要求要求100%正确。在这种情况下,可以期望在创建测试期间会捕获到相互矛盾的需求。但是问题在于,在复杂的场景中情况并非如此。 我已经读过这个问题:TDD为什么起作用? TDD是否真正适用于复杂的企业项目,或者实际上是对项目类型的限制?
53 tdd 

10
如何测试测试?
我们测试代码以使其更正确(实际上,不正确的可能性较小)。但是,测试也是代码-它们也可能包含错误。而且,如果您的测试有错误,则很难使您的代码变得更好。 我可以想到测试中三种可能的错误类型: 逻辑错误,当程序员误解了手头的任务,并且测试按照他认为应该做的事情进行时,这是错误的; 基础测试框架中的错误(例如,泄漏的模拟抽象); 测试中的错误:测试的执行与程序员认为的稍有不同。 类型(1)错误似乎无法防止(除非程序员只是……变得更聪明)。但是,(2)和(3)可能很容易处理。您如何处理这些类型的错误?您有什么特殊策略可以避免它们吗?例如,您是否编写了一些特殊的“空”测试,仅检查测试作者的预设?此外,您如何调试已损坏的测试用例?

11
如果我需要设计来开始测试,我不明白TDD如何帮助我获得良好的设计
我试图围绕TDD,特别是开发部分,全神贯注。我看过一些书,但是我发现的书主要涉及测试部分-NUnit的历史,为什么测试很好,红色/绿色/重构以及如何创建字符串计算器。 好东西,但这只是“单元测试”,而不是TDD。具体来说,如果我需要一个设计来开始对其进行测试,我不理解TDD如何帮助我获得一个好的设计。 为了说明这一点,请想象一下这三个要求: 目录需要有产品列表 目录应记住用户查看过的产品 用户应该可以搜索产品 在这一点上,许多书从书本上摘下来,只是跳入“测试ProductService”,但他们没有解释如何得出结论,即首先有ProductService。这就是我要理解的TDD中的“开发”部分。 需要有一个现有的设计,但是实体服务之外的东西(也就是说:有一个Product,所以应该有一个ProductService)找不到地方(例如,第二个要求要求我有一个用户,但是我应该在哪里提醒该功能?搜索是ProductService的功能还是单独的SearchService?我怎么知道应该选择哪个?) 根据SOLID,我将需要一个UserService,但是如果我设计一个没有TDD的系统,则可能会得到一堆完整的Single-Method Services。TDD并不是一开始就让我发现自己的设计吗? 我是.net开发人员,但Java资源也可以使用。我觉得似乎没有真正的示例应用程序或书籍可以处理真正的业务应用程序。有人可以提供一个清晰的示例来说明使用TDD进行设计的过程吗?
50 java  c#  .net  tdd 

11
自动化测试的缺点是什么?
这个站点上有许多问题,可以提供有关自动测试可以带来的好处的大量信息。但是我没有看到代表硬币另一面的东西:缺点是什么?生活中的所有事情都是折衷方案,没有万灵药,因此,一定有一些正当理由不进行自动化测试。这些是什么? 以下是我提出的一些建议: 给定功能需要更多的初始开发时间 需要团队成员更高的技能水平 增加工具需求(测试执行者,框架等) 遇到失败的测试时,需要进行复杂的分析-该测试是由于我的更改而过时还是在告诉我我做错了? 编辑 我应该说我是自动化测试的坚定支持者,并且我不希望这样做。我想了解缺点是什么,所以当我去公司提出理由时,我看起来好像并没有扔下一个想象中的银弹。 另外,我明确地是不希望有人对我的上述示例提出异议。我确实认为必须存在一些不利因素(所有因素都需要权衡),我想了解它们是什么。

9
单元测试或测试驱动的开发值得吗?
我的工作团队正在迁移到Scrum,其他团队也开始使用单元测试和用户接受测试来进行测试驱动的开发。我喜欢UAT,但是对于测试驱动的开发或通常测试驱动的开发,我不出售单元测试。 看来编写测试是一项额外的工作,使人们在编写实际代码时显得cr不休,而且可能并不经常有效。 我了解单元测试如何工作以及如何编写它们,但是任何人都可以证明这确实是一个好主意,值得付出时间和精力吗? 另外,还有什么使TDD特别适合Scrum的?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.