Questions tagged «unit-testing»

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

1
如何对数据库逻辑进行单元测试?
关于TDD,我仍然遇到一个小问题。 我需要一种方法,该方法将从数据层(linq2SQL)中获取已过滤数据的特定记录集。请注意,我使用的是从DBML生成的linq生成的类。现在的问题是我要为此编写测试。 我是否: a)首先将记录插入测试中,然后执行方法并测试结果 b)使用数据库中可能存在的数据。不热衷于这种逻辑会导致事情破裂。 c)你有什么建议?
12 c#  unit-testing 

2
我应该对子类还是抽象父类进行单元测试?
我有一个简单的实现,如Effective Java的第18项(此处扩展了讨论)。它是一个抽象类,提供2个公共方法methodA()和methodB(),这些方法调用子类方法来“填补我无法以抽象方式定义的空白”。 我首先通过创建一个具体的类并为其编写单元测试来开发它。当第二个类到来时,我能够提取常见的行为,在第二个类中实现“缺失的差距”,并且已经准备就绪(当然,单元测试是为第二个子类创建的)。 时光流逝,现在我有4个子类,每个子类实现3个受保护的短方法,这些方法非常具体地针对其具体实现,而骨架实现则完成所有常规工作。 我的问题是,当我创建一个新的实现时,我会重新编写测试: 子类是否调用给定的必需方法? 给定的方法是否具有给定的注释? 从方法A中可以获得预期的结果吗? 从方法B中可以获得预期的结果吗? 虽然看到了这种方法的优点: 它通过测试记录了子类需求 如果重构有问题,它可能会很快失败 对子类进行整体测试,并通过其公共API进行测试(“ methodA()是否起作用?”而不是“此受保护的方法起作用吗?”) 我的问题是对新子类的测试基本上是理所当然的:-这些测试在所有子类中都相同,它们只是更改方法的返回类型(最基本的实现是通用的)和属性I检查测试的断言部分。-通常,子类没有针对其的测试 我喜欢测试集中于子类本身的结果并防止其重构的方式,但是实施测试只是“手动工作”,这一事实使我觉得我做错了。 测试类层次结构时,此问题常见吗?我该如何避免呢? ps:我考虑过测试骨架类,但是创建一个抽象类的模拟对象以进行测试也很奇怪。而且我认为,对抽象类进行的任何重构会改变子类所不期望的行为,因此不会很快被注意到。我的胆量告诉我,“整体”测试子类是这里的首选方法,但是请随时告诉我我错了:) ps2:我已经在Google上搜索了,发现了许多与此主题有关的问题。其中之一是这样的一个具有很大的答案从奈杰尔·索恩,我的情况下,将他的“1号。” 那太好了,但是我现在不能重构,所以我不得不忍受这个问题。如果我可以重构,我会将每个子类都作为一种策略。可以,但是我仍然会测试“主类”并测试策略,但是我不会注意到任何重构会破坏主类和策略之间的集成。 ps3:我找到了一些答案,说测试抽象类“可以接受”。我同意这是可以接受的,但是我想知道在这种情况下哪种方法更可取(我仍然从单元测试开始)

3
单断言单元测试不会违反DRY原理吗?
每当我编写单元测试时,我总是试图在每个测试中使用一个断言,以便在测试失败时简化调试。但是,当我遵循这个规则时,我感到我在每个测试中都在不断复制相同的代码,并且通过进行更多的测试,变得更难回头阅读和维护。 那么单断言测试是否违反DRY? 而是否有一个很好的规律可循找到了很好的平衡,就像刚有每个方法一个测试?* *我意识到可能没有一种适合所有需求的解决方案,但是有没有建议的解决方法?


5
RSpec和Cucumber真的值得吗?
我知道大多数RoR程序员都在测试成瘾者,并且我了解大型测试套件的优势,但是当我开始测试时,我从来没有得到如此大型的套件,而且我总是想知道“我是否以正确的方式进行测试?真的有效率吗?”。我经常处理集成测试,仅测试应用程序的行为方式。 首先,测试真的值得吗?我的意思是,花在编写测试上的时间真的值得吗? 然后,我使用RSpec,我最近发现了Cucumber,使用了一段时间,但我不知道编写所有这些步骤是否真的值得一试?我知道我可以重用步骤,但是我不知道这些步骤是否太完整:例如,我一直在使用a,Given I am logged in as (.+)但是我不知道是否必须在其定义中说,Given there's a user called $1因为如果创建了它就可以复制用户但这并不值得总是先走一步Given I am logged in as (.+)。很多代码可能很少有用。我猜每天测试的零件上都没有新的错误……与RSpec相比,Cucumber真的值得吗?

2
将单元测试添加到旧的普通C项目中
标题说明了一切。我公司正在将微控制器设备的旧固件项目重复使用,完全用纯C语言编写。 有些部分显然是错误的,需要更改,并且这些部分来自C#/ TDD背景,我不喜欢无测试地随机重构内容以确保功能保持不变的想法。此外,我已经看到,在很多情况下,通过微小的更改就引入了难以发现的错误(如果使用回归测试,我相信这是可以解决的)。为避免这些错误,需要格外小心:很难在代码周围跟踪大量的全局变量。 总结一下: 在重构之前,如何在现有的紧密耦合代码中添加单元测试? 您推荐什么工具?(重要性不高,但仍然很高兴知道) 我没有直接参与编写此代码(我的责任是一个可以通过多种方式与设备交互的应用程序),但是如果有可能使用它们时,如果抛弃了良好的编程原则,那将是很糟糕的。

2
测试-内存中数据库与模拟
在编写测试时,为什么有人要使用内存数据库来模拟数据呢? 我可以看到内存数据库对于测试一个人的存储库可能是有益的。但是,如果使用框架(例如Spring Data),则测试存储库将测试框架,而不是测试应用程序逻辑。 但是,模拟似乎更快,并且遵循编写单元测试和TDD时通常采用的相同模式。 那我想念什么呢?何时/为什么内存数据库会受益?

2
单元测试以测试域对象的创建
我有一个单元测试,如下所示: [Test] public void Should_create_person() { Assert.DoesNotThrow(() => new Person(Guid.NewGuid(), new DateTime(1972, 01, 01)); } 我声称这里创建了一个Person对象,即验证不会失败。例如,如果Guid为null或生日早于01/01/1900,则验证将失败并且将引发异常(意味着测试失败)。 构造函数如下所示: public Person(Id id, DateTime dateOfBirth) : base(id) { if (dateOfBirth == null) throw new ArgumentNullException("Date of Birth"); elseif (dateOfBith < new DateTime(1900,01,01) throw new ArgumentException("Date of Birth"); DateOfBirth = dateOfBirth; } 这是测试的好主意吗? 注意:我遵循经典方法对单元模型进行单元测试(如果有)。

3
如何正确处理用于python中的单元测试的全局参数?
我们正在实现许多算法,这些算法通常具有许多共享的,众所周知的和与安全性相关的参数。 当前,我们仅使用一个包含所有参数和两个预定义全局对象的类: class PublicParams(object): p = q = 0 def __init__(self, p, q): self.p = p self.q = q # used for tests publicParams_test = PublicParams(15,7) # Some 2048 bit numbers for example publicParams_secure = PublicParams(128378947298374928374,128378947298374928374) 然后,算法将一个PublicParams对象作为默认为生产性的参数publicParams_secure def AlgoOne(n, publicParams = publicParams_secure): # do stuff with publicParams.p # ... AlgoTwo(x, …

2
测试(确定性)算法有多个或难以证明正确的正确答案
我想前言本认为这个问题是相似的,但我的问题不涉及随机性,只是挑剔的决定,所以回答“使用已知的种子”并没有真正适用。同样,这个问题是相似的,但是我也不希望算法会失败-我只是不知道哪种方法正确。 这个问题是在测试图形算法时出现的。但绝不仅限于此。某些算法(例如A *)可以有多个正确答案。根据您的确切实现,您可能会得到几个答案中的任何一个,每个答案都是正确的。但是,这会使他们难以测试,因为您不知道它会提前吐出哪一个,并且手工计算答案非常耗时。 在我的特定情况下,我通过修改Floyd-Warshall使其吐出所有可能的最短路径来解决它,并花了一些时间进行测试。它具有本身就是一个好的功能的好处。然后,我可以根据FW已知的正确路径测试其他功能(如果返回的路径是FW为该开始/结束对返回的路径中的任何一条,那是正确的)。当然,由于FW的工作原理,这仅适用于密集图,但它仍然很好。 但是,这对于具有此特征的所有算法可能并不总是可行的。到目前为止,我想出的最佳答案是测试正确答案的特征,而不是正确答案本身。要返回最短路径算法,您可以对照已知的正确成本检查返回路径的成本,并确保路径有效。 此方法可行,但存在更多的正确性标准时,可能冒着无法正确验证所有内容的风险,尤其是在验证本身很复杂的情况下(例如,在存在正确算法的情况下,验证最小生成树是一个已知的难题;可能比构建MST本身),在这种情况下,您现在必须广泛测试测试代码。更糟:大概您必须构造一个MST来测试MST验证算法,因此您现在遇到了一个很好的方案,其中MST测试依赖于MST验证算法的工作,而MST验证算法测试依赖于MST生成代码的工作。 最后,有一种“便宜的方法”,它涉及观察输出,手工验证输出,然后对测试进行硬编码以测试刚刚验证的输出,但这并不是一个好主意,因为您可能每次都要修改测试稍微更改实现(这是自动化测试应该避免的)。 显然,答案取决于您在某种程度上要测试的确切算法,但是我想知道是否有“最佳实践”来验证具有几个确定的,确定性的“正确”输出的算法,但是这些精确的正确输出很难做到提前知道,可能事后甚至很难核实。

3
如何用硬编码对象模拟方法?
我正在研究具有多层的应用程序。数据访问层从数据源检索和保存数据,业务逻辑处理数据,用户界面在屏幕上显示数据。 我还对业务逻辑层进行了单元测试。唯一的要求是测试业务层逻辑流。因此,我使用Moq框架来模拟数据访问层,并使用MS Unit对业务逻辑层进行单元测试。 我正在使用接口编程来使设计尽可能地分离,以便可以进行单元测试。业务层通过接口调用数据访问层。 当我尝试测试一种业务逻辑方法时,我遇到了一个问题。该方法完成了一些工作并创建了一个对象,并将其传递给数据访问层。当我尝试模拟该数据访问层方法时,则无法成功模拟。 在这里,我试图创建一个演示代码来显示我的问题。 模型: public class Employee { public string Name { get; set; } } 数据访问层: public interface IDal { string GetMessage(Employee emp); } public class Dal : IDal { public string GetMessage(Employee emp) { // Doing some data source access work... return string.Format("Hello {0}", emp.Name); …

10
有关如何反驳代码覆盖率质量参数的任何工具/建议
现在,我知道人们会认为这个问题重复或被问过很多次,在这种情况下,我希望获得与相关问题的链接以及我的问题的答案。 我最近在代码覆盖方面与某些人意见不一致。我有一群人希望我们的团队基于100%的覆盖率并不意味着良好的质量测试以及良好的代码质量就完全放弃代码覆盖率的研究。 通过推销“代码覆盖率”可以告诉我尚未确定的内容的论点,我可以进行回退,并帮助我们专注于这些领域。 (以上已经在类似这样的其他SO问题中以类似的方式进行了讨论-https: //stackoverflow.com/questions/695811/pitfalls-of-code-coverage) 这些人的论据是-然后,团队会做出反应,迅速创建质量低下的测试,从而浪费时间,同时又不增加明显的质量。 在理解他们的观点的同时,我正在寻找一种方法,通过引入更健壮的工具/框架来照顾更多的覆盖标准, 从而使代码覆盖更可靠(Functional, Statement,Decision, Branch, Condition, State, LCSAJ, path, jump path, entry/exit, Loop, Parameter Value etc)。 我正在寻找的建议是将这样的代码覆盖率工具和实践/过程结合在一起使用,这可以帮助我在对建议感到满意的同时反驳此类争论。 我也欢迎根据您的经验/知识如何提出反对意见提出的任何评论/建议,因为尽管主观,但是代码覆盖率使我的团队更加意识到了代码质量和测试价值。 编辑:为了减少对我对典型代码覆盖范围弱点的理解的困惑,我想指出的是,我并不是指 Statement Coverage(或执行的代码行)工具(有很多)。实际上,这里有一篇很好的文章介绍了所有错误之处:http : //www.bullseye.com/statementCoverage.html 我不仅在寻找语句或行覆盖率,而且还在寻找多个覆盖率标准和级别。 请参阅:http : //en.wikipedia.org/wiki/Code_coverage#Coverage_criteria 这个想法是,如果一个工具可以根据多个标准告诉我们我们的覆盖范围,那么它将成为对测试质量的合理自动化评估。我绝不是要说线路覆盖率是一个很好的评估。实际上,这就是我提出这个问题的前提。 编辑: 好的,也许我对它的预测太过夸张了,但是您明白了。问题在于以统一/一致的方式在所有团队中设置流程/策略。人们普遍担心,您如何确保测试质量,如何在没有任何措施的情况下分配保证的时间。因此,我喜欢具有可测量的功能,当使用适当的流程和正确的工具进行备份时,它将使我们能够提高代码质量,同时又知道不会浪费时间在浪费性的流程上。 编辑:到目前为止,我从答案中得到了什么: 代码审查应涵盖测试以确保测试质量 “测试优先”策略有助于避免事后写出的测试仅增加覆盖率% 探索涵盖测试标准的替代工具,而不仅仅是声明/行 分析覆盖的代码/发现的错误数量将有助于理解覆盖的重要性并提供更好的案例 最重要的是,请信任团队的投入以做正确的事并为自己的信念而战 涵盖的区块/测试数量-值得商but,但具有一定价值 感谢您迄今为止的出色回答。我真的很感激他们。此功能比具有强大功能的头脑风暴要好几个小时。

3
模拟具体课程-不推荐
我刚刚读了《成长面向对象的软件》一书的摘录,其中解释了为什么不建议模拟具体类的一些原因。 以下是MusicCentre类的单元测试的一些示例代码: public class MusicCentreTest { @Test public void startsCdPlayerAtTimeRequested() { final MutableTime scheduledTime = new MutableTime(); CdPlayer player = new CdPlayer() { @Override public void scheduleToStartAt(Time startTime) { scheduledTime.set(startTime); } } MusicCentre centre = new MusicCentre(player); centre.startMediaAt(LATER); assertEquals(LATER, scheduledTime.get()); } } 和他的第一个解释: 这种方法的问题在于,它使对象之间的关系保持隐式。我希望我们现在已经弄清楚了,使用模拟对象进行测试驱动开发的目的是发现对象之间的关系。如果我是子类,则域代码中没有任何东西可以使这种关系可见,而只是对象上的方法。这使得很难看到支持这种关系的服务是否在其他地方有用,下次我与该类一起工作时,我将不得不再次进行分析。 他说的时候我无法确切知道他的意思: 这使得很难看到支持这种关系的服务是否在其他地方有用,下次我与该类一起工作时,我将不得不再次进行分析。 我了解该服务对应于MusicCentre称为的方法startMediaAt。 他在“其他地方”是什么意思? 完整的摘录在这里:http : …

3
我应该在单元测试和集成测试之间划清界限吗?它们应该分开吗?
我有一个正在研究的小型MVC框架。它的代码库肯定不大,但是不再仅仅是几个类。我最终决定尝试一下并开始为此编写测试(是的,我知道我应该一直这样做,但是到目前为止,它的API还是非常不稳定的) 无论如何,我的计划是使其变得非常容易测试,包括集成测试。集成测试示例将遵循以下原则: 伪造的HTTP请求对象-> MVC框架-> HTTP响应对象->检查响应是否正确 因为这一切都可以在没有任何状态或特殊工具(浏览器自动化等)的情况下完成,所以实际上我可以使用常规的单元测试框架轻松地做到这一点(我使用NUnit)。 现在是个大问题。我应该在单元测试和集成测试之间划清界限吗?我是否应该一次(尽可能多地)仅通过单元测试来测试一门课程?另外,是否应该将集成测试与单元测试项目放在同一测试项目中?

3
我可以使用哪些论点将BDD概念“出售”给不愿意采用它的团队?
我有点支持“行为驱动开发”方法论(又名BDD)。我已经使用BDD已有两年了,并且在开发DotNet应用程序时采用StoryQ作为我的首选框架。即使我已经进行了多年的单元测试,并且以前已经转向测试优先的方法,但我发现使用BDD框架会带来更多的价值,因为我的测试抓住了相对而言需求的意图。在我的代码中清除英语,并且因为我的测试可以执行多个断言而无需在测试进行到一半时结束测试-这意味着我可以一目了然地查看哪些特定断言通过/失败,而无需进行调试即可证明。 对于我来说,这确实是冰山一角,因为我还注意到,我能够以更有针对性的方式调试测试和实现代码,从而提高了我的生产力,并且我可以如果由于输出进入构建日志而导致问题一直困扰到集成构建,则可以轻松确定发生故障的位置。此外,StoryQ api具有很好的流利语法,易于学习,并且可以以多种方式应用,不需要外部依赖就可以使用它。 因此,有了所有这些好处,您会认为很容易将概念引入团队其他成员。不幸的是,其他团队成员甚至都不愿看StoryStorQ来对其进行正确评估(更不用说应用BDD的想法了),并说服彼此尝试从我们自己的核心测试框架中删除许多StoryQ元素,甚至尽管他们最初支持使用StoryQ,但是即使他们希望删除的代码也不会影响我们测试系统的任何其他部分。这样做将最终导致整体上显着增加我的工作量,并且确实与实际情况背道而驰,因为我通过实践经验深信,这是在特定的工作环境中以“测试优先”的方式工作的更好方法,只会导致更大的工作量。鉴于以下情况,我们的软件质量得到了改善 我们发现更容易坚持使用BDD进行测试。为了进一步澄清,我们大多数的单元测试往往都很脆弱且难以维护,多年来由于应用程序测试不佳而导致的结果是,由于不愿坚持测试驱动的流程,开发人员退回到了旧习惯,在项目结束时进行所有测试(这些人声称自己是敏捷的!)。 因此,问题实际上归结为以下几点: 我可以使用哪些论点来真正说明这个团队使用StoryQ或至少采用BDD方法会更好? 您能否指出我能用来支持我的论点以采用BDD作为我们的标准选择方法的任何轶事证据? 您能想到什么相反的论点,这可能表明我希望鼓励团队采用BDD的想法可能是错误的?是的,只要论据是合理的,我很高兴被证明是错误的。 注意:我并不是在主张我们全面重写测试,而只是为了以后的所有测试工作而以不同的方式开始工作,最好以与客户互动的方式开始。 对于希望进一步了解BDD的人来说,以下链接可能会有用: http://dannorth.net/introducing-bdd/ http://en.wikipedia.org/wiki/Behaviour_driven_development http://behaviour-driven.org/简介 对于那些对更多细节感兴趣的人,我们是一个由4人组成的小型团队,致力于大约5个大型项目。BDD的“试验”最初进行了大约2个月,随后又进行了大约4个月。团队接受了我应该继续以这种方式工作并进行自己的尝试。自试验结束以来,我一直从事BDD工作约两年,而其他人则非常擅长回避问题。我不是在问题上施加“对抗”,而是在寻找一种方法来温和地说服团队摆脱集体的落后,并抽出时间来做好自己的工作。

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.