1

Eclipse で maven を使用して構成された Google Maps V2 を使用した Android アプリケーションがあります。したがって、私は worspace に「Mavenized」Google Play Services lib を持っており、アプリ pom には google-play-services jar と apklib への 2 つの Maven 依存関係があります。

マップ フラグメントが null でないかどうかのみをチェックするダミー テストを実装しました。

@RunWith(RobolectricTestRunner.class)
public class MapsTest {

    private GoogleMap map;
    private ElementMapActivity activity;

    @Before
    public void setUp() throws Exception {
        activity = new ElementMapActivity();
        activity.onCreate(null);
    }

    @Test
    public void mapExists() {
        // Try to obtain the map from the SupportMapFragment.
        map = ((SupportMapFragment) activity.getSupportFragmentManager()
                .findFragmentById(R.id.elementMap)).getMap();
        Assert.assertNotNull(map);
    }   
}

注: 同様のコードが実際のアプリケーション アクティビティで使用されてマップが表示され、正常に実行されます。

カスタムのテストランナーは実装していません。

maven: mvn test でテストを実行します。

Robolectric 1.2 では、テストはビルドおよび実行されますが、マップ インスタンスが null であるため、assertNotNull は失敗します。フラグメントが正しく復元されていません。

Robolectric 2.1.1 では、テストはビルドされますが、実行に失敗します。プロジェクト内の各テストで例外が発生します (マップをテストするものだけではありません)。

WARNING: no system properties value for ro.build.date.utc
java.lang.RuntimeException: .\..\google-play-services_lib\AndroidManifest.xml not found or not a file; it should point to your project's AndroidManifest.xml
    at org.robolectric.AndroidManifest.validate(AndroidManifest.java:108)
    at org.robolectric.AndroidManifest.getResourcePath(AndroidManifest.java:274)
    at org.robolectric.AndroidManifest.getIncludedResourcePaths(AndroidManifest.java:280)
    at org.robolectric.AndroidManifest.getIncludedResourcePaths(AndroidManifest.java:282)
    at org.robolectric.RobolectricTestRunner.createAppResourceLoader(RobolectricTestRunner.java:576)
    at org.robolectric.RobolectricTestRunner.getAppResourceLoader(RobolectricTestRunner.java:568)
    at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:89)
    at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:387)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:227)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120)
    at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:169)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
    at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)

Robolectric は、デフォルトの場所であるアプリのルート フォルダーにあるメインのアプリケーション マニフェストではなく、google-play-services ライブラリ マニフェストを使用しようとしているようです。ライブラリ マニフェストも独自のルート フォルダーにあります。

テスト用の構成が不足していますか? カスタム テストランナーを使用する必要がありますか? それとも、Google マップ V2 が Robolectric 2 でサポートされていないということですか?

編集:マップテストなしでできます。問題は、Robolectric 2 では、google-play-library 依存関係があるだけで、他のすべてのテストでもこのエラーが発生するため、今では Robolectric 2 を使用できないことです。Robolectric 1 に戻すかどうかを決定するために、これが既知のバグであるかどうかを知りたいです。Robolectric のバグ レポートを確認しましたが、これについては何も見つかりませんでした。

4

2 に答える 2

0

最近、Maven ビルド プランで Robolectric テストを実行しているときに、ActionBarSherlock で同じ問題が発生しました。

この問題は、Windows マシンでビルドを完了していたときには明らかではなく、ラップトップを OSX 電源デバイスに切り替えた後に初めて明らかになりました。

問題は、ライブラリ名「google-play-services_lib」がディレクトリ構造のフォルダー名と (正確に) 一致しないことであることがわかりました。私の場合、私のEclipseプロジェクトは「ActionBarSherlock-4.3.1」と呼ばれていましたが、フォルダー自体はファイルシステムの下で「actionbarsherlock」と呼ばれていました。

2 つの名前 (Eclipse プロジェクトとファイル システム) を同期し、テストを再実行することをお勧めします。それが役立つことを願っています。

于 2013-07-25T08:14:09.230 に答える
0

google-play-services_lib (Google マップ) を使用する Android アプリを Robolectric 2.1.1 でテストすると、AndroidManifest.xml が見つからない RuntimeException が生成されます。

短い答えは太字でここにあります。長い答えはその下にあります。

プロジェクトで project.properties という名前のファイルを探します

test-project.properties という名前の新しいファイルを作成します

android.library.reference.$ の一部またはすべてをオーバーライドします。

たとえば、私の project.properties には、次のライブラリ参照がありました。

**android.library.reference.1=../../../ADK/adt-bundle-windows-x86_64-20130522/sdk/extras/google/google_play_services/libproject/google-play-services_lib**

test-project.properties ファイルでオーバーライドしました

android.library.reference.1=res

google-play-services_lib の AndroidManifest.xml を、テストしているプロジェクトの res (またはプロジェクト内の任意のフォルダー) フォルダーに配置します。

長い答え:

私は同じ問題を抱えていて、問題は上記の「メイン アプリケーション マニフェストではなく google-play-services ライブラリ マニフェスト」と同じであると考えていたので、google-place-services_lib へのすべての参照を削除しましたが、それでもエラーが発生しました. 2.1.1 Robolectric コードを github からダウンロードし、デバッグを開始しました。org.robolectric.AndroidManifest クラスには、createLibraryManifests を呼び出し、findLibraries を呼び出す getLibraryManifests というメソッドがあることがわかりました。これが行うことの 1 つは、プロジェクトに project.properties ファイルをロードすることです。私の場合、このコンテンツの project.properties ファイル:
android.library.reference.1=../../../ADK/adt-bundle-windows-x86_64-20130522/sdk/extras/google/google_play_services/libproject /google-play-services_lib

これは、Google のドキュメントに従って、Google Play サービスのインストールに Android ツールを使用したときに作成されました。project.properties ファイルからその行をコメントアウトすると、エラーはなくなります。より良い解決策は、それをそのままにして、test-project.properties という名前の独自のファイルを作成し、android.library.reference.1 の正しいディレクトリに配置することです。AndroidManifest は元の値をオーバーライドします。

AndroidManifest.java の関連コードは次のとおりです。

protected List<FsFile> findLibraries() {
FsFile baseDir = getBaseDir();
List<FsFile> libraryBaseDirs = new ArrayList<FsFile>();

Properties properties = getProperties(baseDir.join("project.properties"));
// get the project.properties overrides and apply them (if any)
Properties overrideProperties = getProperties(baseDir.join("test-project.properties"));
if (overrideProperties!=null) properties.putAll(overrideProperties);
if (properties != null) {
int libRef = 1;
String lib;
while ((lib = properties.getProperty("android.library.reference." + libRef)) != null) {
FsFile libraryBaseDir = baseDir.join(lib);
libraryBaseDirs.add(libraryBaseDir);
libRef++;
}
}
return libraryBaseDirs;
}
于 2013-09-17T19:11:28.500 に答える