Использование Android SDK Tools r15 и Eclipse.
Предположим, вы создаете три проекта в eclipse: Lib (проект библиотеки android) <- App (проект приложения android) <- Test (проект android unit test) и определяетеследующие классы: </p>
[Lib]
public class A {}
[App]
public class A extends B {}
[Test]
public class MyUnitTest extends AndroidTestCase {
public void test() {
new A();
new B();
}
}
В этой настройке TestMainссылается на TestLib как библиотеку Android, а TestMainTest имеет проектную ссылку на TestMain.
Вы должны увидеть, что Test не компилируется, поскольку не удается разрешить A.Это ожидается, потому что Test не имеет видимости в Lib.Одним из решений является добавление ссылки на библиотеку из Test в Lib.Хотя это решает проблему компиляции, оно ломается во время выполнения.В результате возникает куча ошибок, но вот интересная:
W/dalvikvm( 9275): Class resolved by unexpected DEX: Lcom/example/B;(0x40513450):0x294c70 ref [Lcom/example/A;] Lcom/example/A;(0x40513450):0x8f600
W/dalvikvm( 9275): (Lcom/example/B; had used a different Lcom/example/A; during pre-verification)
W/dalvikvm( 9275): Unable to resolve superclass of Lcom/example/B; (1)
W/dalvikvm( 9275): Link of class 'Lcom/example/B;' failed
E/dalvikvm( 9275): Could not find class 'com.example.B', referenced from method com.example.test.MyUnitTest.test
W/dalvikvm( 9275): VFY: unable to resolve new-instance 3 (Lcom/example/B;) in Lcom/example/test/MyUnitTest;
D/dalvikvm( 9275): VFY: replacing opcode 0x22 at 0x0000
D/dalvikvm( 9275): VFY: dead code 0x0002-000a in Lcom/example/test/MyUnitTest;.test ()V
Это связано с тем, что оба проекта: Test и App ссылаются на проект библиотеки Lib, поэтому оба полученных apk включают копию com.example.A.
Не добавляйте явные зависимости в затмении из тестового проекта в проект библиотеки (если эта библиотека является зависимостью тестируемого проекта приложения).Это может привести к тому, что и проект приложения, и тестовый проект будут включать копии одинаковых классов в свои конечные файлы apks, и тест не будет выполнен во время выполнения.вопрос.Во время выполнения Test будет видеть приложение и, следовательно, классы в Lib.Вместо создания ссылки на библиотеку из Test to Lib обновите путь сборки приложения, чтобы экспортировать его библиотечные проекты.Теперь тест компилируется, и модульный тест успешно выполняется.
В Eclipse, чтобы протестировать проект приложения, который ссылается на проект библиотеки, экспортируйте проекты библиотеки из проекта приложения в его настройках пути сборки.
Теперь все работает в Eclipse, но как насчет Ant?Используйте команды проекта android update [lib- | test-] для создания необходимых файлов build.xml.Обязательно запустите Ant clean во всех трех каталогах: Lib, App и Test.Невозможность очистить все три проекта может привести к успешной компиляции.
Компиляция Ant завершится неудачно с:
[javac] ...Test/src/com/example/test/MyUnitTest.java:3: cannot find symbol
[javac] symbol : class A
[javac] location: package com.example
[javac] import com.example.A;
[javac] ^
[javac] ...Test/src/com/example/test/MyUnitTest.java:10: cannot access com.example.A
[javac] class file for com.example.A not found
[javac] new B();
[javac] ^
[javac] ...Test/src/com/example/test/MyUnitTest.java:11: cannot find symbol
[javac] symbol : class A
[javac] location: class com.example.test.MyUnitTest
[javac] new A();
[javac] ^
[javac] 3 errors
Почему сборка Ant завершается неудачно, когда сборка Eclipse завершается успешно?Системы сборки Eclipse и Ant отличаются друг от друга.Экспорт проектов библиотеки из App в Eclipse не влияет на сборку Ant.Сборка не удалась, потому что тестовый проект не имеет видимости в проект Lib.Если мы попытаемся решить эту проблему, добавив свойство android.library.refernce в Test / project.properties, мы сделали то же самое, что и добавили ссылку на библиотеку из Test в Lib в Eclipse.Сборка Ant будет выполнена успешно, но во время выполнения тест завершится неудачно со знакомой ошибкой «Класс разрешен неожиданным DEX».
Нам нужен способ компиляции тестового проекта с библиотечным проектом, но не включающийэто в процессе дексинга.Есть два шага к этому процессу.Во-первых, включите ссылку из Test to Lib, которая не влияет на Eclipse.Во-вторых, обновите систему сборки Ant, чтобы библиотека была скомпилирована, но исключена из dexing.
В верхней части Test / build.xml я определяю свойство, которое указывает на библиотеку.Это похоже на добавление ссылки на Test / project.properties, за исключением того, что Eclipse ее не увидит:
Теперь нам нужно исключить библиотечный jar из процесса dexing.Это требует обновления макроса dex-helper.Я помещаю макрос переопределения после строки в моем файле Test / build.xml.Новый dex-helper исключает все jar-файлы, отсутствующие в дереве папок проекта Test, из процесса dexing:
<macrodef name="dex-helper">
<element name="external-libs" optional="yes"/>
<attribute name="nolocals" default="false"/>
<sequential>
<!-- sets the primary input for dex. If a pre-dex task sets it to
something else this has no effect -->
<property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}"/>
<!-- set the secondary dx input: the project (and library) jar files
If a pre-dex task sets it to something else this has no effect -->
<if>
<condition>
<isreference refid="out.dex.jar.input.ref"/>
</condition>
<else>
<!--
out.dex.jar.input.ref is not set. Compile the list of jars to dex.
For test projects, only dex jar files included in the project
path
-->
<if condition="${project.is.test}">
<then>
<!-- test project -->
<pathconvert pathsep="," refid="jar.libs.ref" property="jars_to_dex_pattern"/>
<path id="out.dex.jar.input.ref">
<files includes="${jars_to_dex_pattern}">
<!-- only include jar files actually in the test project -->
<filename name="${basedir}/**/*"/>
</files>
</path>
<property name="in_jars_to_dex" refid="jar.libs.ref"/>
<property name="out_jars_to_dex" refid="out.dex.jar.input.ref"/>
<echo message="Test project! Reducing jars to dex from ${in_jars_to_dex} to ${out_jars_to_dex}."/>
</then>
<else>
<path id="out.dex.jar.input.ref"/>
</else>
</if>
</else>
</if>
<dex executable="${dx}" output="${intermediate.dex.file}" nolocals="@{nolocals}" verbose="${verbose}">
<path path="${out.dex.input.absolute.dir}"/>
<path refid="out.dex.jar.input.ref"/>
<external-libs/>
</dex>
</sequential>
</macrodef>
С этими изменениями Test собирает и запускает как из Eclipse, так и из Ant.
Счастливого тестирования!
Другие примечания: Если что-тоне создавайте в Eclipse, и вы считаете, что они должны, попробуйте обновить проекты в следующем порядке: Lib, App, Test. Мне часто приходится делать это после внесения изменений в пути сборки. Мне также иногда приходится собирать чистые вещи, чтобы все работало правильно.