OSGi单元测试和捆绑导出

时间:2012-09-11 15:04:18

标签: java unit-testing junit osgi

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

考虑要为其编写单元测试的捆绑“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)。这里创建了一个单独的bundle片段:

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

该片段将'mybundle'声明为其主机,从而允许它在'mybundle'中共享类,而无需导出包。

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

导出问题

在考虑捆绑包执行Export-Package时会出现问题。 It is considered good practice to export as few packages as possible。然而,单元测试似乎迫使额外的包出口。

对于第二个选项,这是最明显的,具有单独的测试包。测试包中的测试必须对测试中的类进行Import-Package,并且测试中的bundle还必须Export-Package所有正在测试的所有类。

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

组织OSGi捆绑/项目进行测试的最佳方法是什么?

3 个答案:

答案 0 :(得分:0)

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

正如上面的评论和更新的原始问题所述,使用片段仍然会让您对如何处理构建和类路径留下一些疑问。如果您在OSGi容器外运行测试,那么片段的类加载器优势很可能会消失,除非您在IDE中引入导入的测试依赖项。

如果您在OSGi容器中运行测试,与正常捆绑包相比,碎片确实存在一些缺点,这可能是一个问题,这取决于您是如何驾驶测试的。片段无法声明Activator,因为它们没有独立的生命周期。尽管Blueprint服务通常can,但声明式服务也无法以自然方式从片段中注册。

答案 1 :(得分:0)

使用Maven会使选项1变得非常简单。优点是Maven manages your classpaths适合您,因此任何仅需要进行测试的代码或依赖项都不会在最终的包中结束。您甚至可以将单元测试放在与测试类相同的包中,这样您就可以从测试中访问包私有类。由于测试是使用正常的类加载执行的,Export-Packages根本不会影响它。

答案 2 :(得分:0)

如果您要以出色的隔离度测试类(就像许多单元测试通常所做的那样),那么为什么要打包和在OSGi框架中运行此类单元测试呢?只需编译该类,编译相应的测试类,然后在您喜欢的任何测试框架中运行它们即可。