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

然而,有一个测试子集我从未期望在我的代码上通过。但是,如果我开始向这些测试添加 @Ignore 注释,我将不得不维护自己的测试实现的单独副本,我将其 真的 不想做。

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

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

  • 我考虑组合一个 TestSuite,它使用反射来动态查找和添加所有原始测试,然后添加代码以显式删除我不想运行的测试。但当我注意到 测试套件API 不提供删除测试的方法。

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

  • 我能想到的唯一其他选择是无论如何都运行不好的测试并忽略失败。然而,这些测试需要一段时间才能运行(并且会失败!),所以我宁愿根本不运行它们。此外,我看不到一种方法来告诉 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 任务没有提供一种指定测试运行器的机制,而这本来是理想的。

我能想到的在规定的约束下实现您想要的效果的一种可能性是使用字节码修改。您可以在单独的文件中保留要忽略的类和方法的列表,并在加载测试类时修补它们的字节码以完全删除这些方法。

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

像这样的图书馆 BCEL 可用于在加载时修改类。

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

如果您无法做到其中任何一项,那么覆盖的选择可能是最好的选择。每当您需要忽略扩展该类的某些方法并将其添加到 Ant 排除列表时,请采取以下过程。这样您就可以排除无法通过的内容,并且仍然会引入所有新测试(您没有覆盖的方法和新测试类),而无需修改您的构建。

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

两种选择

  1. 与借用测试的所有者合作,将您的测试提取到一个你们都可以共享的单独类中。
  2. 创建您自己的测试类,它代理您要使用的测试类。对于您想要包含的每个方法,您的类中都有一个方法。您需要构造您正在调用的测试类的实例,并且如果它们位于原始方法中,则还需要在方法之前和之后执行这些操作。
  3. 基于 blockjunitrunner 创建自定义 Junit 运行程序,并使用它来过滤或过滤您想要的测试。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top