繁体   English   中英

在不修改Test类的情况下排除单个JUnit Test方法?

[英]Exclude individual JUnit Test methods without modifying the Test class?

我目前正在使用另一个项目中的JUnit 4测试来反对我的代码。 作为自动化Ant构建的一部分,我直接从其他项目的存储库中获取它们。 这很棒,因为它可以确保我的代码在最新版本的测试中保持绿色。

但是,有一部分测试我从未希望传递给我的代码。 但是如果我开始在这些测试中添加@Ignore注释,我将不得不维护自己的测试实现的单独副本,我真的不想这样做。

有没有一种方法可以在不修改测试源的情况下排除单个测试? 这是我到目前为止所看到的:

  • 据我所知,Ant JUnit任务只允许你排除整个Test类,而不是单独的测试方法 - 这对我没有好处,我需要方法粒度。

  • 我考虑整合一个TestSuite,它使用反射动态查找并添加所有原始测试,然后添加代码以显式删除我不想运行的测试。 但是当我注意到TestSuite API没有提供删除测试的方法时,我放弃了这个想法。

  • 我可以创建自己的Test类来扩展原始的Test类,覆盖我不想运行的特定测试,并使用@Ignore注释它们。 然后我在我的子类上运行JUnit。 这里的缺点是,如果将新的测试类添加到原始项目中,我将不会自动选择它们。 我将不得不监视新的Test类,因为它们被添加到原始项目中。 到目前为止,这是我最好的选择,但感觉并不理想。

  • 我能想到的唯一另一个选择是无论如何都要运行错误的测试并忽略失败。 但是,这些测试需要一段时间才能运行(并且失败!)所以我宁愿根本不运行它们。 另外,我看不到告诉Ant任务忽略特定测试方法失败的方法(再次 - 我看看如何为单个测试类而不是方法执行此操作)。

如果您根本无法接触原始测试,那么您将面临一些严重的限制。 你的压倒性声音是最好的选择,但有一些变化:

构建特别排除超类的Ant测试,以便运行您不了解的其他类。

您可以使用@Rule注释(JUnit 4.7的新增内容)来了解正在运行的测试并中止它(通过返回空的Statement实现)而不是覆盖特定的方法,让您在知道是否避免测试时更灵活。 此方法的唯一问题是您无法使用此方法停止运行@Before方法,这可能很慢。 如果这是一个问题(你真的无法触及测试),那么在重写方法中的@Ignore是我唯一能想到的。

但是,如果您可以触摸这些测试,则会打开一些其他选项:

您可以通过在类上指定@RunWith标记来使用自定义运行器运行它们。 这个运行器只是将执行传递给该项目中的标准运行器(JUnit4.class),但是在您的项目中(通过系统属性或其他一些机制)将检查测试名称而不运行测试。 这样做的优点是侵入性最小,但最难实现(跑步者是毛茸茸的野兽,@ Rule的既定目标之一是消除制造它们的大部分需求)。

另一个是在测试中做一个假设的声明,它会检查一些配置设置,如果该测试应该运行则该设置是真的。 这实际上涉及注入测试,这很可能是任何远程标记为“单独项目”的交易破坏者。

它现在没有帮助,但TestNG支持这种能力。

好吧,这是一个相当重要的解决方案,但如果听起来很荒谬,不要向我扔东西。

Junit4的核心是org.junit.runner.Runner类及其各种子类,最重要的是org.junit.runners.Suite 这些运行器使用@Test和@Ignore之类的东西确定给定测试类的测试内容。

创建一个跑步者的自定义实现非常容易,通常你可以通过在测试类上使用@RunWith注释来连接它们,但显然这不适合你。

但是,从理论上讲,您可以编写自己的Ant任务,可能基于标准的Ant Junit任务,该任务采用您的自定义测试运行器并直接使用它,依次将每个测试类传递给它。 您的运行器实现可以使用外部配置文件,该文件指定要忽略的测试方法。

这将是相当多的工作,你必须花时间在史前的Ant Junit代码库中挖掘,以了解它是如何工作的。 然而,时间投入可能是值得的。

令人遗憾的是,Junit Ant任务没有提供指定测试Runner的机制,这是理想的。

我可以想到用规定的约束来实现你想要的东西是使用字节码修改。 您可以在单独的文件中保留要忽略的类和方法的列表,并在加载它们时修补测试类的字节码以完全删除此方法。

如果我没有弄错,JUnit使用反射来查找要执行的测试方法。 然后,方法重命名操作将允许您在JUnit找到它们之前删除这些方法。 或者可以修改方法以立即返回,而不执行任何操作。

BCEL这样的库可用于在加载时修改类。

如果你只想运行一部分测试,那么听起来这个类有多个责任,应该重构。 或者,测试类可以拆分,以便原始项目具有所有测试,但是在一个或多个类上(我猜测某些测试实际上是集成测试并触摸数据库或网络)并且您可以排除类( es)你不想要的。

如果你不能做到这一点,你可以选择覆盖最好。 无论何时需要忽略扩展该类的某些方法并将其添加到Ant排除列表,都需要执行此过程。 这样你就可以排除你无法传递的内容,并且仍然会在不修改你的构建的情况下引入所有新的测试(你没有覆盖的方法和新的测试类)。

如果不需要的测试位于特定的类/包中,则可以使用Ant中的文件集排除在导入期间将其排除。

两种选择

  1. 与借用测试的所有者合作,将您的测试提取到您可以共享的单独课程中。
  2. 创建自己的测试类,代理要使用的测试类。 对于要包含的每个方法,在您的类中都有一个方法。 你需要构建一个你正在调用的测试类的实例,并且如果它们在原始版本中,也需要在方法之前和之后执行。
  3. 基于blockjunitrunner创建一个自定义Junit运行器,并使用它来过滤掉你想要的测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM