我应该使用继承测试吗? [英] Should I use inherited tests?

查看:28
本文介绍了我应该使用继承测试吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在审查一些代码,其中开发人员有一些类 ClassA 和 ClassB.它们都继承自 ParentClass,因此都必须实现一些抽象方法(例如 return5Values(2))

I am reviewing some code where the developer has some classes ClassA and ClassB. They both inherit from ParentClass so both must implement a number of abstract methods (e.g. return5Values(2))

在 ClassA 中,所有值都是前一个值的两倍:[2,4,8,16,32]在 ClassB 中,值都是 +1 前一个值 [2,3,4,5,6]

In ClassA the values are all double the previous value: [2,4,8,16,32] In ClassB the values are all +1 the previous value [2,3,4,5,6]

还有其他限制,例如如果参数为负数则引发错误等.

There are also other constraints such as raising an error if the parameter is negative etc.

其他测试如仅获取第三个值,也存在等

Other tests like getting the 3rd value only, also exist etc.

(显然这些只是为了表达我的观点的假例子)

(Obviously these are just fake examples to get my point across)

现在,开发人员所做的不是为 ClassA 和 ClassB 编写大量类似的测试,而是创建了 ParentClassChildTests,其中包含一些类似这样的代码:

Now, instead of writing a lot of similar tests for both ClassA and ClassB, what the developer has done is created ParentClassChildTests which contains a some code something like this:

public void testVariablesAreCorrect() {
  returnedValues = clazz.return5Values(2)
  # Does a bunch of other things as well
  # ...
  assertEqual(expectedValues, returnedValues)
} 

ClassATests 现在继承自 ParentClassChildTest,并且必须将 expectedValues 定义为类变量.

ClassATests now inherits from ParentClassChildTest and must define expectedValues as a class variable.

expectedValues 也在几个不同的测试中使用,所以它们不是只为这个单一测试定义的.

The expectedValues are used within a few different tests as well, so they aren't being defined just for this single test.

现在当 ClassATestsClassBTests 运行时,它也会运行 ParentClassChildTests 中的所有测试.

Now when ClassATests and ClassBTests are run, it also runs all the tests inside ParentClassChildTests.

我的问题是:这是避免大量重复测试并确保子类中一切正常的好方法吗?这会导致任何重大问题吗?或者有更好的处理方法?

My question is: Is this a good method to avoid a lot of duplicate tests and ensure everything works as expected in child classes? Are there any major issues this can lead to? Or a better way of handling this?

虽然这都是 Java 代码,但我的问题不是关于任何特定的测试框架或语言,而是关于从也有测试的父类继承的一般想法.

Whilst this is all Java code, my question isn't about any particular testing framework or language but the idea in general of inheriting from a parent class which also has tests in it.

推荐答案

针对接口/基类的不同实现重用测试是可能且明智的,这种情况并不常见.以下方面限制了适用性:

The situation that it is possible and sensible to re-use tests for different implementations of an interface / base class is not very common. The following aspects limit the applicability:

  • 派生类具有不同的依赖关系,这可能需要创建和设置不同的模拟.在这种情况下,测试方法不能完全相同.即使 classAclassB 当前没有依赖项或具有(巧合)相同设置的相同依赖项,这也可能随着时间或下一个类 classC 将具有不同的依赖项.
  • 每个派生类将实现不同的算法.在您的情况下,return5ValuesClassAClassB 中执行不同的算法.由于不同的算法,相同设置和相同输入的 SUT 行为可能不同:例如,每个算法将在不同点遇到溢出.即使调用 return5Values(2) 允许在今天对 classAclassB 使用派生测试,也可能具有潜在的未来 classC 导致可能引发异常的溢出场景.
  • 派生类中实现的不同算法将具有不同的潜在错误和不同的极端情况.也就是说,SUT 的必要设置和输入必须不同才能刺激各自的边界.对于某些实现,测试调用 return5Values(2) 可能根本不会带来任何好处,而测试除 2 之外的其他参数是必要的.
  • 如果您在类之间共享测试方法并且只提供参数,那么与测试意图相关联的测试方法不是 - 每个参数集都有自己的意图.但是,理想情况下,意图/场景应该是每个单独测试的输出的一部分.
  • Derived classes have different dependencies, which may require different mocks to be created and to be set up. In such a case, the test methods can not be identical. Even if classA and classB currently do not have dependencies or the same dependencies with (coincidentially) the same setup, this can change over time or the next class classC will have different dependencies.
  • Each derived class will implement different algorithms. In your case, return5Values performs different algorithms in ClassA and ClassB. Due to the different algorithms, the behaviour of the SUT for the same set up and the same inputs may be different: For example, each algorithm will run into overflows at different points. Even the call return5Values(2) that allows to use a derived test for classA and classB today, could with a potential future classC lead to an overflow scenario with possible exceptions thrown.
  • The different algorithms implemented in the derived classes will have different potential bugs and different corner cases. That is, the necessary set up and inputs for the SUT will have to be different to stimulate the respective boundaries. For some implementations, testing the call return5Values(2) may simply not bring any benefit while test for other parameters than 2 are necessary.
  • If you share test methods between the classes and only provide the parameters, it is not the test method which is associated with the tests' intent - each parameter set has its own intent. The intent/scenario, however, should ideally be part of the output of each individual test.

考虑到所有这些问题,测试方法的继承似乎不是这里重用的最佳方法.相反,拥有一些可供不同派生类使用的通用辅助函数可能更有益.

Given all these problems, inheritance of test methods does not seem to be the best approach for re-use here. Instead, it may be more beneficial to have have some common helper functions that can be used by the different derived classes.

这篇关于我应该使用继承测试吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆