Questions tagged «unit-testing»

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

2
RSpec与Test :: Rails中的单元
我从来没有真正相信过从Ruby on Rails中的Test :: Unit切换到RSpec所获得的优势(尽管不时阅读有关RSpec的信息)。 大多数Rails项目似乎都在使用RSpec呢? (一些代码示例清楚地表明了一个相对于另一个的优势,将不胜感激)

7
如何提倡对私有代码进行单元测试?
我试图在工作组中倡导单元测试,但我经常遇到的反对意见是,它只能用于外部导出的API(这只是我们系统的最小和非关键部分),而不能用于内部和专用代码(现在仅具有功能测试)。 虽然我认为单元测试可以并且应该应用于所有代码,但是我如何说服我的同事?

1
科学计算库的单元测试
我以前在单元测试中有过一些经验,我称之为(不是贬义)经典的软件工程项目:MVC,带有用户GUI,数据库,中间层的业务逻辑等。现在,我我用C#编写了一个科学计算库(是的,我知道C#太慢了,使用C,不要重新发明轮子,所有这些,但是我们有很多人在C#中从事科学计算,我们有点需要)。就软件开发行业而言,这是一个小项目,因为我主要是自己写这篇文章,有时是在一些同事的帮助下编写的。另外,我并没有为此获得报酬,最重要的是,这是一个学术项目。我的意思是,我希望它有一天能达到专业水平,因为我正计划开源。 无论如何,该项目正在变得越来越庞大(大约18,000行代码,对于一个人的项目而言,我认为这是很大的),而且它也变得一发不可收拾。我正在使用git进行源代码控制,我认为我还不错,但是我正在像老派一样进行测试,我的意思是编写编写测试系统大部分内容的完整控制台应用程序,主要是因为我不知道如何在这种情况下进行单元测试,尽管我认为那是我应该做的。问题在于该库主要包含算法,例如图算法,分类器,数值解算器,随机分布等。我只是不知道如何为每种算法指定微小的测试用例,因为其中很多是随机的,我不知道如何验证正确性。例如,对于分类,有一些指标,例如精度和召回率,但是这些指标对于比较两种算法比判断一种算法更好。那么,如何在这里定义正确性? 最后还有性能问题。我知道它是一套完全不同的测试,但是性能是科学工具的重要功能之一,而不是用户满意度或其他软件工程指标。 我最大的问题之一是数据结构。我可以针对kd-tree进行的唯一测试是压力测试:插入许多随机向量,然后执行许多随机查询,然后与朴素的线性搜索进行比较。性能相同。使用数值优化器,我可以测试基准功能,但是再次,这是压力测试。我不认为这些测试可以归类为单元测试,最重要的是,它们不能连续运行,因为其中大多数都很繁重。但是我也认为这些测试需要完成,我不能只插入两个元素,弹出根,是的,它适用于0-1-n的情况。 那么,这种软件的(单元)测试方法是什么(如果有)?以及如何围绕代码-构建-提交-集成周期组织单元测试和繁重的单元测试?
15 c#  unit-testing 

8
单元测试-数据库耦合应用
在对集成到与数据库紧密耦合的应用程序中的模型进行单元测试的最佳方法是什么? 这里的特定情况是一个购物车-我希望能够测试购物车中商品的添加,删除和检索以及定价逻辑等。在我看来,这一切都需要数据库访问,尽管我已经读过好几次了。应该避免数据库访问。

4
测试驱动的开发是否迫使我遵循SOLID?
我从TDD的实践者那里听到很多东西,TDD的优势之一是它迫使开发人员遵循SOLID原则(单一职责,开放式封闭,Liskov替代,接口隔离和依赖倒置)。但是对我而言,只需编写一些测试(主要是单元测试)就足以理解遵循SOLID(从而创建可测试的体系结构)非常重要。 TDD是否会迫使开发人员更积极地遵循SOLID,而不仅仅是编写单元测试?

5
单元测试无效方法
为了修复应用程序中的错误,我postLogin通过将调用添加到名为的现有方法上来修改了一种名为的方法getShoppingCart。 码 protected void postLogin() { getShoppingCart(); } 但是,我不确定编写单元测试的最佳方法postLogin是什么。 方法1 使用Mockito中的verify可以简单地验证该方法是否已被调用。 verify(mock).getShoppingCart(); 方法2 通过获取用户购物车的值来测试方法调用的副作用。 AssertNotNull(user.getShoppingCart()); 一种方法比另一种更好吗?

5
switch语句-处理无法达到的默认情况
如果我使用switch语句来处理枚举(属于我的班级)中的值,并且每个可能的值都有一个大小写,是否值得添加代码来处理“默认”大小写? enum MyEnum { MyFoo, MyBar, MyBat } MyEnum myEnum = GetMyEnum(); switch (myEnum) { case MyFoo: DoFoo(); break; case MyBar: DoBar(); break; case MyBat: DoBat(); break; default: Log("Unexpected value"); throw new ArgumentException() } 我不认为这是因为永远无法到达此代码(即使使用单元测试也是如此)。我的同事不同意并认为这可以保护我们免受因将新值添加到MyEnum而导致的意外行为。 社区,你怎么说?

7
如何避免需要对私有方法进行单元测试
我知道您不应该测试私有方法,并且如果您看起来需要测试私有方法,那么那里可能会有一个类在等待发布。 但是,我不想拥有大量的类来测试它们的公共接口,我发现对于许多类来说,如果仅测试公共方法,最终我就不得不模拟很多依赖,而单元测试就是巨大且难以遵循。 我更喜欢在测试公共方法时嘲笑私有方法,而在测试私有方法时嘲笑外部依赖关系。 我疯了吗?

2
在哪里推动失败的测试?
我只是更改了GitHub存储库上的分支设置,所以我的[下一个]分支需要通过pull请求传递一个CI构建。 随后与许多团队成员进行了关于测试失败的讨论。 为了上下文... 该仓库有一个[大师]分支,只有PR'd成时,有一个释放,使[大师]包含代码为的最后一个版本,无论它是否是一个重大的,未成年人,修补程序,β,α-/预发行版本。 [next]分支是“默认”分支,我们打算保留“发布就绪”代码;从技术上讲,可以随时将该分支公诸于[master]并发布。 每个fork都有自己的dev分支,并为[next]贡献者PR。 当我审阅不重要的PR时,我会将贡献者的dev分支合并到我的“ review”分支中,如果我发现可以快速修复的问题,则将提交/推送更改以及新的(有时会失败)测试和PR返回贡献者的dev分支;当他们合并我的更改时,使新的失败测试通过,然后推送,它们的PR进行同步,然后将PR合并到[next]中。 但是这个问题不是关于通过测试,而是关于失败的测试。 测试失败记录了需要解决的问题。 已知的bug应该编写测试,以便我们知道什么不起作用。 从技术上讲,GitHub 问题列表(针对错误和/或关键 标签进行了过滤)也可以做到这一点。它是一个很好的做法,也有一堆失败的测试文档的bug? 在[next]上失败的构建意味着我们还没有准备好发布……但是,“准备发布”有点像“准备好”要孩子了-您从没有为此做好充分的准备,并且某些地方(重要性不一)将不可避免地出问题。 因此,我们只是将通过测试推向[next]。那么,将失败的测试推向何处呢?我的意思是,在PR /审查流程之外? 例如,一个用户在问题列表中报告了一个新错误,我想为其编写一个失败的测试套件-以便指定需要执行的操作以及在何处进行操作,这使新贡献者更容易上手最终PR修复。 我应该在哪里推动这些失败的测试?还是将失败的测试推送到任何地方甚至是个好主意?

1
单元测试API客户端和包装器
我一直在兜圈子,试图找出对我正在开发的API客户端库进行单元测试的最佳方法。该库具有一个Client基本上与API进行1:1映射的Wrapper类,以及一个额外的类,该类在的顶部提供了更加用户友好的界面Client。 Wrapper --> Client --> External API 我首先针对Client和编写了一系列测试Wrapper,实际上只是测试它们是否转发到操作的任何适当功能(Wrapper在上操作Client,并Client在HTTP连接上操作)。但是,我开始对此感到不舒服,因为我感觉自己正在测试这些类的实现,而不是接口。从理论上讲,我可以将这些类更改为具有另一个完全有效的实现,但是我的测试将失败,因为未调用我希望调用的函数。对我来说,这听起来像是脆弱的考验。 之后,我考虑了类的接口。测试应该验证类是否确实完成了其应做的工作,而不是他们是如何完成的。那我该怎么做呢?首先想到的是对外部API请求进行存根。但是,我担心过度简化外部服务。我见过的很多存根API的示例都给出了罐头响应,这听起来像是一种非常简单的方法,可以仅测试您的代码是否针对假API正确运行。另一种方法是模拟服务,这是不可行的,并且每当真实服务发生变化时就需要保持最新状态-感觉像是过分杀伤和浪费时间。 最后,我从程序员SE的另一个答案中读取了此内容: 远程API客户端的工作是发出某些调用-不多也不少。因此,它的测试应验证它是否发出了这些呼叫-不多也不少。 现在,我或多或少地确信-测试时Client,我需要测试的是它向API发出了正确的请求(当然,总有API会更改但我的测试继续通过的可能性-但这就是集成测试很有用的地方)。由于Client与API只是1:1的映射,因此在将一个有效实现更改为另一个之前,我的担心并没有真正适用-的每种方法只有一个有效实现Client。 但是,我仍然坚持Wrapper上课。我看到以下选项: 我对Client类进行存根处理,然后测试是否调用了适当的方法。这样,我做的与上述相同,但是将其Client作为API的替代。这使我回到了起点。再一次,这给了我测试实现而不是界面的不舒服的感觉。将Wrapper很可能使用了完全不同的客户端实现。 我创建一个模拟Client。现在,我必须决定对它进行模拟的程度-创建服务的完整模拟将花费很多精力(比库本身要付出更多的工作)。API本身很简单,但是服务却很复杂(本质上是一个对数据进行操作的数据存储)。再说一次,我将必须使模拟与real保持同步Client。 我只是测试是否正在发出适当的HTTP请求。这意味着Wrapper将通过一个真实的Client对象进行调用以发出这些HTTP请求,因此我并不是在单独测试它。这使得它有点可怕的单元测试。 因此,我对这些解决方案都不满意。你会怎么做?有正确的方法去做吗?


3
如何对返回集合的测试方法进行单元化,同时避免测试中的逻辑
我正在测试一种生成数据对象集合的方法。我想验证是否正确设置了对象的属性。一些属性将被设置为相同的东西;其他的将被设置为一个值,该值取决于它们在集合中的位置。做到这一点的自然方法似乎是循环。但是,Roy Osherove强烈建议不要在单元测试中使用逻辑(Art of Unit Testing,178)。他说: 包含逻辑的测试通常一次只能测试多个对象,因此不建议这样做,因为该测试的可读性和脆弱性更高。但是测试逻辑也会增加复杂性,其中可能包含隐藏的错误。 通常,测试应该是一系列没有控制流的方法调用,甚至没有try-catch,并且带有断言调用。 但是,我看不出我的设计有什么问题(您还如何生成数据对象列表,其中某些值取决于它们在序列中的位置?无法完全分别生成和测试它们)。我的设计中是否存在非测试友好的问题?还是过于刻板地致力于Osherove的教学?还是有一些我不知道的秘密单元测试魔术可以解决这个问题?(我正在用C#/ VS2010 / NUnit编写,但是如果可能的话,寻找与语言无关的答案。)

1
我是否应该编写测试以证明删除代码可修复错误?
有时候,我会遇到这样的情况:修复错误需要删除一段代码。TDD的纯粹主义者会(我认为)提倡编写一个失败的测试,删除代码,然后查看测试通过。 现在,有一个测试断言某些代码已被删除真是很奇怪。当然,我想它可以确保没有人去研究源代码控制并将该代码放回去,但这值得吗?如果值得的话,它似乎比为已添加的代码编写测试要有价值,对吧?
14 unit-testing  tdd  bug 

4
测试具有随机行为的程序的最佳实践是什么?
在进行研发工作时,我经常发现自己编写的程序在行为上有很大的随机性。例如,当我从事基因编程工作时,我经常编写生成并执行任意随机源代码的程序。 测试此类代码的问题在于,错误通常是间歇性的,并且很难重现。这不仅仅是将随机种子设置为相同的值并重新开始执行。 例如,代码可能从内核环形缓冲区读取一条消息,然后对消息内容进行条件跳转。自然,当以后尝试重现该问题时,环形缓冲区的状态将已更改。 即使此行为是一种功能,它也可能以意想不到的方式触发其他代码,从而经常揭示出单元测试(或人工测试人员)找不到的错误。 是否有建立此类测试系统的最佳实践?如果是这样,一些参考资料将非常有帮助。如果没有,欢迎任何其他建议!

4
通过使用单元测试超时来衡量方法的性能是一个好主意吗?
在有非功能性需求的项目中,该非功能性需求指定了特定操作的最长时间执行时间,QA必须在精确负载下使用精密硬件检查专用设备上此动作的性能,硬件和负载均在需求中指定。 另一方面,对源代码的一些错误更改可能会严重影响性能。在源代码到达源代码控制并由QA部门验证之前尽早注意到这种负面影响,这可能会因为QA部门报告问题而浪费时间,而开发人员稍后再修复它会造成损失。 为此,这是一个好主意: 要使用单元测试有花了执行相同action²时间的想法ñ倍, 要在C#中通过属性使用每次测试超时[TestMethod, Timeout(200)]? 我期望这种方法会出现几个问题: 从概念上讲,单元测试并非真正做到这一点:它们应仅测试代码的一小部分,仅此而已:既不检查功能需求,也不进行集成测试,也不进行性能测试。 考虑到这些测试不存在初始化和清除功能,或者它们太短而无法影响结果,Visual Studio中的单元测试超时是否真的可以衡量预期的结果? 用这种方法衡量性能很难看。在独立于硬件,负载等因素的任何计算机上运行基准测试,就像进行基准测试一样,表明一种数据库产品总是比另一种数据库产品更快。另一方面,我不希望这些单元测试是确定的结果,也不希望质量检查部门使用这些东西。这些单元测试将仅用于提供有关预期性能的一般概念,并且实质上是在提醒开发人员,他的最后修改破坏了某些内容,从而严重影响了性能。 对于这些测试,无法进行测试驱动开发(TDD)。首先,在开始实施代码之前它将如何失败? 性能测试太多将影响运行测试所需的时间,因此此方法仅限于短期操作。 考虑到这些问题,如果将此类单元测试与质量保证部门的实际性能指标结合使用,我仍然觉得很有趣。 我错了吗?还有其他问题使其完全不能使用单元测试吗? 如果我错了,那么在源代码到达源代码控制并由质量检查部门验证之前,警告开发人员该源代码的更改严重影响性能的正确方法是什么? ¹实际上,单元测试只能在具有相当硬件性能的开发人员PC上运行,从而缩小了永远无法通过性能测试的最快计算机与永远无法通过性能测试的最慢计算机之间的差距。 ²实际上,我的意思是一段相当短的代码,需要花费几毫秒来运行。

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.