2012-03-30 15 views
12

Sto usando Approval Tests. Sulla mia macchina dev Sono contento DiffReporter che inizia TortoiseDiff quando i miei risultati dei test variano da approvato:Come utilizzare ApprovalTests su Teamcity?

[UseReporter(typeof (DiffReporter))] 
    public class MyApprovalTests 
    { ... } 

Tuttavia, quando gli stessi test sono in esecuzione su TeamCity ed i risultati sono diversi test che non con il seguente errore:

System.Exception : Unable to launch: tortoisemerge.exe with arguments ... 
Error Message: The system cannot find the file specified 
---- System.ComponentModel.Win32Exception : The system cannot find the file 
                   specified 

Ovviamente non è possibile trovare tortoisemerge.exe e va bene perché non è installato su build agent. Ma cosa succede se viene installato? Quindi, per ogni errore, verrà avviata un'altra istanza di tortoisemerge.exe e nessuno la chiuderà. Alla fine tonnellate di istanze di tortoisemerge.exe uccideranno i nostri server :)

Quindi la domanda è: come devono essere decorati i test per eseguire Tortoise Diff sulla macchina locale e solo segnalare errori sul server di build? Sono a conoscenza di #IF DEBUG [UseReporter(typeof (DiffReporter))] ma preferirei un'altra soluzione, se possibile.

+0

Puoi farci sapere quale versione di ApprovalTests che si sta utilizzando? La versione –

+0

è 1.0.4381.19674 –

+1

Ok. Ero curioso perché in 1.17 DiffReporter è stato rinforzato per provare alcuni reporter diversi prima di arrendersi e chiamare Assert, o QuietReporter. Quindi, nell'ultima versione non dovresti vedere quell'eccezione, anche se questo non risponde alla tua domanda su cosa succederebbe se qualcuno installasse TortiseSVN. Posso dirti che su CC.NET, non succede nulla ... TortiseMerge non si avvia sul server. –

risposta

9

Ci sono un paio di soluzioni alla domanda di Reporters e CI. Li elenco tutti, quindi indicare una soluzione migliore, che è non ancora abilitata allo.

  1. Utilizzare AppConfigReporter. Ciò consente di impostare il reporter in AppConfig e utilizzare QuietReporter per CI. C'è un video qui, insieme a molti altri reporter. AppConfigReporter appare alle 6:00. Questo ha il vantaggio di configurazioni separate, e puoi decorare a livello di assembly, ma ha lo svantaggio di scavalcare a livello di classe/metodo, hai ancora il problema.

  2. Crea i tuoi (2) giornalisti. Vale la pena notare che se si usa un reporter, verrà chiamato, indipendentemente dal fatto che funzioni nell'ambiente.IEnvironmentAwareReporter consente ai reporter composti, ma non impedisce una chiamata diretta al reporter. Molto probabilmente avrai bisogno di 2 reporter, uno che non fa nulla (come un reporter silenzioso) ma funziona solo sul tuo server CI o quando chiamato da TeamCity. Chiameremo il TeamCity Reporter. E uno, che è un multiprotettore che chiama teamCity se sta funzionando, altrimenti si rimanda a.

  3. Utilizzare un FrontLoadedReporter (non ancora pronto). Questo è il modo in cui attualmente ApprovalTests utilizza NCrunch. Fa il metodo sopra davanti a qualsiasi cosa viene caricata nell'attributo UseReporter. Ho intenzione di aggiungere un attributo di livello assembly per la configurazione di questo, ma non ho ancora (mi dispiace) cercherò di aggiungerlo molto presto.

Spero che questo aiuti. Llewellyn

+0

Grazie, sembra che ho ottenuto il punto –

+0

In approvazioni 1,8 ora è possibile aggiungere [assembly: FrontLoadedReporter (typeof (NCrunchReporter))] Questo è solo consentito a livello di assembly e deve essere un IEnvironmentAwareReporter. Se il giornalista è autorizzato nell'ambiente corrente, eluderà tutti gli altri reporter. Questo è molto utile per Build Systems in cui si desidera sovrascrivere il comportamento dei reporter. Non c'è ancora un TeamCityReporter, ma se vuoi, sarei felice di accoppiarti con te per crearne uno. (Non usare TeamCity me stesso ...) –

2

Ho appena avuto una piccola idea.

È possibile implementare il proprio giornalista, chiamiamolo DebugReporter

public class DebugReporter<T> : IEnvironmentAwareReporter where T : IApprovalFailureReporter, new() 
{ 
    private readonly T _reporter; 

    public static readonly DebugReporter<T> INSTANCE = new DebugReporter<T>(); 

    public DebugReporter() 
    { 
     _reporter = new T(); 
    } 

    public void Report(string approved, string received) 
    { 
     if (IsWorkingInThisEnvironment()) 
     { 
      _reporter.Report(approved, received); 
     } 
    } 

    public bool IsWorkingInThisEnvironment() 
    { 
#if DEBUG 
     return true; 
#else 
     return false; 
#endif 
    } 
} 

Esempio di utilizzo,

[UseReporter(typeof(DebugReporter<FileLauncherReporter>))] 
public class SomeTests 
{ 
    [Test] 
    public void test() 
    { 
     Approvals.Verify("Hello"); 
    } 
} 

Se il test è in caduta, ancora sarebbe rosso - ma giornalista non si avvicinò .

Il IEnvironmentAwareReporter è appositamente definito per quello, ma sfortunatamente qualunque cosa io torni lì, chiama comunque il metodo Report(). Quindi, inserisco la chiamata IsWorkingInThisEnvironment() all'interno, che è un po 'hacker, ma funziona :)

Spero che Llywelyn possa spiegare perché si comporta così. (bug?)

+0

Sembra che IsWorkingInThisEnvironment() sia usato dai reporter compositi come 'FirstWorkingReporter' e non sia necessariamente chiamato ogni volta che il reporter viene richiamato direttamente come hai fatto nell'esempio. –

1

Sto usando CC.NET e ho TortoiseSVN installato sul server.

Ho riconfigurato il mio build server per consentire al servizio CC.NET di interagire con il desktop. Quando l'ho fatto, è stato lanciato TortiseMerge. Quindi penso che quello che sta succedendo è che Approvals proverà a lanciare lo strumento, ma non può perché CC.NET è in esecuzione come un servizio e il sistema operativo impedisce questo comportamento di default. Se TeamCity funziona come un servizio, dovresti stare bene, ma potresti voler testare.

+0

Ho aggiornato all'ultima versione di ApprovalTests e ora tenta di eseguire 'XUnitReporter' quando l'avvio della tartaruga fallisce. Purtroppo sembra avere un bug che Llewellyn si spera risolvere presto :) –

4

Recentemente mi sono imbattuto in questo problema.

Prendendo in prestito da xunit e il modo in cui gestiscono la registrazione di TeamCity, mi sono inventato un TeamCity Reporter basato su NCrunch Reporter.

public class TeamCityReporter : IEnvironmentAwareReporter, IApprovalFailureReporter 
{ 
    public static readonly TeamCityReporter INSTANCE = new TeamCityReporter(); 

    public void Report(string approved, string received) { } 

    public bool IsWorkingInThisEnvironment(string forFile) 
    { 
     return Environment.GetEnvironmentVariable("TEAMCITY_PROJECT_NAME") != null; 
    } 
} 

E così ho potuto combinare con il reporter NCrunch:

public class TeamCityOrNCrunchReporter : FirstWorkingReporter 
{ 
    public static readonly TeamCityOrNCrunchReporter INSTANCE = 
     new TeamCityOrNCrunchReporter(); 

    public TeamCityOrNCrunchReporter() 
     : base(NCrunchReporter.INSTANCE, 
     TeamCityReporter.INSTANCE) { } 
} 

[assembly: FrontLoadedReporter(typeof(TeamCityOrNCrunchReporter))] 
+0

Love this! aggiungendolo a ApprovalTests (v.21) adesso. –

+1

@llewellynfalco Si noti che ho riscontrato problemi durante l'esecuzione dei test in modalità di rilascio poiché il CLR stava integrando il metodo di test in modo che non apparisse nello stacktrace e quindi i test di approvazione non sono riusciti a trovarlo. Ho dovuto aggiungere '[MethodImpl (MethodImplOptions.NoInlining)]' al metodo di test prima che funzionasse. Questo era in xUnit. Qualcosa di cui essere a conoscenza. –