[Specflow] TRUNCATE Table Test Data by Tag

Effectively reconstruct test program that lets TDD or write a test program to enhance productivity several times.

This article describes the time when specflow integration or acceptance tests performed in the feature file through labeling tag, you can begin before the scenario, and after the end of the feature, clear test data related to table to ensure repeatable automated test execution correct.

SpecFlow - Cucumber for .NET


In fact, often with the Entity Framework and other ORM framework through specflow to initialize the data plane integration testing, clearing data validation and query data. Examples are as follows:

Feature content of the document

Feature: BookService


Scenario: Add the first book 
	Given a book for registering
	| ISBN          | Name  |
	| 9789869094481 | specification by example |	
	When Create
	Then Book table should exist a record
	| ISBN          | Name                     |
	| 9789869094481 | specification by example |	

Step Definitions Content

    [Binding]
    public class BookServiceSteps
    {
        private BookService _bookService;

        [BeforeScenario()]
        public void BeforeScenario()
        {
            this._bookService = new BookService();
        }

        [Given(@"a book for registering")]
        public void GivenABookForRegistering(Table table)
        {
            var bookViewModel = table.CreateInstance
  
  
   
   ();
            ScenarioContext.Current.Set
   
   
    
    (bookViewModel);
        }

        [When(@"Create")]
        public void WhenCreate()
        {
            var bookViewModel = ScenarioContext.Current.Get
    
    
     
     ();
            this._bookService.Create(bookViewModel);
        }

        [Then(@"Book table should exist a record")]
        public void ThenBookTableShouldExistARecord(Table table)
        {
            using (var dbcontext = new NorthwindEntitiesForTest())
            {
                var book = dbcontext.Books.FirstOrDefault();
                Assert.IsNotNull(book);

                table.CompareToInstance(book);
            }
        }
    }
    
    
   
   
  
  

Production Code Content

    internal class BookViewModel
    {
        public string ISBN { get; set; }
        public string Name { get; set; }
    }

    internal class BookService
    {
        public void Create(BookViewModel bookViewModel)
        {
            var book = new Book { ISBN = bookViewModel.ISBN, Name = bookViewModel.Name };

            //production and testing project shouldn't use the same connection string
            //it is just for sample code
            using (var dbcontext = new NorthwindEntitiesForTest())
            {
                dbcontext.Books.Add(book);
                dbcontext.SaveChanges();
            }
        }
    }

The first test results by testing

The second test, the test fails, duplicate key

Second test fails, the test as described in the report, as an ISBN PKey, not repeated. This is a problem in the integration testing is often encounter, so we need this kind before and after the test case execution, clearing Book data table.

Clean up the test data using Entity Framework

In the BeforeScenario added Truncatecommand procedure is as follows:

        [BeforeScenario()]
        public void BeforeScenario()
        {
            this._bookService = new BookService();
            using (var dbcontext = new NorthwindEntitiesForTest())
            {
                dbcontext.Database.ExecuteSqlCommand("TRUNCATE TABLE [Books]");

                dbcontext.SaveChangesAsync();
            }
        }

In this way we can ensure, before each test case is executed, the Booksdata in the table cleared.

But the practice will encounter two problems:

  1. On the BeforeScenarioinside,Scenario will be executed no cleaning unnecessary data TRUNCATE command, cost performance
  2. To clean up the test data in a different table, you can not be flexible reuse of this program.
For these two problems, we can through Use tag tag to a particular scenario which table to clean up To resolve.

Tag use to bind logic to be implemented

First, first CleanTable()extracted from the step definitions in a common place Hooks.csin.

[Binding]
public sealed class Hooks
{
    [BeforeScenario()]
    public void CleanTable()
    {
        using (var dbcontext = new NorthwindEntitiesForTest())
        {
            dbcontext.Database.ExecuteSqlCommand("TRUNCATE TABLE [Books]");

            dbcontext.SaveChangesAsync();
        }
    }
}

The original step definitions do not need to write any cleaning table commands.

        [BeforeScenario()]
        public void BeforeScenario()
        {
            this._bookService = new BookService();            
        }

Next, we hope to determine through a tag marked with the tag name, the first clear test this scenario what data tables, the Hooks of CleanTable()processing it.

    [BeforeScenario()]
    public void CleanTable()
    {
        var tags = ScenarioContext.Current.ScenarioInfo.Tags
            .Where(x => x.StartsWith("Clean"))
            .Select(x => x.Replace("Clean", ""));

        if (!tags.Any())
        {
            return;
        }

        using (var dbcontext = new NorthwindEntitiesForTest())
        {
            foreach (var tag in tags)
            {
                dbcontext.Database.ExecuteSqlCommand($"TRUNCATE TABLE [{tag}]");
            }

            dbcontext.SaveChangesAsync();
        }
    }
Use ScenarioContext.Current.ScenarioInfo.Tags after obtaining all the tag, selected at the beginning of the tag Clean and parse table name, execute truncate the command.

Next, only tag on tag scenario, for example, @CleanBookscan be cleared before scenario execution table [Books] data.

Similarly when necessary to set the web UI testing browser, it can also be treated in the same manner, for example:

        [BeforeFeature()]
        [Scope(Tag = "web")]
        public static void SetBrowser()
        {
            SeleniumWebDriver.Bootstrap(
               SeleniumWebDriver.Browser.Chrome
           );
        }

As long as the flag @webwill be set for the browser Chrome, of course, you may be set through a plurality of different types of browser tag.

in conclusion

Like the ASP.NET MVC ActionFilteras Hook through the tag do in addition to what appears to be a background job to be processed at a glance, but also allows common procedures independent maintenance, re-use the feature.

Common applications, as well asSome features require log in first in order to use the, Except in the Background feature is labeled, but also can be handled through the tag.

Development process, please refer to github repository: CleanTableByTag

Perhaps you would be interested in the following training courses:

  1. 2019/7/27 (six) ~ 2019/7/28 (day): Evolution of design: Test-driven development and continuous refactoring sixth echelon (Chinese Taipei)
  2. 2019/8/16 (e) ~ 2019/8/18 (day): [C # Advanced Design - Design learn from the reconstructed high ease of use and high flexibility API] second echelon (Chinese Taipei)
  3. 2019/9/21 (six) ~ 2019/9/22 (day): Clean Coder: DI and AOP advanced combat second echelon (Chinese Taipei)
  4. 2019/10/19 (f): [Art added unit tests for legacy code] seventh echelon (Chinese Taipei)
  5. 2019/10/20 (day): [development] Speed ​​eighth echelon (Chinese Taipei)

Would like to receive first-hand information public training courses, or would like to inquire about house training, consulting, coaching, consulting services, please contact Facebook fan page: 91 agile development of the road.

Original: Large column  [Specflow] TRUNCATE Table Test Data by Tag


Guess you like

Origin www.cnblogs.com/chinatrump/p/11496117.html