6

バンドルからのパッケージの宣言されたエクスポートと単体テストの要件のバランスをとる最良の方法は何ですか?

単体テストを作成するバンドル 'mybundle' について考えてみましょう。バンドルのソースは、IDE の「プロジェクト」の概念に格納されます。例えば:

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

単体テストとは、個々の POJO のテストを意味し、これらのクラスがバンドル内で使用される可能性がある、より広い OSGi コンテキストとは無関係です。可能であれば、テストは 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 コンテナーで実行するか、クラスパスをデコレートする必要があることです。

エクスポートの問題

問題は、バンドルが Export-Package を実行する方法を検討するときに発生します。エクスポートするパッケージはできるだけ少なくすることをお勧めします。それでも、単体テストによって余分なパッケージが強制的にエクスポートされるようです。

これは、別のテスト バンドルを持つ 2 番目のオプションで最も明白です。テスト バンドル内のテストは、テスト対象のクラスを Import-Package する必要があり、テスト対象のバンドルは、すべてのテスト対象クラスを Export-Package する必要があります。

したがって、明白な解決策は、バンドル ソースに単体テストを含めることに傾倒することですが、重要な状況ではすぐに問題が発生します。たとえば、別のバンドルに OSGi 統合テストがある場合など、テスト コードを共有したい場合があります。コードを共有するには、テスト パッケージを Export-Package する必要があります。もちろん、ビルドされたバンドル内のコードもテストすることになります!

テスト用に OSGi バンドル/プロジェクトを編成する最良の方法は何ですか?

4

3 に答える 3

0

3 番目のオプションは、単体テストに OSGi フラグメントを使用することです。これにより、テストがテスト対象のコードとクラスローダーを共有することが保証されるため、内部パッケージの追加のパッケージ エクスポートは必要ありません。テスト フラグメントは、必要に応じてメイン バンドルの内部パッケージをエクスポートすることもできます。フラグメントには独自のパッケージ インポートがあるため、メイン バンドルのパッケージ インポートを汚染することなく、共有テスト コードを取り込むことができます。

上記のコメントと更新された元の質問で述べたように、フラグメントを使用すると、ビルドとクラスパスの処理方法についていくつかの質問が残ります。OSGi コンテナーの外部でテストを実行している場合、おそらくIDEにインポートされたテストの依存関係を取り込む場合を除いて、フラグメントのクラスローダーの利点はほとんどなくなります。

OSGi コンテナーでテストを実行している場合、フラグメントには通常のバンドルと比較していくつかの欠点があり、テストの実行方法によっては問題になる可能性があります。フラグメントには独立したライフサイクルがないため、アクティベーターを宣言できません。宣言型サービスもフラグメントから自然な方法で登録することはできませんが、ブループリント サービスは通常.

于 2012-09-12T09:15:42.950 に答える
0

Mavenを使用すると、オプション 1 の実装が非常に簡単になります。利点は、Mavenがクラスパスを管理するため、テストにのみ必要なコードや依存関係が最終的なバンドルに含まれないことです。単体テストをテスト対象のクラスと同じパッケージに配置して、テストからパッケージ プライベート クラスにアクセスできるようにすることもできます。テストは通常​​のクラスローディングを使用して実行されるため、Export-Packages影響はまったくありません。

于 2012-09-12T09:33:57.137 に答える