Questions tagged «unit-testing»

单元测试是一种测试源代码的各个单元以确定它们是否适合使用的方法。

2
单元测试和集成测试的代码覆盖率报告是分开的,还是两者都有一个报告?
应该为单元测试和集成测试提供单独的代码覆盖率报告,还是为两者提供一个代码覆盖率报告? 其背后的想法是,代码覆盖率使我们能够确保我们的代码已被尽可能多的测试所覆盖(无论如何,现在无论如何机器)。 拥有单独的报告更方便我们了解单元测试未涵盖的内容以及集成测试未涵盖的内容。但是这样一来,我们看不到总覆盖率。

1
游戏行业是否对游戏/渲染的视觉部分使用自动化测试?怎么样?
游戏的某些部分易于以自动化方式进行测试(逻辑,数学,输入处理);但是还有很多是纯视觉的,并且不容易测试。 如果游戏行业将所有这些都留给人工测试,我会感到惊讶。里面有足够的钱,我想应该已经投入了至少对游戏的某些视觉方面进行回归测试的能力。 这是真的?如果是这样,可以测试游戏渲染的可能方式有哪些?捕获输出并比较图像(这可以可靠吗?)?从低级别拦截图形卡中的数据?正在捕获通往图形卡的顶点信息(等)?似乎有很多可能性;但我找不到关于此的任何信息:( 注意:这个问题被标记为对此的重复,但是我并不是要问具体的技术/框架/工具如何做到这一点,而是要更广泛地了解这种做法的想法以及实际的游戏行业(如果他们做的)。

2
单元测试副作用繁重的代码
我开始写C ++代码来运行机器人,如果可以的话,我不知道如何合并单元测试。我提供了一个库,该库允许为机器人创建“命令”,这些命令会自动调度和执行。创建这些命令的机制是继承一个命令基类它们提供,并执行虚拟void Initialize(),void Execute()和void End()方法。这些功能纯粹是出于其副作用而运行,这些副作用会对机器人产生影响(运行电动机,伸出活塞等)。因此,除了模拟整个库之外,我几乎看不到任何将单元测试附加到代码的地方,这样我就可以检查机器人的虚拟前后状态。有没有一种方法可以对此进行单元测试,而不会造成太大的负担? 编辑 我想我可能对库的功能产生了误导。该库提供了机器人以及命令/调度系统的大部分接口,因此它不像模拟命令基类那么简单,我必须模拟整个硬件接口。不幸的是,我没有时间这样做。

1
“正当的做法”有多少嘲笑?
我开玩笑地为这个问题命名,因为我确定“取决于情况”,但是我有一些具体的问题。 在具有许多深层依赖项的软件中工作时,我的团队已经习惯了使用相当广泛的模拟将每个代码模块与其下的依赖项分开的习惯。 因此,令我惊讶的是Roy Osherove在此视频中建议您仅在5%的时间内使用模拟。我猜我们坐在70-90%之间。我也时常看到其他类似的指导。 我应该定义我认为是“集成测试”的两类,它们是如此不同,以至于它们实际上应该被赋予不同的名称:1)集成多个代码模块的进程内测试;以及2)进行对话的进程外测试。到数据库,文件系统,Web服务等。我关心的是类型#1,这些测试将所有代码模块都集成在进程中。 我阅读的许多社区指南都建议您应该使用大量独立的,细粒度的单元测试,以及少量的粗粒度的端到端集成测试,因为单元测试会为您提供有关确切位置的精确反馈可能已经创建了回归,但是设置繁琐的粗略测试实际上验证了系统的更多端到端功能。 鉴于此,似乎有必要经常使用模拟来隔离这些单独的代码单元。 给定一个对象模型,如下所示: ...还要考虑到我们应用程序的依赖深度比我在该图中适合的深度要深得多,因此在2-4层和5-13层之间有多层N。 如果我想测试在单元#1中做出的一些简单的逻辑决定,并且是否将每个依赖项都构造函数注入到依赖于它的代码模块中,例如将2、3和4构造函数注入到模块1中,图片,我宁愿将2、3和4的模拟物注入1。 否则,我将需要构造2、3和4的具体实例。这可能比仅仅进行一些额外的键入要困难得多。通常2、3和4会有构造器要求,要满足这些挑战可能很困难,根据图(并根据我们项目的实际情况),我将需要构造N到13的具体实例,以满足N的构造器。 2 3 3 当我需要2、3或4以某种方式运行时,这种情况变得更具挑战性,以便我可以测试#1中的简单逻辑决策。我可能需要一次理解整个对象图/树并“在逻辑上进行推理”,以使2、3或4以必要的方式运行。做myMockOfModule2.Setup(x => x.GoLeftOrRight())。Returns(new Right());通常看起来容易得多。当模块2告诉它正确时,测试模块1是否按预期响应。 如果我要一起测试2 ... N ... 13的具体实例,那么测试设置将非常大,并且几乎是重复的。测试失败可能无法很好地指出回归失败的位置。测试不会是独立的(另一个支持链接)。 当然,对底层进行基于状态的测试,而不是基于交互的测试,通常是合理的,因为这些模块很少具有任何进一步的依赖性。但似乎从定义上讲,模拟几乎是必要的,以隔离最底层之上的任何模块。 考虑到所有这些,谁能告诉我我可能会缺少什么?我们的团队过度使用模拟吗?还是在典型的单元测试指南中可能存在一些假设,即大多数应用程序中的依赖层将足够浅,因此测试集成在一起的所有代码模块确实是合理的(使我们的案例“特殊”)?或者,也许是不同的,我们的团队是否没有适当地限制我们有限的环境?

3
重构大型方法以确保我不会破坏任何内容时,会有什么帮助?
我目前正在重构大型代码库的一部分,而没有任何单元测试。我试图以残酷的方式重构代码,即试图猜测代码在做什么,什么更改不会改变它的含义,但是没有成功:它随机破坏了整个代码库的功能。 请注意,重构包括将旧版C#代码移动到更具功能性的样式(旧版代码未使用.NET Framework 3和更高版本的任何功能,包括LINQ),在代码可能会从中受益的地方添加了泛型,等等。 考虑到要花多少钱,我不能使用形式化方法。 另一方面,我认为至少要严格遵循“任何重构的遗留代码都应带有单元测试”的规则,无论它要花多少钱。问题在于,当我重构500 LOC私有方法的一小部分时,添加单元测试似乎是一项艰巨的任务。 什么可以帮助我了解哪些单元测试与给定的代码相关?我猜测对代码进行静态分析会有所帮助,但是我可以使用哪些工具和技术: 确切知道我应该创建什么单元测试, 和/或知道我所做的更改是否以与现在不同的方式影响了原始代码?

4
在单元测试中,为什么要创建两次存储库?
前几天,我在阅读有关单元测试的内容时,看到了一些示例,人们在其中创建了一个存储库界面(即IExampleRepository),然后创建了真实的存储库(public class ExampleRepository : IExampleRepository)和一个用于单元测试的存储库(FakeExampleRepository : IExampleRepository)。 在中,IExampleRepository他们实现了与中相同的方法ExampleRepository,但是使用了不同的Linq查询。 确切的目的是什么?我认为对代码进行单元测试的一部分是确保一种方法正常工作吗?但是,当我使用两个完全不同的查询时,一个用于“真实”查询,另一个在测试中,该测试有多大意义?

6
针对REST服务器测试REST客户端。夹具怎么做?
在编写单元测试时,通常使用固定装置:可测试的数据很少,因此我们可以说:1.让所有客户都应该包括Willy Wonka。2.删除客户端3,现在获取客户端不应再包括Willy Wonka。 单元测试很好。使用设置/拆卸来重新加载固定装置或回滚事务。因此,测试可以在事务内部完成创建,更新和删除操作。新的临时数据仅持续测试时间,然后被重置。 但是,当我们将REST服务器与REST客户端分离时该怎么办? 我们要确保REST客户端不仅正确读取,而且正确创建,更新和删除。 对于如何针对远程测试REST服务器执行此操作,我找不到任何示例或建议。 假设我有一个仅测试灯具的测试REST服务器。HTTP的整个无状态性质意味着很难发送“ BEGIN TRANSACTION”和“ ROLLBACK TRANSACTION”或“ RELOAD FIXTURES”类型的消息,对吗? 我不能成为第一个这样做的人,所以我觉得我需要以不同的方式来思考这个问题。 有什么建议么?
10 unit-testing  api  rest 

2
使用动态语言创建模拟时如何检测类型错误?
在执行TDD时会出现问题。经过几次测试通过后,某些类/模块的返回类型发生了变化。在静态类型的编程语言中,如果在其他某个类的测试中使用了先前的模拟对象,并且未对其进行修改以反映类型更改,则将发生编译错误。 但是,对于动态语言,可能无法检测到返回类型的更改,并且其他类的测试仍将通过。当然,可能会有集成测试稍后会失败,但是单元测试会错误地通过。有什么办法可以避免这种情况? 用一个简单的示例(在某些组合语言上)更新... 版本1: Calc = { doMultiply(x, y) {return x * y} } //.... more code .... // On some faraway remote code on a different file Rect = { computeArea(l, w) {return Calc.doMultipy(x*y)} } // test for Rect testComputeArea() { Calc = new Mock() Calc.expect(doMultiply, 2, 30) // …

5
在这种情况下,坚持每个测试一个断言是否愚蠢的一致性?
我有一个正在测试的课程。该类具有一个功能:apply(List<IRule> rules, List<ITarget> targets); 在一个测试中,我想确保每个目标都已通过一个规则,例如: rule1.AssertWasCalled(fnord => fnord.Test(target1)); rule1.AssertWasCalled(fnord => fnord.Test(target2)); rule1.AssertWasCalled(fnord => fnord.Test(target3)); 在我看来,将自己限制在一条断言中就等于是妖精。在这个假设中我是否正确,还是可以通过其他方式断言每个目标实际上都已经过测试?

5
如何对重构为策略模式的功能进行单元测试?
如果我的代码中有一个像这样的函数: class Employee{ public string calculateTax(string name, int salary) { switch (name) { case "Chris": doSomething($salary); case "David": doSomethingDifferent($salary); case "Scott": doOtherThing($salary); } } 通常,我会使用工厂类和策略模式将其重构为使用多态性: public string calculateTax(string name) { InameHandler nameHandler = NameHandlerFactory::getHandler(name); nameHandler->calculateTax($salary); } 现在,如果我正在使用TDD,那么calculateTax()在重构之前,我将对原始版本进行一些测试。 例如: calculateTax_givenChrisSalaryBelowThreshold_Expect111(){} calculateTax_givenChrisSalaryAboveThreshold_Expect111(){} calculateTax_givenDavidSalaryBelowThreshold_Expect222(){} calculateTax_givenDavidSalaryAboveThreshold_Expect222(){} calculateTax_givenScottSalaryBelowThreshold_Expect333(){} calculateTax_givenScottSalaryAboveThreshold_Expect333(){} 重构后,我将具有Factory类NameHandlerFactory和的至少3个实现InameHandler。 我应该如何重构我的测试?我应该claculateTax()从中删除单元测试,EmployeeTests并为的每个实现创建一个Test类InameHandler吗? 我也应该测试工厂课程吗?

3
在“经常提前发布”环境中进行单元测试有什么意义?
在过去的一年左右的时间里,我带动了我的团队朝着经常提前发布的开发模式发展(又名:快速应用程序开发,而不是敏捷)。有关关闭构建方式的更多信息,请在此处查看我的答案: 一种提高RAD环境中发布质量的简单方法 当我们采用RAD时,人们是非常独立的,他们首先进行单元测试。集成测试发生在过程的后期。对于他们来说,这是自然的过程,无需太多正式的强制措施。现在情况大不相同了: 整个平台与已建立的内部版本/发行版很好地集成在一起,可在客户端工作,没有任何热点。 新功能需求不断涌现,我们会逐步构建它们。 系统的整体动力非常重要,因为尽管独立的开发小组可能会正确地遵循流程,但由于复杂,非显而易见的情况而导致了重大故障。 系统的许多部分都涉及新算法和研究投入,因此并非总是可以正确地预见到挑战(以及测试机制),例如在定义明确的软件中进行功能测试。 最近,我试图获得更好的整体情况,以查看我们是否需要改进流程。当我和我的团队坐下时,他们中的许多人都拒绝了:“我们不再进行单元测试了!” 而其他人则认为我们不应该立即开始,因为它将永远无效。 单元测试在相对成熟的系统中有用吗?我们是否至少需要根据单元的成熟度来权衡测试范围?单元测试会减慢开发速度吗?是否需要以其他方式评估单元测试? 在经常提前发布的环境中测试成熟平台的最佳实践是什么?
10 unit-testing  rad 

9
我应该将对象传递给构造函数,还是在类中实例化?
考虑以下两个示例: 将对象传递给构造函数 class ExampleA { private $config; public function __construct($config) { $this->config = $config; } } $config = new Config; $exampleA = new ExampleA($config); 实例化课程 class ExampleB { private $config; public function __construct() { $this->config = new Config; } } $exampleA = new ExampleA(); 处理将对象添加为属性的正确方法是哪种?我什么时候应该使用另一个?单元测试会影响我应该使用的内容吗?

3
我们需要测试数据还是可以依靠单元测试和手动测试?
我们目前正在开发一个中型/大型PHP / MySQL项目。我们正在使用PHPUnit&QUnit进行单元测试,并且有两个全职测试人员正在手动测试应用程序。我们的测试(模拟)数据当前是使用SQL脚本创建的。 我们在维护测试数据脚本方面遇到问题。业务逻辑非常复杂,测试数据中的一个“简单”更改通常会在应用程序中产生多个错误(不是真正的错误,只是无效数据的产物)。由于我们不断创建和更改表,因此这已成为整个团队的一大负担。 我真的看不到在脚本中维护测试数据的意义,因为可以使用UI在大约5分钟内将所有内容手动添加到应用程序中。我们的PM不同意,并说拥有无法使用测试数据进行部署的项目是一种不良做法。 我们是否应该放弃使用测试数据来维护脚本,而只是让测试人员在没有数据的情况下测试应用程序?最佳做法是什么?

3
调用供应商Web服务的单元测试方法
我有一类具有一个公共方法Send()和一些私有方法的类。它调用几个Web服务并处理响应。该处理以私有方法完成。 我想对代码进行单元测试。我的理解是,单元测试应该单独测试我的代码(即模拟供应商的响应)。 我还认为私有方法不需要进行单元测试,但是如果我仅测试Send()方法,我的代码就不会被单独测试,而取决于供应商的共鸣。 然后是否应该将我的私有方法公开,以便可以通过模拟响应对其进行测试?这似乎是不好的做法,因为我只有全班同学才需要给他们打电话。 道歉,如果这是一个基本问题,对单元测试来说还很新。 我正在使用C#和VS2010

3
使球在TDD上滚动
我是一个开发团队的成员,该团队与许多其他团队一起维护和改进已使用了至少15年的应用程序。最初构建和设计TDD时闻所未闻。 该应用程序相当稳定,我们很少遇到显示错误,但是我们每周平均会发现大约一两个错误,这严重降低了服务质量。这些错误要花很长时间才能找到并修复,这在很大程度上是因为手指指向的,而我们仅有的测试是接口测试。因为在修复该错误之前浪费了很多时间,所以我和另一个开发人员计划提出测试驱动开发。即将进行新的大修,我们希望在新模块上完成几乎完整的单元测试,我们还计划建议为我们必须更改的任何遗留代码(例如,错误修复或功能实现)构建测试单元。 ),但不要花时间为尚未引起问题的代码开发测试用例。 对我来说,这似乎是合理的。本月,我们修复了一个错误,该错误花费了两周的时间,但是如果完成了单元测试,则可以在部署之前发现该错误。但是对于我们的经理们来说,他们好像要花更多的钱。 我如何说服我们的客户他们想花钱进行单元测试和测试驱动的开发?是否有任何研究表明单元测试的投资回报率?
10 unit-testing  tdd 

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.