2012-08-31 12 views
7

prima di tutto sono nuovo in SpecFlow.SpecFlow: ClassInitialize e TestContext

Ho un file di funzionalità che ho/desidera automatizzare utilizzando MSTest per l'esecuzione come test funzionale che coinvolge un server completamente configurato, accesso ai dati ... Per questo scopo devo configurare il server con i dati in i blocchi "Dati" dello SpecFlow e avviarlo in seguito. Devo anche copiare alcuni file nella directory di output del test.

Nei test funzionali non SpecFlow stavo utilizzando l'attributo ClassInitialize per ottenere TestDeploymentDir da TestContext; qualcosa di simile:

[ClassInitialize] 
public static void ClassSetup(TestContext context) 
{ 
    TargetDataDeploymentRoot = context.TestDeploymentDir; 
} 

Ora con SpecFlow non posso utilizzare questo attributo più come esso viene utilizzato da SpecFlow sé. Esistono alcuni nuovi attributi, come BeforeFeature che agisce in modo simile, ma non passa il TestContext come parametro.

Ho solo bisogno di accedere al TestDeploymentDir di TestContext per copiare alcuni file lì prima di riavviare veramente il mio server di test funzionale - facilmente eseguibile senza SpecFlow ma quasi impossibile con SpecFlow.

Come gestire questo problema?

È possibile a tutti?

Grazie mille per un consiglio!

Robert


Ambiente:

  • Visual Studio 2012
  • SpecFlow 1.9.0.77
+0

è possibile generare test MSTest dei tuoi caratteristica fiels con specflow: http: //stackoverflow.com/questions/2984318/how-to-run-specflow-tests-in-visual-studio-2010 – nemesv

+2

Grazie per la risposta. Sto già generando test MSTest dai miei file di funzionalità, ma come accennato in precedenza, non ho accesso a TestContext. –

+3

Forse il [AssemblyInitialize] (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.assemblyinitializeattribute (v = vs.80) .aspx) può funzionare per il tuo scenario, specflow don non usarlo Altrimenti con i file di funzione generati 'MsTestGeneratorProvider' non è possibile ottenere il' TestContext' provato. Tuttavia è possibile derivare da 'MsTestGeneratorProvider' e generare test che memorizzano' TestContext' da qualche parte all'interno di specflow. – nemesv

risposta

-1

C'è un FeatureContext così come il più comunemente usato ScenarioCont ext. La differenza ovviamente è che FeatureContext esiste durante l'esecuzione della funzione completa mentre lo ScenarioContext esiste solo durante uno scenario.

Ad esempio:

Aggiungi al contesto:

ScenarioContext.Current.Add("ObjectName", myObject); 

Get:

var myObject = ScenarioContext.Current.Get<object>("ObjectName"); 

Si può leggere di più su di esso here.

+0

Buongiorno, l'ho visto e andrebbe bene se potessi avere la proprietà del mio TestContext. Come sarebbe possibile? Questo è un problema di blocco per me! Grazie mille per il consiglio, robert –

3

Per poter accedere ai valori nel TestContext è necessario creare una classe parziale per ogni file di scenario in cui si aggiunge il file.

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using TechTalk.SpecFlow; 

/// <summary> 
/// Partial class for TestContext support. 
/// </summary> 
public partial class DistributionFeature 
{ 
    /// <summary> 
    /// Test execution context. 
    /// </summary> 
    private TestContext testContext; 

    /// <summary> 
    /// Gets or sets test execution context. 
    /// </summary> 
    public TestContext TestContext 
    { 
     get 
     { 
      return this.testContext; 
     } 

     set 
     { 
      this.testContext = value; 

      //see https://github.com/techtalk/SpecFlow/issues/96 
      this.TestInitialize(); 
      FeatureContext.Current["TestContext"] = value; 
     } 
    } 
} 

Poi si potrebbe accedere alla directory di distribuzione dai tuoi passi utilizzando

var testContext = (TestContext)FeatureContext.Current["TestContext"]; 
var deploymentDir = testContext.TestDeploymentDir; 

Se si dispone di troppi scenari, allora si ha probabilmente per automatizzare la creazione di tali file con T4.

+0

Se stai usando questa tecnica, quando esegui l'aggiornamento a SpecFlow 2.2.1, devi modificare leggermente le cose. Dai un'occhiata qui: https://github.com/techtalk/SpecFlow/issues/936 –

3

È possibile creare un plugin e personalizzare l'implementazione dell'IUnitTestGeneratorProvider. Quanto segue dovrebbe aggiungere la linea alla classe MSTest di inizializzazione.

// It's very important this is named Generator.SpecflowPlugin. 
namespace MyGenerator.Generator.SpecflowPlugin 
{ 
    public class MyGeneratorProvider : MsTest2010GeneratorProvider 
    { 
     public MyGeneratorProvider(CodeDomHelper codeDomHelper) 
      : base(codeDomHelper) 
     { 
     } 

     public override void SetTestClassInitializeMethod(TestClassGenerationContext generationContext) 
     { 

      base.SetTestClassInitializeMethod(generationContext); 

generationContext.TestClassInitializeMethod.Statements.Add(new CodeSnippetStatement(
                     @"TargetDataDeploymentRoot = context.TestDeploymentDir;")); 

     } 

    } 


[assembly: GeneratorPlugin(typeof(MyGeneratorPlugin))] 

    public class MyGeneratorPlugin : IGeneratorPlugin 
    { 
     public void RegisterDependencies(ObjectContainer container) 
     { 
     } 

     public void RegisterCustomizations(ObjectContainer container, SpecFlowProjectConfiguration generatorConfiguration) 
     { 
      container.RegisterTypeAs<MyGeneratorProvider, IUnitTestGeneratorProvider>(); 
     } 

     public void RegisterConfigurationDefaults(SpecFlowProjectConfiguration specFlowConfiguration) 
     { 
     } 
    } 

} 

e di riferimento nel file App.config:

<specFlow> 
    <plugins> 
     <add name="MyGenerator" type="Generator"/> 
    </plugins> 
</specFlow> 

La prossima volta che ri-salvare il file .Feature il codice generato in ClassInitialize dovrebbe impostare il TargetDataDeploymentDirectory.

Ho dovuto fare qualcosa di simile. Ecco il mio codice di lavoro https://github.com/marksl/Specflow-MsTest e post di blog http://codealoc.wordpress.com/2013/09/30/bdding-with-specflow/

0

Da SpecFlow 2.2.1 il TestContext è disponibile tramite Context Injection. (https://github.com/techtalk/SpecFlow/pull/882)

È possibile ottenere dal contenitore direttamente:

ScenarioContext.Current.ScenarioContainer.Resolve<Microsoft.VisualStudio.TestTools.UnitTesting.TestContext>()

o tramite iniezione contesto:

public class MyStepDefs 
{ 
    private readonly TestContext _testContext; 
    public MyStepDefs(TestContext testContext) // use it as ctor parameter 
    { 
     _testContext = testContext; 
    } 

    [BeforeScenario()] 
    public void BeforeScenario() 
    { 
     //now you can access the TestContext 
    } 
} 
Problemi correlati