6

平衡从捆绑包中声明的包导出和单元测试要求的最佳方法是什么?

考虑要为其编写单元测试的捆绑包“mybundle”。捆绑包的源代码存储在 IDE 的“项目”概念中。例如:

mybundle
  src/java
    mybundle.package1
      ...java
  bnd.bnd

我所说的单元测试是指对单个 POJO 的测试,与可以在包中使用这些类的更广泛的 OSGi 上下文无关。在可能的情况下,测试应该可以使用“vanilla”类加载来运行,例如通过 Eclipse 中的 JUnit 运行程序。

在开发时,这里有几种打包单元测试的方法:

包源中的单元测试

在这里,单元测试被添加到项目的源文件夹中:

mybundle
  src/java
    mybundle.package1
      ...java
  test/java
    mybundle.package1.test
      ...java
  bnd.bnd

请注意附加的“.test”以区分包并避免拆分包问题。

通常会有一些措施来确保测试类不会最终出现在构建的捆绑 JAR 中。

单独包中的单元测试

这里添加了一个单独的包,名称后缀为“.test”,这是一般约定。

mybundle
  src/java
    mybundle.package1
      ...java
mybundle.test
  test/java
    mybundle.package1.test
      ...java
  bnd.bnd

这样做的问题是,因为类是分离的,并且单元测试的运行可能不了解 OSGi 环境(例如使用 Eclipse JUnit 运行器),您将不得不装饰 JUnit 运行器的运行时类路径。

片段中的单元测试

(感谢@HollyCummins)。这里创建了一个单独的包片段:

mybundle.fragment
  test/java
    mybundle.package1.test
      ...java
  bnd.bnd

该片段将“mybundle”声明为其宿主,从而允许它共享“mybundle”中的类,而无需导出包。

这样做的缺点是,因为片段加载是一个 OSGi 概念,所以您需要使用 OSGi 容器运行或装饰类路径。

出口问题

当考虑捆绑包如何执行导出包时,问题就来了。导出尽可能少的包被认为是一种很好的做法。然而,似乎单元测试会强制导出额外的包。

这对于第二个选项最为明显,具有单独的测试包。测试包中的测试必须 Import-Package 被测类,并且被测包还必须 Export-Package 所有所述被测类。

因此,显而易见的解决方案是倾向于在包源中进行单元测试,但问题很快就会在非平凡的情况下出现。您可能希望共享测试代码,例如,您可能在单独的包中拥有 OSGi 集成测试。要共享代码,您最终必须导出-打包测试包,然后当然您最终还会在构建的捆绑包中获得测试代码!

组织 OSGi 包/项目进行测试的最佳方式是什么?

4

3 回答 3

0

第三种选择是使用 OSGi 片段进行单元测试。这可以确保您的测试与要测试的代码共享一个类加载器,因此不需要额外的内部包导出包。如果需要,测试片段甚至可以导出主包的内部包。该片段将有自己的包导入,因此它可以拉入共享测试代码,而不会污染主包的包导入。

正如上面的评论和更新的原始问题中提到的,使用片段仍然会给您留下一些关于如何处理构建和类路径的问题。如果您在 OSGi 容器之外运行测试,则片段的类加载器优势在很大程度上消失了,除了可能在 IDE中引入导入的测试依赖项。

如果您在 OSGi 容器中运行测试,与普通包相比,片段确实有一些缺点,这可能是一个问题,这取决于您如何驱动测试。片段不能声明激活器,因为它们没有独立的生命周期。声明式服务也不能以自然的方式从片段中注册,尽管蓝图服务通常可以.

于 2012-09-12T09:15:42.950 回答
0

使用Maven将使选项 1 实现起来非常简单。优点是 Maven为您管理类路径,因此任何仅用于测试的代码或依赖项都不会出现在最终包中。您甚至可以将单元测试与被测类放在同一个包中,这样您就可以从测试中访问包私有类。由于测试是使用正常的类加载执行的,Export-Packages因此根本不会影响它。

于 2012-09-12T09:33:57.137 回答
0

如果您在出色的隔离中测试类(正如许多单元测试通常所做的那样),为什么还要在 OSGi 框架中打包和运行此类单元测试。只需编译类,编译相应的测试类并在您喜欢的任何测试框架中运行它们。

于 2020-01-24T22:57:31.510 回答