2012-08-31 11 views
7

Przede wszystkim jestem nowy w SpecFlow.SpecFlow: ClassInitialize and TestContext

Mam plik funkcji, który mam/chcę zautomatyzować używając MSTest do uruchomienia jako test funkcjonalny z w pełni skonfigurowanym serwerem, dostępem do danych ... W tym celu muszę skonfigurować serwer z danymi w bloki "Given" SpecFlow i uruchom je później. Muszę również skopiować niektóre pliki do katalogu wyjściowego testu.

W testach funkcjonalnych innych niż SpecFlow użyłem atrybutu ClassInitialize do pobrania TestDeploymentDir z TestContext; coś takiego:

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

Teraz SpecFlow nie mogę używać tego atrybutu, ponieważ jest już używany przez samego SpecFlow. Niektóre nowe atrybuty istnieją, np. BeforeFeature, który działa podobnie, ale nie przekazuje TestContext jako parametru.

Po prostu potrzebuję uzyskać dostęp do TestDeploymentDir TestContext w celu skopiowania niektórych plików, zanim naprawdę przetestuję mój serwer testów funkcjonalnych - łatwo wykonalne bez SpecFlow, ale prawie niemożliwe z SpecFlow.

Jak radzić sobie z tym problemem?

Czy to w ogóle możliwe?

Wielkie dzięki za porady!

Robert


Środowisko:

  • Visual Studio 2012
  • SpecFlow 1.9.0.77
+0

Można wygenerować MSTest testy ze swoimi fiels fabularnych z specflow: http: //stackoverflow.com/questions/2984318/how-to-run-specflow-tests-in-visual-studio-2010 – nemesv

+2

Dzięki za odpowiedź. Generuję już testy MSTest z moich plików funkcji, ale jak wspomniano powyżej, nie mam dostępu do TestContext. –

+3

Może plik [AssemblyInitialize] (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.assemblyinitializeattribute (v = vs.80) .aspx) może działać w twoim scenariuszu, specflow don Z niego skorzystaj. W przeciwnym razie przy obecnych plikach funkcji generowanych 'MsTestGeneratorProvider' nie można uzyskać sprawdzonego' TestContext'. Jednakże możesz czerpać z 'MsTestGeneratorProvider' i generować testy, które przechowują' TestContext' gdzieś wewnątrz specflow. – nemesv

Odpowiedz

-1

Jest FeatureContext jak również powszechnie stosowane ScenariuszCont ext. Różnica oczywiście polega na tym, że FeatureContext istnieje podczas wykonywania pełnej funkcji, podczas gdy kontekst scenariusza istnieje tylko podczas scenariusza.

Na przykład:

Dodaj do kontekstu:

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

otrzymujemy:

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

Możesz przeczytać więcej na ten temat here.

+0

Dzień dobry, widziałem to i byłoby dobrze, gdybym mógł tam umieścić moją własność TestContext. Jak byłoby to możliwe? To dla mnie problem blokujący! Wielkie dzięki za porady, robert –

3

Aby uzyskać dostęp do wartości w tekście testowym, należy utworzyć klasę cząstkową dla każdego pliku scenariusza, do którego dodajesz.

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; 
     } 
    } 
} 

Następnie można uzyskać dostęp do katalogu wdrażania kroków od korzystania

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

Jeśli masz zbyt wiele scenariuszy, to prawdopodobnie ma zautomatyzować tworzenie takich plików z T4.

+0

Jeśli używasz tej techniki, po uaktualnieniu do SpecFlow 2.2.1, musisz trochę zmienić. Zajrzyj tutaj: https://github.com/techtalk/SpecFlow/issues/936 –

3

Można utworzyć wtyczkę i dostosować implementację IUnitTestGeneratorProvider. Poniższe informacje powinny dodać wiersz do inicjowania klasy MSTest.

// 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) 
     { 
     } 
    } 

} 

i odniesienie go w pliku app.config:

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

Następnym razem ponownie zapisać .feature plików wygenerowany kod w ClassInitialize należy ustawić TargetDataDeploymentDirectory.

Musiałem zrobić coś podobnego. Oto mój działający kod https://github.com/marksl/Specflow-MsTest i wpis na blogu http://codealoc.wordpress.com/2013/09/30/bdding-with-specflow/

0

Ponieważ specyfikacja SpecFlow 2.2.1 jest dostępna w trybie Kontekstowy wtrysk. (https://github.com/techtalk/SpecFlow/pull/882)

Można go pobrać z pojemnika bezpośrednio:

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

lub poprzez iniekcję kontekstowego:

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 
    } 
} 
Powiązane problemy