Тестирование проекта, который использует ActionBarSherlock

Моя настройка:

  1. Библиотечный проект: ActionBarSherlock
  2. проект
  3. Тестовый проект

Мой проект имеет библиотечный проект, связанный как библиотечный проект. Он компилируется и работает нормально.

Сейчас я пытаюсь протестировать свое приложение, используя обычный тестовый проект. Запуск тестов в Eclipse работает отлично. Если я попытаюсь запустить тесты с помощью ant, тестовый проект даже не скомпилируется:

[javac] LoginActivityTest.java:9: cannot access com.actionbarsherlock.app.SherlockActivity
[javac] class file for com.actionbarsherlock.app.SherlockActivity not found
[javac] public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {
[javac]                                                                        ^
[javac] LoginActivityTest.java:25: cannot find symbol

Сборка через eclipse работает отлично, и тест тоже проходит отлично.

Если я связываю проект библиотеки с моим тестовым проектом, он компилируется с помощью ant, но тесты не пройдены.

 [exec] Error in testSuiteConstructionFailed:
 [exec] java.lang.RuntimeException: Exception during suite construction
 [exec]     at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:238)
 [exec]     at java.lang.reflect.Method.invokeNative(Native Method)
 [exec]     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
 [exec]     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
 [exec]     at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:537)
 [exec]     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)
 [exec] Caused by: java.lang.reflect.InvocationTargetException
 [exec]     at java.lang.reflect.Constructor.constructNative(Native Method)
 [exec]     at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
 [exec]     at android.test.suitebuilder.TestMethod.instantiateTest(TestMethod.java:87)
 [exec]     at android.test.suitebuilder.TestMethod.createTest(TestMethod.java:73)
 [exec]     at android.test.suitebuilder.TestSuiteBuilder.addTest(TestSuiteBuilder.java:262)
 [exec]     at android.test.suitebuilder.TestSuiteBuilder.build(TestSuiteBuilder.java:184)
 [exec]     at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:371)
 [exec]     at com.zutubi.android.junitreport.JUnitReportTestRunner.onCreate(JUnitReportTestRunner.java:90)
 [exec]     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3891)
 [exec]     at android.app.ActivityThread.access$1300(ActivityThread.java:122)
 [exec]     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1184)
 [exec]     at android.os.Handler.dispatchMessage(Handler.java:99)
 [exec]     at android.os.Looper.loop(Looper.java:137)
 [exec]     at android.app.ActivityThread.main(ActivityThread.java:4340)
 [exec]     at java.lang.reflect.Method.invokeNative(Native Method)
 [exec]     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
 [exec]     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
 [exec]     at dalvik.system.NativeStart.main(Native Method)
 [exec] Caused by: java.lang.NoClassDefFoundError: com.myproject.android.app.activities.LoginActivity
 [exec]     at com.myproject.android.app.test.LoginActivityTest.<init>(LoginActivityTest.java:18)
 [exec]     ... 19 more

Мой тестовый класс:

public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {

    private LoginActivity mActivity;

    private EditText      mTextUserName;

    private EditText      mTextUserPassword;

    public LoginActivityTest() {
        // the super call is line 18 (see stack trace above)
        super("com.myproject.android.app.activities", LoginActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mActivity = getActivity();
        mTextUserName = (EditText) mActivity.findViewById(com.myproject.android.app.R.id.login_activity_username);
        mTextUserPassword = (EditText) mActivity.findViewById(com.myproject.android.app.R.id.login_activity_password);
    }

    public void testPreConditions() {
        assertTrue("Activity is null!", mActivity != null);
    }

    public void testLogin() throws Throwable {
        mActivity.runOnUiThread(new Runnable() {
            public void run() {
                mTextUserName.setText("username");
                mTextUserPassword.setText("password");
            }
        });
        sendKeys(KeyEvent.KEYCODE_ENTER);
    }
}

Некоторые идеи, как я могу это исправить?

Обновление: похоже, сборка / тестирование муравья все еще беспорядок. Согласно этой записи в блоге о тестировании библиотечного проекта, большинство из 7 перечисленных проблем будут исправлены в следующем выпуске ADT (ADT r20).

1 ответ

Решение

Есть много разной информации, касающейся использования Library проекты, начиная с ADT 17, ломали / исправляли все (в зависимости от того, в какой момент вы сейчас бьетесь головой о стол).

Прежде всего, обратите внимание на разницу между Library и "библиотека" где Library это существительное, определенное командой Android. Я также использую Referencing проект, который описывает проект, который использует Library проект.

то есть Referencing Проект использует Library проект.

не Library"библиотека" Проекты

В обычной разработке Java можно связать проекты в Eclipse, где один зависит от источника другого. Я полагаю, что такой подход позволяет использовать источник (и) библиотечных проектов в качестве источника для ссылочного проекта. Это означает, что источник библиотечных проектов находится в области действия при компиляции ссылочного проекта. Классы проекта библиотеки создаются одновременно с классами ссылочного проекта.

При сборке для использования в большинстве ситуаций это работает отлично, так как все классы создаются и затем упаковываются в файлы JAR или WAR или что-то еще.

Библиотечные проекты

Конкурирующий (не смешанный и подходящий) подход к библиотечным проектам - команды AndroidLibraryпроекты:

Проект Android, помеченный как Library Проект скомпилирует и соберет свои источники в jar файл в его bin каталог (после команды clean/build). любой Referencing проекты автоматически импортируют это jar и получить доступ к Libraryфункциональность проектов. Вы можете увидеть эти отношения, заглянув внутрь библиотеки JavaAndroid Dependenciesв проводнике пакетов.

Наряду с разрешением зависимостей класса на ресурс также непосредственно ссылаются и компилируют в R.java файлы внутриReferencingпроектовgenкаталог.

НовыйADTпредставил проблемы созданным народам, потому что он добавил "поддержку" для включения банок, на которые ссылалисьLibrary проект:

До ADT 17

Library Проект добавил банку к пути сборки. Referencing В проекте также может быть добавлен jar к собственному пути сборки.

ADT 17 года

Работа с зависимостями

После ADT 17 Library проекты, которые динамически ссылались на свои собственные банки, начали вести себя странно. Это был не просто случай включения той же зависимой ссылки в ваш Referencing Проект, чтобы держать кувшин видимым в обеих областях. Это теперь привело к странному дублированию включенных классов.

К сожалению, просто удалив библиотеку из Referencing или же Library проект (поэтому присутствовала только одна ссылка) затем запутал затмение, он больше не мог видеть банку из сферы действия проекта, используя его.

Чтобы это исправить, вам нужно разместить Library проекты банок в /libs каталог - это может быть боль в тылу, если ваши банки находятся в труднодоступных местах на вашем жестком диске. Эти банки будут автоматически использоваться в вашем Library а также Referencing проекты.

Итак, чтобы пройти мимо ADT 17:

  • Удалите все файлы JAR, которые не используются в качестве источника в текущей области проекта (будь то ваш Library или же Referencing проект).
  • Не удаляйте ни одного "библиотечного" проекта из вашего Library проект (вместо этого скомпилируйте их в банки).
  • Удалите внешние банки с вашего Library проект, скопируйте их в libs каталог вместо.
Другие вопросы по тегам