2014-06-16 18 views
11

Utilizzando MSTest, avevo bisogno di ottenere il nome del test corrente all'interno del metodo [TestInitialize]. È possibile ottenere questo dalla proprietà TestContext.TestName.Informazioni su MSTest TestContext

Ho trovato una differenza inaspettata di comportamento tra uno statico TestContext passato al metodo [ClassInitialize] e uno che è dichiarato come proprietà pubblica (e viene impostato dal runner di test).

Si consideri il seguente codice:

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace TestContext.Tests 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     public TestContext TestContext { get; set; } 

     private static TestContext _testContext; 

     [ClassInitialize] 
     public static void SetupTests(TestContext testContext) 
     { 
      _testContext = testContext; 
     } 

     [TestInitialize] 
     public void SetupTest() 
     { 
      Console.WriteLine(
       "TextContext.TestName='{0}' static _testContext.TestName='{1}'", 
       TestContext.TestName, 
       _testContext.TestName); 
     } 

     [TestMethod] public void TestMethod1() { Assert.IsTrue(true); } 

     [TestMethod] public void TestMethod2() { Assert.IsTrue(true); } 

     [TestMethod] public void TestMethod3() { Assert.IsTrue(true); } 
    } 
} 

Questo fa sì che il seguente da emettere (copia-incollato da l'uscita di test ReSharper corridore in VS2013):

TextContext.TestName='TestMethod1' static _testContext.TestName='TestMethod1' 
TextContext.TestName='TestMethod2' static _testContext.TestName='TestMethod1' 
TextContext.TestName='TestMethod3' static _testContext.TestName='TestMethod1' 

precedenza avevo ipotizzato che il due istanze di TestContext sarebbero equivalenti, ma chiaramente non lo sono.

  • La proprietà public TestContext si comporta come mi aspetto
  • Il valore private static TestContext che viene passato al metodo [ClassInitialize] non lo fa. Dal momento che TestContext ha proprietà che si riferiscono alla prova attualmente in esecuzione, questa implementazione sembra fuorviante e rotto

C'è qualche scenario in cui si sarebbe effettivamente preferisce utilizzare la TestContext passato al metodo [ClassInitialize], o è meglio ignorato e mai Usato?

+0

Il corridore sta creando una nuova istanza TestContext prima di ogni test. Stai chiedendo perché è stato progettato in questo modo? –

+1

@mikez - A me il comportamento 'private TestContext statico 'sembra sbagliato. Questo è quello che sto chiedendo. –

+0

'_testContext' è un campo assegnato solo una volta, all'interno del metodo contrassegnato con l'attributo' [ClassInitialize] '. Perché ti aspetteresti che cambi tra una prova e l'altra? Come ha scritto @mike, ogni test riceve una nuova istanza di 'TestContext'. – Groo

risposta

8

Come [ClassInitialize] è chiamato solo all'inizio, il nome del test è 'TestMethod1`. Questo è obsoleto dopo la prima esecuzione di prova.

TestContext è impostato per ogni metodo e pertanto ha il nome del test corrente.

Sì, è un po 'sciocco.

+1

La mia aspettativa/speranza era che il test runner mantenga un riferimento al 'TextContext' che passa al metodo' [ClassInitialize] 'e mantiene i suoi valori aggiornati correttamente ... –

+2

@RichardEverett Sarebbe stato più pratico e più intuitivo.Meglio ancora, sarebbe stato passare il metodo 'Initialize()' solo ai dati statici. – BanksySan

2

Il metodo

[ClassInitialize] 
public static void SetupTests(TestContext testContext) { } 

è chiamato prima che la proprietà impostata TestContext è impostata. Quindi, se hai bisogno del contesto in SetupTests, il parametro è utile. utilizzare In caso contrario, la proprietà TestContext, che si trova prima di ogni

[TestInitialize] 
public void SetupTest() { }