Uno dei modi per estendere LoadTests in VSTT è quello di implementare un LoadTestPlugin.
Attraverso un plugin, infatti, tra le altre cose, si riescono ad intercettare gli eventi di un load test e ad iniettare codice da eseguire all’inizio e alla fine del load test, prima e dopo ogni unit test, etc..

Così, armato di buona volontà mi metto a scrivere il mio bel plugin. Mi serve per diversi motivi ma soprattutto perché per ogni unit test devo fare un consistente setup e non posso permettermi che il tempo speso durante tale setup venga incluso nelle statistiche finali (il tempo impiegato negli eventi del LoadTest non viene incluso nel tempo dei singoli unit tests). 

Nella fase di setup, devo anche chiamare un servizio WCF (è necessario per rendere il test relativo il più realistico possibile e per minimizzare quelli che falliscono), solo che scopro che un LoadTest viene eseguito o come parte di vstesthost.exe (se si usa VS) o come parte di qtagent.ext (se si usa un agent/controller). Questo vuol dire che tutta la mia configurazione WCF (che avevo nell’apposito app.config) non viene caricata.

Potrei farne a meno e impostarmi tutto da codice, ma sinceramente preferirei evitarlo, visto che si tratta di più di 30 servizi, vari behaviors, credentials, 3 bindings diversi, configurazione di un SecurityTokenService, etc

Cercando un po’ in giro, trovo alcune (non) soluzioni, tra cui:

  • fare il deployment del file di configurazione attraverso localtestrun.runconfiguration e caricarlo manualmente
  • copiare la parte di configurazione che mi interessa in uno dei file di configurazione che vengono automaticamente caricati (vstesthost.exe.config/qtagent.exe.config o machine.config)

Ho scartato la seconda soluzione per ovvi motivi :)

La prima andrebbe bene se dovessi lavorare con settings generici, ma nel mio caso si tratta di impostazioni WCF e vorrei poter semplicemente scrivere:

   1: MyWCFClient client = new MyWCFClient();
   2: client.Foo();

Quindi quello che mi serve è poter istanziare il mio WCF client dicendogli dove andare a prendersi tutta la configurazione. La soluzione è quella di crearsi un custom client channel ereditando da ChannelFactory<T>. Come al solito c’è qualcuno che l’ha già fatto!

Copiato il codice di Cibrax, fatte alcune minime modifiche e adesso ho il mio plugin che:

  1. in ILoadTestPlugin.Initialize prepara l’ambiente di test (si potrebbe usare anche LoadTest.LoadTestStarting, ma non c’è garanzia che venga eseguito su ogni agent)
  2. in LoadTest.TestSelected verifica che esistano tutti i prerequisiti per eseguire il test selezionato – se così non è viene modificato il test da eseguire, scegliendo un test vuoto di default (sempre per rendere le statistiche finali il più verosimili possibili) – basta settare e.TestName.
  3. in LoadTest.TestStarting, prepara i dati necessari al test selezionato (collegandosi ai servizi wcf) e glieli passa attraverso TestStartingEventArgs.TestContextProperties; prepara dati per la fase di tear down e li salva in TestStartingEventArgs.UserContext.
  4. in LoadTest.TestFinished, recupera i dati necessari dallo UserContext (vedi sopra) ed esegue il tear down per il test selezionato.

Funziona che è una meraviglia.