Les tests de Vues personnalisées avec Robolectric
Je suis en train de lancer les tests unitaires avec Robolectric 2.1.1 et je ne parviens pas à gonfler des mises en page personnalisées (par exemple, ViewPagerIndicator classes).
Supposons que c'est ma mise en page:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="test"
android:id="@+id/test_test"/>
<com.viewpagerindicator.CirclePageIndicator
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
J'classe de test:
@RunWith(RobolectricTestRunner.class)
public class TestRoboActivityTest {
private TestRoboActivity mActivity;
@Before
public void setUp() throws Exception {
mActivity = Robolectric.buildActivity(TestRoboActivity.class).create().get();
}
@After
public void tearDown() throws Exception {
mActivity = null;
}
@Test
public void testSanity() throws Exception {
Assert.assertNotNull(mActivity);
}
}
De l'exécution 'mvn clean test résultats des
Tests en erreur: testSanity(TestRoboActivityTest): fichier XML .\res\layout\test.xml ligne n ° -1 (désolé, pas encore mis en œuvre): Erreur de gonflage de la classe com.viewpagerindicator.CirclePageIndicator
Cool, donc il semble que les vues personnalisées ne sont pas encore pris en charge. La vérification de l'échantillon Robolectric projet sur leur site web,
une solution serait de gonfler la mise en page de LayoutInflater:
@RunWith(RobolectricTestRunner.class)
public class TestRoboActivityTest {
private View mTestRoboActivityView;
@Before
public void setUp() throws Exception {
mTestRoboActivityView = LayoutInflater.from(new Activity()).inflate(R.layout.test, null);
}
@After
public void tearDown() throws Exception {
mTestRoboActivityView = null;
}
@Test
public void testSanity() throws Exception {
Assert.assertNotNull(mTestRoboActivityView);
}
}
qui se traduit par:
Tests en erreur: testSanity(TestRoboActivityTest): fichier XML .\res\layout\test.xml ligne n ° -1 (désolé, pas encore mis en œuvre): Erreur de gonflage de la classe com.viewpagerindicator.CirclePageIndicator
Mon dernier recours est d'essayer d'utiliser de l'ombre classes:
@Implements(CirclePageIndicator.class)
public class CirclePageIndicatorShadow implements PageIndicator {
@Override
@Implementation
public void setViewPager(ViewPager view) {
//Stub
}
//etc.
}
et à l'aide de @Config(shadows = {CirclePageIndicatorShadow.class})
. Cela a entraîné
Tests en erreur: testSanity(TestRoboActivityTest): fichier XML .\res\layout\test.xml ligne n ° -1 (désolé, pas encore mis en œuvre): Erreur de gonflage de la classe com.viewpagerindicator.CirclePageIndicator
Édition (Décembre 2014)
Veuillez noter que la suite de stracktrace a été ajouté plus tard par David Rabinowitz. Bien que liées, il n'est pas la question, j'ai été confronté à l'époque.
Ici est la trace de la pile:
android.view.InflateException: XML file .\res\layout\activity_home.xml line #-1 (sorry, not yet implemented): Error inflating class com.test.custom.RobotoTextView
at android.view.LayoutInflater.createView(LayoutInflater.java:613)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
at android.app.Activity.setContentView(Activity.java)
at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:241)
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.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
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)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createView(LayoutInflater.java:587)
at android.view.LayoutInflater.createView(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.rInflate(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:352)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.robolectric.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:455)
at android.app.Activity.setContentView(Activity.java)
at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
... 22 more
Caused by: java.lang.RuntimeException: error converting RobotoMedium.ttf using EnumConverter
at org.robolectric.shadows.Converter.convertAndFill(Converter.java:150)
at org.robolectric.shadows.Converter.convertAndFill(Converter.java:50)
at org.robolectric.shadows.ShadowResources.createTypedArray(ShadowResources.java:228)
at org.robolectric.shadows.ShadowResources.attrsToTypedArray(ShadowResources.java:203)
at org.robolectric.shadows.ShadowResources.access$000(ShadowResources.java:51)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:460)
at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java)
at android.widget.TextView.__constructor__(TextView.java:561)
at android.widget.TextView.<init>(TextView.java:447)
at android.widget.TextView.<init>(TextView.java:442)
at com.test.custom.RobotoTextView.<init>(RobotoTextView.java:16)
at android.view.LayoutInflater.createView(LayoutInflater.java:587)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
at android.app.Activity.setContentView(Activity.java)
at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
... 22 more
Caused by: java.lang.RuntimeException: no value found for RobotoMedium.ttf
at org.robolectric.shadows.Converter$EnumOrFlagConverter.findValueFor(Converter.java:375)
at org.robolectric.shadows.Converter$EnumConverter.fillTypedValue(Converter.java:343)
at org.robolectric.shadows.Converter$EnumConverter.fillTypedValue(Converter.java:336)
at org.robolectric.shadows.Converter.convertAndFill(Converter.java:148)
at org.robolectric.shadows.Converter.convertAndFill(Converter.java:50)
at org.robolectric.shadows.ShadowResources.createTypedArray(ShadowResources.java:228)
at org.robolectric.shadows.ShadowResources.attrsToTypedArray(ShadowResources.java:203)
at org.robolectric.shadows.ShadowResources.access$000(ShadowResources.java:51)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:460)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.robolectric.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:455)
at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java)
at android.widget.TextView.$$robo$$TextView_347d___constructor__(TextView.java:561)
at android.widget.TextView.<init>(TextView.java:447)
at android.widget.TextView.<init>(TextView.java:442)
at com.test.custom.RobotoTextView.<init>(RobotoTextView.java:16)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createView(LayoutInflater.java:587)
at android.view.LayoutInflater.createView(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.rInflate(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:352)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.robolectric.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:455)
at android.app.Activity.setContentView(Activity.java)
at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
... 22 more
Pourriez-vous les gars merci de me pointer dans la bonne direction? Je suis à court d'idées.
Merci.
- Pouvez-vous poster plein de trace de pile?
- Êtes-vous d'utiliser une police personnalisée, ou une vue personnalisée qui utilise une police personnalisée? Je pense que @joecks est sur la bonne voie avec leur réponse. Android ne peut pas afficher les polices personnalisées dans un aperçu (c'est à dire, lorsque vous êtes à la recherche xml dans Eclipse), et le même problème peut se produire ici. Si vous contrôlez l'affichage de texte, essayez d'emballage code qui récupère le style avec
if (!isInEditMode())
- Êtes-vous capable de voir la vue personnalisée dans la mise en page xml aperçu graphique?
- Similaire: les Tests ViewPager (et CursorLoader) avec Robolectric
- Je peux tester des vues personnalisées. Peut-être que quelque chose est incorrect avec votre affichage personnalisé. Essayez de faire un temporaire et très simple affichage personnalisé (fondamentalement, il suffit de prolonger le bouton ou textview). Branchez cette simple vue personnalisée où votre vue actuelle est. Voir si elle se plaint encore à ce sujet.
- Pourrait l'OP poster son/sa trace de la pile pour que nous puissions vous aider? Avoir quelqu'un d'autre trace de la pile n'est pas très utile. Merci.
- Avez-vous trouvé un solution pour cela ? Je suis confronté au même type de problème.
Vous devez vous connecter pour publier un commentaire.
Problème:
Ce problème se produit, parce que gradle fusionne les dépendances d'un projet (ex:
compile project(':lib-custom')
) et dépendances externes (ex:compile 'lib.package:name:1.1.0'
) de manière différente. Après les dépendances ont été fusionnées app aR.java
fichier avec toutes les ressources des champs (couleurs, id, un drawable, ...). Mais généréR.java
fichier est différent après la fusion des submodules et dépendances externes.Ce problème n'existe qu'avec les projets, qui ont des vues personnalisées dans les submodules. Dans le cas de dépendances externes il y a une autre questions, qui peuvent être facilement corrigé. Lisez à propos de dépendances types ici.
Pour les dépendances d'un projet résultat
R.java
fichier contient tous les identificateurs de ressources, mais les identificateurs de sous-module n'est pas égale à leur valeur d'origine identificateurs d'entier:Pour les dépendances externes fusionné
R.java
fichier juste un résultat de la fusion de R.java les fichiers de toutes les dépendances externesSolution:
J'ai trouvé deux solutions possibles:
Mais ce n'est pas encore assez - vous besoin d'ajouter des items relatifs au projet.fichier de propriétés à votre principale sourceSet. Plus d'infos ici
Exemple:
Vous pouvez vérifier diff pour cette solution ici
Error inflating class
.Je préfère la première solution, mais il n'est pas possible, parfois, projet de modification de la dépendance à l'externe.
J'ai aussi l'intention de faire rapport sur cette question à Robolectric équipe.
P. S. j'ai projet sur github liées à cette question.
Je test vues dans la même classe de test avec l'Activité qui les utilise. Dans ce cas, je dis Robolectric pour donner un exemple de cette Activité, et depuis que j'ai récupérer une instance de la gonflés vue:
LE: - je utiliser Robolectric 3.0 donc je ne sais pas si cela s'applique à vous.
mTestRoboActivityView = LayoutInflater.from(new Activity()).inflate(R.layout.test, null);
Dans cette ligne de code que vous avez utilisé de cette nouvelle Activité () " désigne l'instance de la nouvelle Activité, qui n'est pas pour votre Activité actuelle.
Vous pouvez résoudre ce problème en passant de l'instance sur l'Activité en cours.
Utilisez ce
Je ne suis pas sûr que le code ci-dessus fonctionne bien, mais l'utilisation de la référence, de l'instance de l'Activité en cours.
Reportez-vous qu'il peut être vous aider.
Vous ne pouvez pas gonfler le nombre de vues dans Roboelectric puisqu'elle n'utilise pas la complète android de cadre, mais au lieu de cela on se moque de toutes les API Android de.
Vous ne devez pas utiliser roboelectric de test réel affichage de comportement.
Il est utilisé pour les tests unitaires et juste pour tester votre logique métier et ne pas regarder le dessin/l'écran, etc. À atteindre que Vous pouvez créer par programme, des objets et de se moquer de certaines pièces du système android (Utiliser quelque chose comme Mockito ou Powermock).
par exemple d'un simple point de vue de test dans roboelectic:
Aussi, si vous voulez tester le rendu de la façon dont votre point de vue semble ou rend etc, vous devez utiliser les tests fonctionnels des frameworks tels que Espresso ou Robotium qui tournent sur un périphérique réel.
Où est Viewpager? . Il est d'avoir d'erreur, car CirclePageIndicator veut gonfler le point de vue, mais il n'y a rien à gonfler. l'indicateur.setViewPager(téléavertisseur);