Questions tagged «unit-testing»

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

5
单元测试-入门
我刚刚开始进行单元测试,但不确定我是否真的了解所有内容。我阅读了有关这方面的教程和书籍,但是我有两个快速问题: 我认为单元测试的目的是测试我们实际编写的代码。但是,在我看来,为了能够运行测试,我们必须更改原始代码,这时我们并不是在真正测试我们编写的代码,而是在测试我们编写的代码。 我们的大多数代码都依赖于外部资源。但是,在重构我们的代码后,即使它会破坏原始代码,我们的测试仍然可以正常运行,因为外部源只是我们测试用例内部的模型。它是否违反了单元测试的目的? 抱歉,我在这里听起来很蠢,但我认为有人可以启发我。 提前致谢。

5
是否应该测试算法复杂度?如果是这样,怎么办?
假设我正在实现一些简单的操作,例如搜索排序的列表/数组。该函数(在c#中)看起来类似于: static int FindIndex(int[] sortedList, int i); 我可以根据功能来实现和测试它,但是出于显而易见的原因,我通常宁愿二进制搜索胜于线性搜索或某些故意的愚蠢行为。 所以我的问题是:我们是否应该尝试编写能够在算法复杂度方面保证性能的测试,如果可以,如何做? 我已经开始在这个问题的“您应该”部分的两边都进行争论,但是我想看看人们在没有我的争论的情况下会怎么说。 就“如何”而言,这变得非常有趣:)您可以看到参数化比较运算符并进行测试,该测试的比较运算符对比较进行计数或类似的操作。但是仅仅因为你能做并不意味着你应该... 有没有其他人考虑过(可能)?谢谢。

3
单元测试的正交性与单元测试的简洁性
我正在为视频游戏的转向系统编写单元测试。系统具有多种行为(由于原因A避免了该区域,由于原因B避免了该区域,每个行为都向该区域的地图添加了一些上下文。然后,一个单独的函数解析该地图并产生所需的运动。 我在决定如何编写行为的单元测试时遇到了麻烦。正如TDD所建议的,我只对行为如何影响所需的运动感兴趣。例如,避免-原因-A会导致移动远离建议的不良位置。我实际上并不在乎行为如何或为何为地图添加上下文,仅是所需的运动远离该位置。 因此,我对每种行为的测试都建立了行为,将其写入地图,然后执行地图解析功能来计算出所需的动作。如果该运动满足我的要求,那么我很高兴。 但是,现在我的测试取决于行为是否正常运行以及映射解析功能是否正常运行。如果解析功能失败,那么我将获得数百个失败的测试,而不是几个。许多测试写作指南都建议这是一个坏主意。 但是,如果我通过模拟映射直接针对行为的输出进行测试,那么我肯定与实现紧密结合了吗?如果我可以通过使用稍微不同的行为从地图上获得相同的期望运动,则测试应该仍然可以通过。 所以现在我正遭受认知失调。构造这些测试的最佳方法是什么?
14 tdd  unit-testing 

4
什么时候应该使用模拟对象?
我已经阅读了很多有关TDD的内容,但是我仍然有疑问。例如,我有以下类图: 这是一个简单的示例,仅用于了解TDD和模拟对象。 我应该先写哪个测试?产品,然后行,最后,订购?如果这样做,我应该使用生产线和产品来测试订单还是应该使用模拟对象?我什么时候应该使用模拟对象?我应该在XP和TDD中使用UML吗? 我还没有这些东西。

6
中间编写单元测试
单元测试是否完全是100%的交易? 我正在浏览旧项目并开始添加功能,这次是进行单元测试。但是,如果我要重新使用过去没有单元测试的组件,这最终将一文不值吗? 我是否需要为所有先前的类编写单元测试,而不必费神,还是只为要添加的新内容编写单元测试可以吗?

4
单元测试内部组件
您在多大程度上对类/模块/包/等的内部/私有组件进行单元测试?您是否对它们进行了测试,还是仅测试了与外界的接口?这些内部方法的一个示例是私有方法。 例如,想象一下递归下降解析器,它具有从一个中央过程调用的几个内部过程(函数/方法)。到外部世界的唯一接口是中央过程,该过程采用字符串并返回已解析的信息。其他过程解析字符串的不同部分,可以从中央过程或其他过程中调用它们。 当然,您应该通过使用示例字符串调用外部接口并将其与手动分析的输出进行比较来测试外部接口。但是其他程序呢?您是否会分别测试它们以检查它们是否正确解析了其子字符串? 我可以想到一些论点: 优点: 测试越多越好,这可以帮助增加代码覆盖率 通过向外部接口提供输入,某些内部组件可能很难提供特定的输入(例如,边缘情况) 更清晰的测试。如果内部组件具有(已修复的)错误,则该组件的测试用例可以清楚地表明该错误位于该特定组件中 缺点: 重构变得非常痛苦和耗时。要更改任何内容,即使外部接口的用户不受影响,也需要重写单元测试。 某些语言和测试框架不允许这样做 您对此有何看法?

7
在应用程序的CRUD层上创建单元测试,如何使测试独立?
因此,我试图使我的单元测试尽可能地按书进行,但是当我测试一些简单的添加/删除方法时,这会很麻烦。 对于add方法,我基本上必须创建一个虚拟对象并将其添加,然后在测试成功之后,我必须删除该虚拟对象。 对于删除测试,我显然必须创建一个虚拟对象,以便可以将其删除。 如您所见,如果一项测试失败,那么另一项测试也会失败,因为它们都是必需的。 与需要编写“取消订单”测试的系统相同……那么首先需要取消一些虚拟订单,这是否违反单元测试的准则? 这样的案件应该如何处理?

4
为什么可以使用传统的手动测试时使用phpunit
当我制作一个Web应用程序时,我会在浏览器上测试我的作品,以查看是否收到任何错误并进行修复。我已经完成了复杂的应用程序,并且以这种方式进行的测试非常简单快捷。我已经在YouTube上观看了许多有关phpunit的视频,但找不到目的。为什么这个库有用?phpunit是否更适合蛋糕框架或zend之类的PHP框架?我不使用任何框架,只是核心php。phpunit对我有用吗?如果是,怎么办? 也有xdebug,但我不确定是否相关。

6
您如何编写单元测试用例?
有时我最终会为其他开发人员编写的代码编写单元测试用例。有时候我真的不知道开发人员要做什么(业务部分),而我只是操纵测试用例来获得绿线。这些事情在业界正常吗? 正常趋势是什么?开发人员是否应该为自己编写的代码编写单元测试用例?

4
监视受过测试的班级是不好的做法吗?
我正在一个项目中进行类内部调用,但是结果是简单值的很多倍。示例(不是真实的代码): public boolean findError(Set<Thing1> set1, Set<Thing2> set2) { if (!checkFirstCondition(set1, set2)) { return false; } if (!checkSecondCondition(set1, set2)) { return false; } return true; } 为这种类型的代码编写单元测试真的很困难,因为我只想测试条件系统而不是实际条件的实现。(我在单独的测试中这样做。)实际上,如果我传递实现条件的函数会更好,而在测试中我只提供一些模拟即可。这种方法的问题在于嘈杂:我们大量使用泛型。 一个可行的解决方案;但是,这是使被测对象成为间谍并模拟对内部函数的调用。 systemUnderTest = Mockito.spy(systemUnderTest); doReturn(true).when(systemUnderTest).checkFirstCondition(....); 这里的关注点是有效更改了SUT的实现,并且使测试与实现保持同步可能会出现问题。这是真的?是否有最佳实践来避免这种内部方法调用的麻烦? 请注意,我们正在谈论的是算法的各个部分,因此将其分解为多个类可能不是一个理想的决定。

1
如何对图像处理代码进行单元测试?
我正在图像处理(主要是OCR)方面工作,我想知道如何在开发中集成单元测试。 我已经在使用单元测试来处理更多“常见”类型的代码,但是在处理图像处理代码时,我不确定该如何处理。这种代码总是需要一些图像数据输入/输出,而对其进行模拟并不明显。目前,我主要进行集成测试,但是它们需要一段时间才能运行,我想了解一些有关如何将这种代码分解为单元测试的想法,以便我可以更快地运行它们。 编辑:分析角色可以经历许多步骤,包括多次旋转,缩放和形态操作。随着算法的发展,这些步骤经常改变。因此,在测试期间,输入和预期输出会发生很大变化。每个字符可以为100x100像素,因此毫无疑问地在代码中对它们进行编码或处理生成的数据。

7
是否可以在没有明显分支的情况下实施策略模式?
策略模式很好地避免了if ... else庞大的构造,并使添加或替换功能更加容易。但是,我认为这仍然存在一个缺陷。似乎在每个实现中仍然需要一个分支构造。它可能是工厂或数据文件。以订购系统为例。 厂: // All of these classes implement OrderStrategy switch (orderType) { case NEW_ORDER: return new NewOrder(); case CANCELLATION: return new Cancellation(); case RETURN: return new Return(); } 此后的代码无需担心,现在只有一个地方可以添加新的订单类型,但是此部分代码仍不可扩展。将其拉出到数据文件中有助于提高可读性(我知道这值得商bat): <strategies> <order type="NEW_ORDER">com.company.NewOrder</order> <order type="CANCELLATION">com.company.Cancellation</order> <order type="RETURN">com.company.Return</order> </strategies> 但这仍然增加了样板代码来处理数据文件-授予的,更容易进行单元测试和相对稳定的代码,但是仍然增加了复杂性。 而且,这种结构不能很好地进行集成测试。现在每个单独的策略可能更容易测试,但是您添加的每个新策略都增加了测试的复杂性。它比没有使用模式时要少,但是它仍然存在。 有没有办法实现减轻这种复杂性的战略模式?还是这只是简单而已,而尝试更进一步只会增加另一层抽象,却几乎没有好处?

4
您如何才能对只能修复的bug进行TDD测试?
这是一个示例:我的Web应用程序包含可拖动元素。拖动元素时,浏览器会生成“重影”。我想在拖动时删除“重影”,并为此测试编写了一个测试。 我的问题是,我最初不知道如何解决此错误,而编写测试的唯一方法是在修复它之后。 在诸如之类的简单函数中let sum = (a, b) => a - b,您可以在编写任何代码之前编写一个关于为什么sum(1, 2)不相等的测试3。 在我描述的情况下,我无法测试,因为我不知道验证是什么(我不知道断言应该是什么)。 所描述问题的解决方案是: let dataTransfer = e.dataTransfer let canvas = document.createElement('canvas'); canvas.style.opacity = '0'; canvas.style.position = 'absolute'; canvas.style.top = '-1000px'; dataTransfer.effectAllowed = 'none'; document.body.appendChild(canvas); dataTransfer.setDragImage(canvas, 0, 0); 我不知道这是解决方案。在网上找到解决方案后,我什至无法编写测试,因为我唯一可以知道它是否真正有效的方法就是将这段代码添加到我的代码库中,并通过浏览器进行验证是否达到预期的效果。测试必须在代码之后编写,这与TDD背道而驰。 TDD如何解决此问题?在代码之前编写测试是强制性还是可选的?

4
如何为不返回任何内容的纯方法编写测试?
我有一堆处理值验证的类。例如,一个RangeValidator类检查一个值是否在指定范围内。 每个验证器类都包含两个方法:is_valid(value),该方法返回True或False取决于值,并ensure_valid(value)检查指定的值,如果值有效,则不执行任何操作,或者,如果值与预定义的规则不匹配,则抛出特定的异常。 当前有两种与此方法关联的单元测试: 传递无效值并确保引发异常的代码。 def test_outside_range(self): with self.assertRaises(demo.ValidationException): demo.RangeValidator(0, 100).ensure_valid(-5) 传递有效值的那个。 def test_in_range(self): demo.RangeValidator(0, 100).ensure_valid(25) 尽管第二项测试已完成工作-如果抛出异常,则失败,如果ensure_valid没有抛出异常,则成功,但assert内部没有s 的事实看起来很奇怪。读过此类代码的人会立即问自己,为什么要进行似乎无所事事的测试。 当测试不返回值且没有副作用的方法时,这是当前的做法吗?还是应该以其他方式重写测试?或者只是发表评论以解释我在做什么?

2
如何测试不可注入的代码?
因此,我在系统中使用了以下代码。目前,我们正在回顾性地编写单元测试(比我的观点迟来的要好得多),但是我不知道这将是可测试的吗? public function validate($value, Constraint $constraint) { $searchEntity = EmailAlertToSearchAdapter::adapt($value); $queryBuilder = SearcherFactory::getSearchDirector($searchEntity->getKeywords()); $adapter = new SearchEntityToQueryAdapter($queryBuilder, $searchEntity); $query = $adapter->setupBuilder()->build(); $totalCount = $this->advertType->count($query); if ($totalCount >= self::MAXIMUM_MATCHING_ADS) { $this->context->addViolation( $constraint->message ); } } 从概念上讲,这应该适用于任何语言,但是我正在使用PHP。该代码只是基于一个对象构建了一个ElasticSearch查询对象,而该Search对象又是从一个EmailAlert对象构建的。这些Search和EmailAlert只是POPO。 我的问题是,我不知道怎样才能模拟出的SearcherFactory(使用静态方法),也不是SearchEntityToQueryAdapter,它需要从结果SearcherFactory::getSearchDirector 和的Search实例。如何在方法中注入从结果中构建的内容?也许有一些我不知道的设计模式? 谢谢你的帮助!

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.