Scrivi un programma di test Tradefed

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

Sfondo

Se ti interessa sapere dove si trovano gli esecutori test nell'architettura di Tradefed, consulta Struttura di un esecutore test.

Questo non è un prerequisito per la scrittura di un nuovo esecutore test; gli esecutori test possono essere scritti in isolamento.

Requisito minimo: implementare l'interfaccia

Il requisito minimo per essere considerato un esecutore 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 l'esecutore test, in modo simile a un Java Runnable.

Ogni parte di questo metodo è considerata parte dell'esecuzione dell'esecutore test.

Segnalare i risultati dall'esecutore test

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

Segnalando i risultati strutturati, un esecutore test ha le seguenti proprietà:

  • Segnala un elenco corretto di tutti i test eseguiti, la durata e se sono stati superati, non superati o in altri stati.
  • Segnala le metriche associate ai test, se applicabili, ad esempio le metriche relative al tempo di installazione.
  • Si adatta alla maggior parte degli strumenti dell'infrastruttura, ad esempio la visualizzazione dei risultati e delle metriche e così via.
  • Di solito è più facile eseguire il debug perché è presente una traccia più granulare dell'esecuzione.

Detto questo, la segnalazione dei risultati strutturati è facoltativa; un esecutore test potrebbe semplicemente voler valutare lo stato dell'intera esecuzione come SUPERATO o NON SUPERATO senza alcun dettaglio dell'esecuzione effettiva.

I seguenti eventi possono essere chiamati 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. Uno scenario 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 dall'esecuzione. Ad esempio, un file 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 la garanzia dell'ordine corretto dei callback sono responsabilità dell'implementatore dell'esecutore test, ad esempio assicurandosi che testRunEnded venga chiamato in caso di eccezione utilizzando una clausola finally.

I callback degli scenari 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 a lla tipica struttura JUnit. Questo è intenzionale per mantenere le cose vicine a qualcosa di base che gli sviluppatori di solito conoscono.

Segnalare i log dall'esecutore test

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

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

Test con un dispositivo

L'interfaccia minima sopra consente di eseguire test molto semplici, isolati e che non richiedono risorse particolari, ad esempio unit test 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 fase di 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.

Gli esecutori test sono in genere interessati a queste interfacce per ottenere artefatti relativi all'esecuzione, ad esempio file aggiuntivi, e ottenere il dispositivo in fase di test che verrà utilizzato durante l'esecuzione.

Test con più dispositivi

Tradefed supporta l'esecuzione di test su più dispositivi contemporaneamente. Questa funzionalità è utile quando si testano componenti che richiedono un'interazione esterna, ad esempio l'accoppiamento di uno smartphone e uno smartwatch.

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

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

Test che conoscono le loro configurazioni

Alcune implementazioni dell'esecutore test potrebbero richiedere informazioni sulla configurazione generale per funzionare correttamente, ad esempio alcuni metadati sulla chiamata o quale target_preparer è stato eseguito in precedenza e così via.

Per farlo, un esecutore test può accedere all'oggetto IConfiguration di cui fa parte e in cui viene eseguito. Per maggiori dettagli, consulta la descrizione dell'oggetto di configurazione.

Per l'implementazione dell'esecutore test, dovrai implementare IConfigurationReceiver per ricevere l'oggetto IConfiguration.

Esecutore test flessibile

Gli esecutori test possono fornire un modo flessibile per eseguire i test se hanno un controllo granulare su di essi, ad esempio un esecutore test JUnit può eseguire singolarmente ogni unit test.

In questo modo, l'harness e l'infrastruttura più grandi possono sfruttare questo controllo preciso e gli utenti possono eseguire parzialmente l'esecutore test tramite filtraggio.

Il supporto per il filtraggio è 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 è che un test verrà 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.