java如何在不同的测试环境中重用JUnit测试方法?
到目前为止,我一直在开发测试,以支持我的项目中的某个应用程序。现在我已经安装并运行了一组测试,我需要为另一个类似的应用程序提供支持。在我的系统中,两个应用程序的结果应该是相同的,因为它们都产生相同的操作,但来自不同的上下文。问题是,我正在寻找一种方法,可以重用我为第一个测试所做的测试,而不必为另一个测试用例复制它们的代码
我目前正在使用JavaEE8下的JUnit4
我的情况是这样的。给出如下测试:
class TestExample {
Context context;
@Before
public void setUp() {
context = new ContextA();
}
@After
public void terminate() {
context.dispose();
}
@Test
public void test1() {
context....
}
}
abstract class Context {
@Override
public void dispose() {
...
}
}
class ContextA extends Context {
}
class ContextB extends Context {
}
我希望能够为ContextA做一次测试,然后为ContextB做一次测试
---哦---
因此,在一段时间后回到这个问题,我从这条线索中收集了三种可能的解决方案:
- 参数化
- 测试继承
- 语境构成
然而,在真实的测试用例上尝试了所有这些方法之后,我发现它们都不是完美的解决方案。它们确实解决了我在这个问题上提出的问题,但一旦一个真正的案例出现,它们之间的背景开始略有不同,那么这些选项就会变得复杂和丑陋
最后,我选择了最简单的解决方案:为每个不同的上下文复制测试源代码。它是有效的,但问题是,随着时间的推移,维护测试变得越来越困难,因为对单个测试的更改必须复制到它的所有副本中
# 1 楼答案
另一种方法是改进你的设计:
在你的例子中,两个项目都向我们展示了相同的基类。您可以通过将
Context
转换为一个普通类(删除abstract
关键字)并将其移动到一个公共基础项目中,来应用偏好组合而非内在方法。这样你就有了一个测试Context
行为的单一点您的专用类
ContextA
和ContextB
将获得一个Context
实例作为构造函数参数注入,以便您可以在自己的测试中模拟它然后验证(以及
ContextA
和ContextB
的特殊行为)是否调用了传递的Context
实例上的预期方法是的,您仍然有重复的测试,但它们非常简单,只要
Context
中的方法签名不变,它们就永远不会改变有时候,反过来做可能更好,将专门的实现注入到包含公共行为的类中
# 2 楼答案
通常情况下,您是而不是
单元测试的一个核心点是:当您稍后更改生产代码时,它们可以帮助您快速识别错误。意思:单元测试的一个主要要求是你能够快速地阅读和理解它们。任何让这变得更难的事情,比如避免代码重复的“复杂”解决方案都是有问题的
从这个角度来看,测试代码的“规则”有时与生产代码的“规则”不同。在生产代码中,您希望(几乎)不惜一切代价避免代码重复
然而,对于测试代码来说,两个不同的测试类可以做非常相似的事情。。。两次。也许,只是也许你可以将普通代码提取到助手方法中(比如做一个特定的、复杂的断言)到一些实用程序类中
话虽如此,一个潜在的解决方案是:如果你真的想在多个“输入”上运行完全相同的测试,那么我建议你看看parameterized测试。不必在@Before code中硬编码
context
实例,只需拥有多个不同的context
对象,并为每个对象运行所有测试即可