Questions tagged «unit-testing»

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


11
使用模拟对象时,如何检测单元测试的依赖性问题?
您有一个X类,并且编写了一些验证行为X1的单元测试。还有一个类A,它把X作为依赖项。 为A编写单元测试时,您将模拟X。换句话说,在对A进行单元测试时,您将(假设)X的模拟行为设置为X1。时间的流逝,人们确实在使用您的系统,需要改变,X演变:您修改X以显示行为X2。显然,针对X的单元测试将失败,您需要对其进行调整。 但是A呢?修改X的行为后(由于X的模拟),针对A的单元测试不会失败。当使用“真实”(修改的)X运行时,如何检测A的结果会有所不同? 我期望得到以下答案:“这不是单元测试的目的”,但是单元测试有什么价值呢?它真的只是告诉您,当所有测试通过时,您还没有进行重大更改吗?当某个班级的行为发生变化时(有意或无意),您如何发现(最好以自动化方式)所有后果?我们不应该更多地关注集成测试吗?

18
单元测试真的有用吗?[关闭]
我刚刚获得CS学位,并且目前有初级.NET开发人员(C#,ASP.NET和Web表单)的工作。回到我上大学时,单元测试的主题确实涵盖了,但是我从来没有真正看到它的好处。我了解应该执行的操作,即确定代码块是否适合使用。但是,我之前从未真正编写过单元测试,也从未感到有必要这样做。 正如我已经提到的,我通常使用ASP.NET Web表单进行开发,最近我一直在考虑编写一些单元测试。但是我对此有一些疑问。 我读过单元测试通常是通过写“模拟”来进行的。虽然我理解了这个概念,但似乎无法弄清楚如何为完全动态的网站编写模拟文件,并且几乎所有内容都依赖于来自数据库的数据。例如:我使用很多具有ItemDataBound事件等的转发器(同样取决于“未知”数据)。 因此,问题1:是否经常为ASP.NET Web编写单元测试表单?如果是,那么:如何解决“动态环境”问题? 在开发时,我会经历很多反复的尝试。这并不意味着我不知道自己在做什么,而是我通常会写一些代码,点击Ctrl F5查看会发生什么。尽管这种方法在大多数情况下都能奏效,但有时我会觉得自己有些笨拙(由于我的经验不足)。有时我也会像这样浪费很多时间。 因此,问题2:你们会建议我开始编写单元测试吗?我认为这可能对我的实际实施有所帮助,但是我再次觉得这可能会使我慢下来。

17
为什么单元测试失败被视为不好?
在某些组织中,显然,软件发布过程的一部分是使用单元测试,但是在任何时间点,所有单元测试都必须通过。例如,可能会有一些屏幕以绿色显示所有通过的单元测试-这应该很好。 就我个人而言,出于以下原因,我认为不应该这样: 它提出了这样的想法,即代码应该是完美的,并且不应该存在错误-在现实世界中,对于任何大小的程序,这肯定是不可能的。 考虑将失败的单元测试是不利的。或者肯定会提出很难修复的单元测试。 如果在任何时间点所有单元测试都通过了,那么在任何时间点都没有软件状态的大图。没有路线图/目标。 它阻止了在实现之前预先编写单元测试。 我什至建议即使发布单元测试失败的软件也不一定是坏事。至少您会知道该软件的某些方面存在局限性。 我在这里想念什么吗?为什么组织希望所有单元测试都能通过?这不是生活在梦想世界中吗?难道这实际上并不能阻止对代码的真正理解吗?

10
如何激励同事编写单元测试?[关闭]
我们正在研究已经生产大约5年的大型产品。该代码库在工作。效果不是很好,但是可以正常工作。新功能投入生产并通过少量质量检查进行了测试。错误已修复,等等。但是除我以外,没有人在编写单元测试。没有人通过编写单元测试来确保所有特殊错误(测试用例)再也不会发生,从而利用“跟踪”错误的能力。 我已经和管理层谈过了。我已经和开发人员谈过了。我已经与整个公司的所有人进行了交谈。每个人都说:“是的,我们必须编写更多的单元测试!” 那是大约一年前。从那时起,我就开始引入预提交代码审查(Gerrit)和持续集成(Jenkins)。 我举行了一些有关单元测试的会议,还展示了编写单元测试的好处。但是似乎没有人对此感兴趣。 问题1:如何激励我的同事编写单元测试? 问题2:如何保持动力以遵循我的个人代码质量标准?(有时真的很令人沮丧!) PS:一些令人沮丧的事实(在1年内达成): 单元测试总数:1693 总“示例单元测试”:大约50 由我完成:1521 编辑:我期望太多了吗?这是我的第一个工作地点,我正在努力做到最好。 编辑2:根据所有答案,我为自己做了一个小清单。我已经与两位开发人员私下交谈过,我们进行了坦诚交谈。 其中一位告诉我,就像Telastyn所说的那样,他对单元测试真的很不满意。他说他想变得“更专业”,但是他需要一个启动。他还说,我们与所有开发人员(9-11岁左右)进行的单元测试会议很好,但是太拥挤了。嗯 一些批评家给我,但我会从中学到东西。(请参阅以下有关tdd kata会议的回答!) 另一位表示他对编写单元测试不感兴趣。他认为自己的工作足以应付他的薪水。他不想付出更多的努力。我非常无语。典型的9-5岁的“工人”。 下周,我将与其他开发人员交谈。 感谢您的出色回答(到目前为止!)和支持。我真的很感激!我学到了很多东西,非常感谢!

15
我们是否应该从一开始就设计代码以启用单元测试?
目前,我们的团队正在争论是否修改代码设计以允许单元测试是代码的味道,或者在什么程度上可以做到而又没有代码的味道。之所以如此,是因为我们只是刚刚开始实施几乎所有其他软件开发公司中都存在的实践。 具体来说,我们将提供一个非常薄的Web API服务。它的主要职责将是整理Web请求/响应并调用包含业务逻辑的基础API。 一个示例是我们计划创建一个将返回身份验证方法类型的工厂。我们不需要它继承一个接口,因为我们不希望它有任何具体类型。但是,要对Web API服务进行单元测试,我们需要模拟该工厂。 从本质上讲,这意味着我们要么设计Web API控制器类以接受DI(通过其构造函数或设置器),这意味着我们正在设计控制器的一部分,只是为了允许DI并实现我们原本不需要的接口,或者我们使用第三方框架(如Ninject)可以避免以这种方式设计控制器,但是我们仍然必须创建一个接口。 团队中的某些人似乎不愿意仅仅为了测试而设计代码。在我看来,如果您希望进行单元测试,则必须做出一些妥协,但是我不确定他们的担忧如何得到缓解。 需要明确的是,这是一个全新的项目,因此,它并不是真正地修改代码以进行单元测试。这是关于将要编写的代码设计为可单元测试的。

12
是否有原因未将测试与其测试代码内联地编写?
最近,我一直在阅读一些有关Literate Programming的文章,这让我开始思考...写得井井有条的测试(尤其是BDD风格的规范)在解释代码作用方面比散文效果更好,并且具有以下优点:验证自己的准确性。 我从未见过将测试与其代码内联地编写的测试。这是仅是因为语言在编写到相同的源文件中时不会趋向于将应用程序和测试代码分开(而没有人使之变得容易),还是人们在原则上将测试代码与应用程序代码分开呢?

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) …

11
单元测试是否可以帮助花旗避免这种昂贵的错误?
我读到了这句话:在合法交易被误认为测试数据15年之后,花在编程上的错误使花旗集团损失了700万美元。 在1990年代中期引入该系统时,程序代码过滤掉了从089到100的三位数分支代码的所有交易,并将这些前缀用于测试目的。 但是在1998年,公司在扩展业务时开始使用字母数字分支代码。其中包括代码10B,10C等,系统将该代码视为在排除范围内,因此,它们的交易已从发送给SEC的所有报告中删除。 (我认为这说明使用非显式数据指示符是次优的。填充并使用语义上显式的Branch.IsLive属性要好得多。) 除此之外,我的第一个反应是“单元测试会在这里有所帮助”……但是他们会吗? 我最近读了《为什么大多数单元测试会引起人们的兴趣浪费》,所以我的问题是:在引入字母数字分支代码后失败的单元测试会是什么样?

12
我的项目需要多大才能进行单元测试?[关闭]
我认为我的项目已解耦到足以进行单元测试的程度。但是,就笔迹和功能而言,我的项目到底需要多大才能使单元测试值得? 我们都会犯错,没有人能做到完美,但是我认为自己是一个体面的程序员,可以逐步解决小项目的错误。还是您的项目规模不限,都必须进行单元测试?

11
静态测试对于单元测试而言是否普遍“邪恶”?如果是的话,为什么瑞沙珀推荐它?[关闭]
我发现只有三种方法可以对C#.NET中静态的单元测试(模拟/存根)依赖性进行测试: 鼠 TypeMock JustMock 鉴于其中有两个不是免费的,而另一个没有发布1.0版,因此模拟静态内容并不是一件容易的事。 这是否构成静态方法和此类“邪恶”(就单元测试而言)?如果是这样,为什么harsharper希望我做任何可以静态的事情?(假设重新剃刀也不是“邪恶的”。) 澄清: 我是在谈论要对方法进行单元测试并且该方法在其他单元/类中调用静态方法的情况。根据单元测试的大多数定义,如果仅让被测方法在另一个单元/类中调用静态方法,则您不是单元测试,而是集成测试。(有用,但不是单元测试。)

6
强制执行单元测试的执行命令是不好的做法吗?
我正在为一个包含多个子模块的项目编写测试。我编写的每个测试用例彼此独立运行,并且清除测试之间的所有数据。 尽管测试是独立运行的,但由于某些情况需要多个子模块,因此我正在考虑执行执行顺序。例如,一个子模块正在生成数据,而另一个正在对数据运行查询。如果生成数据的子模块包含错误,则即使子模块本身工作正常,查询子模块的测试也将失败。 我无法使用虚拟数据,因为我正在测试的主要功能是与黑匣子远程服务器的连接,该服务器仅从第一个子模块获取数据。 在这种情况下,可以强制执行测试的执行顺序还是不好的做法?我感觉此设置中有异味,但找不到更好的方法。 编辑:问题来自于如何构建测试,其中一个测试是另一测试的设置?因为“先前”测试不是设置,而是测试执行设置的代码。

12
在单元测试中检查文件内容/编码是否被认为是“不良做法”?
有一点上下文:今天早些时候,我不得不更新我的另一位同事提供的一些SQL代码,由于它是一个很大的脚本,因此将其存储为单独的文件(然后在运行时读取并执行)。在执行此操作时,我不小心重新引入了几个月前的两个错误,即: 出于任何原因,ASCII文件都以UTF-16编码(同事通过电子邮件将其发送给我,这可能是导致该文件的原因)。 该脚本缺少初始SET语句(由于生产中使用了某些驱动程序,而本地没有进行全新安装,因此该脚本是必需的)。 经过大约一个小时的调试之后,我决定编写一些单元测试以确保不再发生这种情况(并在断言消息中包含一种快速修复它的方法,以便于将来的开发人员轻松修复)。 但是,当我推送此代码时,另一个同事(也是我们团队的负责人)走到我面前,告诉我,我不应该再做这些事情,因为: “这些东西不属于单元测试” “单元测试仅应用于检查代码流” 我现在很矛盾,因为我仍然认为自己做的没错,因为以后不会再引入此错误,但是这位同事还是一名资深人士,最终可以决定我们花时间在。我该怎么办?我这样做不对吗?是否被认为是不良做法?

11
单元测试不应该使用我自己的方法吗?
今天,我正在观看“ JUnit基础”视频,作者说,在程序中测试给定方法时,不应在此过程中使用其他自己的方法。 更具体地说,他正在谈论测试某种记录创建方法,该方法采用参数的名称和姓氏,并使用它们在给定表中创建记录。但他声称,在测试此方法的过程中,他不应使用其他DAO方法来查询数据库以检查最终结果(以检查记录是否确实由正确的数据创建)。他声称为此,他应该编写其他JDBC代码来查询数据库并检查结果。 我想我理解他的主张的精神:您不希望一种方法的测试用例取决于另一种方法(在本例中为DAO方法)的正确性,这是通过(再次)编写自己的验证来完成的/支持代码(应该更加具体和集中,因此代码更简单)。 但是,我内心的声音开始以诸如代码重复,不必要的额外努力之类的论点来抗议。在测试其他方法时只使用其中一些方法可以吗?如果其中一个没有按预期执行操作,则其自己的测试用例将失败,我们可以对其进行修复并再次运行测试电池。无需重复代码(即使重复的代码稍微简单一些)也无需浪费精​​力。 我对此有很强烈的感触,因为我最近编写了多个Excel - VBA应用程序(感谢Rubberduck for VBA进行了正确的单元测试),其中应用此建议将意味着很多额外的工作,而没有明显的好处。 您能否分享您对此的见解?

8
在不进行广泛模拟的情况下,应该如何编写单元测试?
据我了解,单元测试的重点是隔离测试代码单元。这意味着: 它们不应被代码库中其他地方不相关的代码更改破坏。 与集成测试相反(集成测试可能会中断),只有一个单元测试应该通过被测试单元中的错误来破坏。 所有这些暗示着,应该模拟掉测试单元的所有外部依赖关系。我的意思是所有外部依赖关系,而不仅仅是网络,文件系统,数据库等“外部层”。 这得出一个合理的结论,几乎每个单元测试都需要模拟。另一方面,谷歌对嘲笑的快速搜索显示了成千上万的文章声称“嘲笑是一种代码味道”,应该(尽管不完全)避免。 现在,到问题。 单元测试应如何正确编写? 它们和集成测试之间的界线到底在哪里? 更新1 请考虑以下伪代码: class Person { constructor(calculator) {} calculate(a, b) { const sum = this.calculator.add(a, b); // do some other stuff with the `sum` } } 可以在Person.calculate不模拟Calculator依赖关系的情况下测试该方法的测试(假定,它Calculator是不访问“外部世界”的轻量级类)可以视为单元测试吗?

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.