2012-08-31 18 views
7

trước hết tôi mới sử dụng SpecFlow.SpecFlow: ClassInitialize và TestContext

Tôi có tệp tính năng mà tôi có/muốn tự động hóa bằng MSTest để chạy thử nghiệm chức năng liên quan đến máy chủ được thiết lập đầy đủ, truy cập dữ liệu ... Vì mục đích này, tôi phải định cấu hình máy chủ với dữ liệu trong các khối 'Given' của SpecFlow và bắt đầu nó sau đó. Tôi cũng phải sao chép một số tệp vào thư mục đầu ra của bài kiểm tra.

Trong các bài kiểm tra chức năng phi SpecFlow, tôi đã sử dụng thuộc tính ClassInitialize để lấy TestDeploymentDir từ TestContext; một cái gì đó như thế này:

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

Bây giờ với SpecFlow tôi không thể sử dụng thuộc tính này nữa vì nó được sử dụng bởi chính SpecFlow. Một số thuộc tính mới tồn tại, chẳng hạn như BeforeFeature hoạt động tương tự NHƯNG nó không truyền trên TestContext dưới dạng tham số.

Tôi chỉ cần truy cập vào TestDeploymentDir của TestContext để sao chép một số tệp ở đó trước khi thực sự phát tán máy chủ thử nghiệm chức năng của mình - dễ dàng thực hiện mà không có SpecFlow nhưng gần như không thể với SpecFlow.

Làm cách nào để giải quyết vấn đề này?

Có thể nào không?

Cảm ơn rất nhiều lời khuyên!

robert


Môi trường:

  • Visual Studio 2012
  • SpecFlow 1.9.0.77
+0

Bạn có thể tạo các bài kiểm tra MSTest từ FIELS tính năng của bạn với specflow: http: //stackoverflow.com/questions/2984318/how-to-run-specflow-tests-in-visual-studio-2010 – nemesv

+2

Cảm ơn bạn đã trả lời. Tôi đã tạo ra các thử nghiệm MSTest từ các tệp tính năng của mình, nhưng như đã đề cập ở trên, tôi không có quyền truy cập vào TestContext. –

+3

Có thể [AssemblyInitialize] (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.assemblyinitializeattribute (v = vs.80) .aspx) có thể hoạt động cho kịch bản của bạn, specflow don không sử dụng nó. Nếu không với các tập tin tính năng hiện tại 'MsTestGeneratorProvider' bạn không thể có được' TestContext' được minh chứng. Tuy nhiên, bạn có thể lấy được từ 'MsTestGeneratorProvider' và tạo ra các xét nghiệm lưu trữ' TestContext' ở đâu đó bên trong specflow. – nemesv

Trả lời

-1

Có một FeatureContext cũng như thường được sử dụng Kịch bản ext. Sự khác biệt của khóa học là FeatureContext tồn tại trong khi thực thi tính năng hoàn chỉnh trong khi ScenarioContext chỉ tồn tại trong một kịch bản.

Ví dụ:

Thêm vào bối cảnh:

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

Nhận:

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

Bạn có thể đọc thêm về nó here.

+0

Chào buổi sáng, tôi đã thấy điều đó và sẽ ổn nếu tôi có thể sở hữu tài sản của TestContext ở đó. Làm thế nào điều này có thể được? Đó là một vấn đề chặn đối với tôi! Cảm ơn rất nhiều lời khuyên, robert –

3

Để có quyền truy cập vào các giá trị trong TestContext, bạn phải tạo một phần lớp cho mỗi tệp kịch bản mà bạn có trong đó bạn thêm.

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

Sau đó, bạn có thể truy cập vào thư mục triển khai từ bước của bạn sử dụng

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

Nếu bạn có quá nhiều kịch bản, sau đó bạn có thể có để tự động tạo ra các tập tin như vậy với T4.

+0

Nếu bạn đang sử dụng kỹ thuật này, khi bạn nâng cấp lên SpecFlow 2.2.1, bạn cần phải sửa đổi một chút. Có một cái nhìn ở đây: https://github.com/techtalk/SpecFlow/issues/936 –

3

Bạn có thể tạo Plugin và tùy chỉnh triển khai IUnitTestGeneratorProvider. Sau đây nên thêm dòng vào lớp khởi tạo của 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) 
     { 
     } 
    } 

} 

Và tham khảo nó trong file App.config:

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

Lần sau bạn lưu lại các tập tin .feature mã được tạo trong ClassInitialize nên thiết lập các TargetDataDeploymentDirectory.

Tôi phải làm điều tương tự. Dưới đây là mã làm việc của tôi https://github.com/marksl/Specflow-MsTest và bài đăng trên blog http://codealoc.wordpress.com/2013/09/30/bdding-with-specflow/

0

Vì SpecFlow 2.2.1 TestContext có sẵn qua Context Injection. (https://github.com/techtalk/SpecFlow/pull/882)

Bạn có thể lấy nó từ container trực tiếp:

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

hoặc thông qua tiêm bối cảnh:

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