Scrivi un programma di test Tradefed

Questa pagina descrive come scrivere un nuovo test runner in Tradefed.

Sfondo

Se ti incuriosisce il ruolo dei test runner nell'architettura di Tradefed, consulta Struttura di un test runner.

Non si tratta di un prerequisito per scrivere un nuovo test runner; i test runner possono essere scritti in isolamento.

Il minimo indispensabile: implementa l'interfaccia

Il minimo indispensabile per essere considerato un esecutore di test Tradefed è implementare l'interfaccia IRemoteTest e, più nello specifico, il metodo run(TestInformation testInfo, ITestInvocationListener listener).

Questo metodo viene richiamato dall'harness quando si utilizza il test runner, in modo simile a un Runnable Java.

Ogni parte di questo metodo viene considerata parte dell'esecuzione del test runner.

Risultati del report dal test runner

Il metodo run nell'interfaccia di base fornisce l'accesso a un oggetto listener di tipo ITestInvocationListener. Questo oggetto è la chiave per segnalare risultati strutturati dal test runner all'harness.

Se segnala risultati strutturati, un test runner ha le seguenti proprietà:

  • Genera un elenco appropriato di tutti i test eseguiti, della loro durata e del loro stato (superato, non superato o altro).
  • Se applicabile, segnala le metriche associate ai test, ad esempio le metriche relative al tempo di installazione.
  • Adattarsi alla maggior parte degli strumenti dell'infrastruttura, ad esempio visualizzare risultati e metriche e così via.
  • Di solito è più facile eseguire il debug perché esiste una traccia più granulare dell'esecuzione.

Detto questo, la generazione di report sui risultati strutturati è facoltativa. Un test runner potrebbe semplicemente voler valutare lo stato dell'intera esecuzione come PASSED o FAILED senza alcun dettaglio sull'esecuzione effettiva.

È possibile chiamare i seguenti eventi sul listener per notificare all'Harness l'avanzamento corrente delle esecuzioni:

  • testRunStarted: notifica l'inizio di un gruppo di scenari di test correlati.
    • testStarted: notifica l'inizio di uno scenario di test.
    • testFailed/testIgnored: notifica la modifica dello stato dello scenario di test in corso. Un caso di test senza alcuna modifica dello stato viene considerato superato.
    • testEnded: notifica la fine dello scenario di test.
  • testRunFailed: notifica che lo stato generale dell'esecuzione del gruppo di scenari di test è un errore. Un'esecuzione del test può essere superata o non superata indipendentemente dai risultati degli scenari di test, a seconda di ciò che era previsto per l'esecuzione. Ad esempio, un binario che esegue diversi scenari di test potrebbe segnalare tutti gli scenari di test superati, ma con un codice di uscita di errore (per qualsiasi motivo: file trapelati e così via).
  • testRunEnded: notifica la fine del gruppo di scenari di test.

Il mantenimento e l'ordine corretto dei callback sono responsabilità dell'implementatore del test runner, ad esempio assicurarsi che testRunEnded venga chiamato in caso di eccezione utilizzando una clausola finally.

I callback dei casi di test (testStarted, testEnded e così via) sono facoltativi. Un'esecuzione del test potrebbe avvenire senza scenari di test.

Potresti notare che questa struttura di eventi è ispirata alla tipica struttura JUnit. Questo è intenzionale per mantenere le cose vicine a qualcosa di base che gli sviluppatori di solito conoscono.

Report dei log del test runner

Se stai scrivendo la tua classe di test o il tuo runner Tradefed, implementerai IRemoteTest e otterrai un ITestInvocationListener tramite il metodo run(). Questo listener può essere utilizzato per registrare i file nel seguente modo:

    listener.testLog(String dataName, LogDataType type_of_data, InputStreamSource data);

Testare con un dispositivo

L'interfaccia minima riportata sopra consente di eseguire test molto semplici, isolati e che non richiedono risorse particolari, ad esempio test delle unità Java.

Gli autori dei test che vogliono passare al passaggio successivo del test del dispositivo avranno bisogno delle seguenti interfacce:

  • IDeviceTest consente di ricevere l'oggetto ITestDevice che rappresenta il dispositivo in test e fornisce l'API per interagire con esso.
  • IBuildReceiver consente al test di ottenere l'oggetto IBuildInfo creato nel passaggio del fornitore di build contenente tutte le informazioni e gli artefatti relativi alla configurazione del test.

I test runner sono in genere interessati a queste interfacce per ottenere artefatti relativi all'esecuzione, ad esempio file aggiuntivi, e ottenere il dispositivo in test che verrà preso di mira durante l'esecuzione.

Testare con più dispositivi

Tradefed supporta l'esecuzione di test su più dispositivi contemporaneamente. Questa opzione è utile per testare componenti che richiedono un'interazione esterna, ad esempio l'accoppiamento di uno smartphone e uno smartwatch.

Per scrivere un test runner che possa utilizzare più dispositivi, devi implementare IMultiDeviceTest, che ti consentirà di ricevere una mappa da ITestDevice a IBuildInfo contenente l'elenco completo delle rappresentazioni dei dispositivi e le relative informazioni sulla build.

Il setter dell'interfaccia verrà sempre chiamato prima del metodo run, quindi è sicuro presupporre che la struttura sarà disponibile quando viene chiamato run.

Test consapevoli delle proprie configurazioni

Alcune implementazioni di test runner potrebbero richiedere informazioni sulla configurazione complessiva per funzionare correttamente, ad esempio alcuni metadati sull'invocazione o quali target_preparer sono stati eseguiti in precedenza e così via.

Per raggiungere questo obiettivo, un test runner può accedere all'oggetto IConfiguration di cui fa parte e in cui viene eseguito. Per ulteriori dettagli, consulta la descrizione dell'oggetto di configurazione.

Per l'implementazione del test runner, devi implementare IConfigurationReceiver per ricevere l'oggetto IConfiguration.

Esecutore test flessibile

I test runner possono fornire un modo flessibile di eseguire i test se hanno un controllo granulare su di essi. Ad esempio, un test runner JUnit può eseguire individualmente ogni test delle unità.

Ciò consente all'imbracatura e all'infrastruttura più grandi di sfruttare questo controllo preciso e agli utenti di eseguire parzialmente il test runner tramite il filtraggio.

Il supporto del filtro è descritto nell'interfaccia ITestFilterReceiver, che consente di ricevere set di filtri include e exclude per i test che devono o non devono essere eseguiti.

La nostra convenzione prevede che un test venga eseguito SE corrisponde a uno o più filtri di inclusione E non corrisponde a nessuno dei filtri di esclusione. Se non vengono forniti filtri di inclusione, tutti i test devono essere eseguiti purché non corrispondano a nessuno dei filtri di esclusione.