web-dev-qa-db-fra.com

Où est écrit la sortie du journal lors de l'utilisation de Robolectric + Roboguice?

J'utilise Robolectric pour tester Android. J'exécute mes tests via maven, par exemple.

mvn -Dtest=LogTest test

Si j'ai du code qui écrit dans les journaux, tels que

Log.d("TAG", "blah");

ou en utilisant la variable Ln de Roboguice

Ln.d("blah");

Je ne vois pas de sortie dans les journaux infaillibles de Maven (fichiers texte).

Idéalement, je souhaite réellement que les instructions de journal simples soient envoyées à la console. Je peux écrire sur la console en utilisant System.out.println("blah"), mais bien sûr, je préfère utiliser les API de journalisation prises en charge.

Ma question est donc la suivante: pourquoi ne vois-je pas du tout la sortie du journal et comment puis-je écrire les messages du journal dans la console?

45
Tyler Collier

Je cours robolectric-2.0-alpha-3 .

Ce qui a fonctionné pour moi a été de définir dans la méthode setUp de mon test le flux sur stdout

Quelque chose comme:

@Before
public void setUp() throws Exception {
  ShadowLog.stream = System.out;
  //you other setup here
}

Avec cette version de robolectric, je n'ai pas réussi à faire de même (ShadowLog.stream = System.out) dans un TestRunner personnalisé ou dans mon TestLifeycleApplication. 

La définition de la propriété système System.setProperty("robolectric.logging","stdout"); était également sans effet, mais cela pourrait fonctionner dans les versions précédentes.

70

J'utilise robolectric 2.3. Comment ça marche pour moi:

Dans mon @Avant:

ShadowLog.stream = System.out;

Dans mes fonctions de test, je peux utiliser (ShadowLog. Ont d’autres options):

ShadowLog.v("tag", "message");

Et dans ma classe testée, je peux mettre quelques messages au journal avec:

System.out.println("message");
14
Bamumi

Par défaut, l'enregistrement de la sortie lorsque vous utilisez RobolectricTestRunner disparaît. Vous pouvez configurer sa destination en consultant la méthode setupLogging () de cette classe.

Pour résumer, vous devez définir la propriété système robolectric.logging sur stdout, stderr ou un chemin de fichier dans lequel le journal doit être écrit. Je fais cela dans le constructeur d'une sous-classe de RobolectricTestRunner que j'utilise pour tous les tests afin que les journaux soient toujours écrits sur stdout.

11
Edward Dale

Ajoutez les éléments suivants à votre configuration de test avant l’exécution de votre test:

ShadowLog.stream = System.out;
Robolectric.bindShadowClass(ShadowLog.class);

https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ

5
emmby

Lorsque vous exécutez des tests avec Maven, vous avez besoin de quelque chose comme ceci:

                 <plugin>
                    <groupId>org.Apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.17</version>
                    <configuration>
                        <systemPropertyVariables>
                          <robolectric.logging>stdout</robolectric.logging>
                        </systemPropertyVariables>
                    </configuration>
                 </plugin>

Lorsque vous exécutez les tests localement, par exemple Dans intellij, tout ce dont vous avez besoin est d’une variable d’environnement: Il suffit d’aller (pour intellij) dans Exécuter/Déboguer les configurations -> Par défaut -> Junit -> VM options et ajouter 

-Drobolectric.logging=stdout
2
sakis kaliakoudas

La solution qui me convenait le mieux (ou pas du tout) consistait à initialiser une implémentation injectée de remplacement (pendant les tests uniquement) de la classe Ln.Print de RoboGuice pour effectuer l’impression System.out au lieu de l’impression Log d’Android, étant donné que j’utilisais Robolectric pour éviter de dépendre du sous-système Android pour exécuter mes tests en premier lieu.

De Ln.Java :

public class Ln  {
...

/**
 * print is initially set to Print(), then replaced by guice during
 * static injection pass.  This allows overriding where the log message is delivered to.
 */
@Inject protected static Print print = new Print();

Donc en gros:

public class TestModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Ln.Print.class).to(TestLogPrint.class);
    }

}

et:

public class TestLogPrint extends Print {

    public int println(int priority, String msg ) {

        System.out.println(
            String.format(
                "%s%s", 
                getScope(4), 
                msg
            )
        );

        return 0;
    }

    protected static String getScope(int skipDepth) {
        final StackTraceElement trace = Thread.currentThread().getStackTrace()[skipDepth];
        return String.format("%s | %s.%s | ", new Date(), trace.getFileName().replace(".Java", ""), trace.getMethodName());
    }
}

Cela bien entendu en supposant que l’initiation standard Robolectric associe le module à RoboGuice: 

@Before
public void setUp() throws Exception {

    Module roboGuiceModule = RoboGuice.newDefaultRoboModule(Robolectric.application);
    Module productionModule = Modules.override(roboGuiceModule).with(new CustomRoboModule());
    Module testModule = Modules.override(productionModule).with(new TestModule());

    RoboGuice.setBaseApplicationInjector(Robolectric.application, RoboGuice.DEFAULT_STAGE, testModule);
    RoboGuice.injectMembers(Robolectric.application, this);

}
0
Roberto Andrade