2013-03-24 4 views
4

Каждый год я запускаю тесты, отличные от Android JUnit, из Eclipse. Сегодня я хотел протестировать некоторые из моих классов библиотеки Android. О, боль.Простой тест без использования API Android JUnit в Eclipse с android-maven-plugin?

У меня есть проект для Android-андроида, использующий android-maven-plugin. У меня есть исходные файлы в src/main/java и мой (новый) модульный тест в src/test/java. У моей POM есть соответствующие зависимости JUnit и ссылки на android-maven-plugin.

Иногда я создаю экземпляр для Android Uri из File. Иногда у меня есть существующий Java URI экземпляр, который я создал из File, который затем конвертирую в Uri. Поскольку я не доверяю ни Java, ни Android с файлами и URI (не заставляйте меня начинать с того, как Java управляет путями UNC в URI или как Java нарушает договор equals() в URI), я хотел создать простой модульный тест для создания временного файл, создайте Uris из двух разных подходов и убедитесь, что они равны.

Итак, я делаю небольшое тестовое тестирование JUnit, как я привык, и попытаюсь запустить его в Eclipse, используя Ctrl+F11. Eclipse спрашивает меня, является ли это «Android JUnit Test» или «JUnit Test». Ну, Android, очевидно. Поэтому я выбираю первый вариант и получаю:

[2013-03-23 21:37:10 - mylib] ------------------------------ 
[2013-03-23 21:37:10 - mylib] Android Launch! 
[2013-03-23 21:37:10 - mylib] adb is running normally. 
[2013-03-23 21:37:10 - mylib] Could not find mylib.apk! 

Хммм ... это было не очень удачным. Поэтому я удаляю конфигурацию запуска и пытаюсь просто «JUnit Test». Теперь я получаю другой диалог, прося меня выбрать мою привилегированную пусковую установку «Android JUnit Test Launcher» или «Eclipse JUnit Test Launcher». Неважно, что я выбираю; Я получаю:

Class not found com.example.MyUnitTest 
java.lang.ClassNotFoundException: com.example.MyUnitTest 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:693) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:429) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

Я читал, что с андроид-Maven-плагин я могу запустить юнит-тесты локально в Eclipse, если они просто использовать классы в Android банку, но не делают никаких API вызовов, который что я здесь делаю. Так как я могу снять это?

+1

И, что еще хуже, я больше не могу запускать приложение, которое зависит от этой библиотеки, поскольку Eclipse/Android жалуется, что в сгенерированных файлах Dex имеется несколько вхождений JUnit/Hamcrest. Поэтому мне нужно вырвать зависимости JUnit из POM и прокомментировать любые аннотации или вызовы, связанные с JUnit, из тестовых файлов. –

+0

P.S. Разумеется, причина, по которой я создал этот тест для начала, заключалась в том, чтобы увидеть, создают ли Android и Java одинаковые типы URI из файлов. Nope: один использует 'file: ///', а другой использует 'файл: /'. Sheesh --- почему люди не могут заставить простейшие вещи работать последовательно? –

+0

Просто, чтобы обратить ваше внимание на эту часть файла File.toURI() javadoc: «URI зависит от системы и не может быть передан между различными операционными/файловыми системами». – ben75

ответ

0

Тест андроида-юнита должен быть расположен в отдельном модуле в качестве установки в проектах образцов Android Maven Plugin (например, пример morseflash). Это связано с настройкой перегруженного пути и необходимостью сборки apk и развертывания на устройстве/эмуляторе для запуска теста. Тесты junit для Android - это НЕ единичные тесты вообще, а скорее интеграционный тест (или в этом случае называемый контрольно-измерительными тестами).

+0

Но что, если я не хочу запускать тест на устройстве/эмуляторе? Что делать, если я хочу запустить его локально? –

+0

Если это тест junit для Android, вы не можете запустить его локально. Вот как работают эти тесты. Если вам нужно запустить локально, используйте Robolectric. –

+0

Затем, как вы интерпретируете [android-maven-plugin documentation] (http://code.google.com/p/maven-android-plugin/wiki/GettingStarted), в котором говорится: «Если у вас есть тесты JUnit, t вызывать любые API Android (прямо или транзитивно), помещать их в 'src/test/java', поэтому JUnit запускает их локально и быстрее, чем при запуске на устройстве." –

3

Не используйте Run As - Android JUnit Test как для бега Android Test Project.

При использовании Run As - JUnit Test, то ClassNotFoundException из-за несогласованности между ADT и Затмение встроенных тестов JUnit относительно папки вывода проекта. ADT генерирует все .class файлы под bin/classes, тогда как встроенный JUnit Test Runner ищет .class файлы под target/classes. Ваш проект Android в Eclipse никогда не использует target/classes, поэтому он остается пустым, поэтому вы получаете ClassNotFoundException исключение.

AFAIK нет возможности изменить Eclipse встроенный JUnit Test Runner для использования другой папки, чем целевой/класс по умолчанию. Просмотрите Ricardo's answer, чтобы узнать, как добавить bin/classes к встроенному пути прохождения JUnit Test Runner. Также обратите внимание, что вы не можете изменить выходную папку по умолчанию вашего Android-проекта на что-то еще, чем на ../bin/classes либо, так как он сломает процесс сборки ADT.

Грязный обходной путь (для решения ClassNotFoundException) является ручным копия все под bin\classes к target\classes, обратите внимание, что вам нужно сделать, это каждый раз, когда вы изменяете исходный код.

Это не проблема при запуске mvn test из командной строки или с помощью Eclipse, а Maven использовать target\classes и знают, как заполнить его правильно. обратите внимание, что с помощью этого подхода вы не сможете использовать окно JUnit с красивой красной/зеленой ошибкой внутри Eclipse.

+0

Итак, даже если я не использую Eclipse для запуска тестов и запуска их вручную, они все равно должны быть способны компилировать в Eclipse и генерировать файлы Dex правильно.Однако, как я упоминал в своем комментарии, просто включение JUnit в зависимости (которое требуется для их компиляции) приводит к ошибке, которую JUnit был дважды включен, когда я пытаюсь развернуть приложение? Как мне обойти это? –

+0

В вашей POM убедитесь, что вы используете ' тест' для вашей зависимости от JUnit. – yorkw

+0

Да, я использую область проверки. Вы пытались добавить тесты JUnit в библиотеку Android с помощью Maven, а затем включить эту библиотеку в отдельный проект приложения для Android с несколькими из этих проектов с использованием зависимостей JUnit в области проверки? –

4

Обходной путь - это нажать кнопку «Запустить как ...» на панели инструментов, а затем выбрать «Запустить конфигурации ...». Если вы выберете созданную JUnit-пусковую установку и перейдите на вкладку «Classpath», вы можете добавить папку bin/classes в путь класса JUnit launcher. Это должно теперь работать.

+0

Я пробовал это, и он работает как шарм, спасибо! – yorkw

+1

Вот оно! Работает как чемпион. Просто, чтобы сделать его более понятным (я немного пытался понять, что сказал Рикардо). Щелкните правой кнопкой мыши ваш тестовый проект -> Запустить как -> Запустить конфигурации -> На вкладке «Тест» посмотрите ниже «Использование Android JUnit Test Launcher» -> Нажмите «Выбрать другое» -> Выберите подходящий вариант -> Ок -> Запустить! Там вы идете! – dazito

 Смежные вопросы

  • Нет связанных вопросов^_^