Skip to main content

Hooks và Dependency Injection trong Specflow

Mình là dev bên .NET, thỉnh thoảng thấy cái gì hay hay trên mạng thì mình học ké. Mình thấy Specflow khá thú vị, nhưng mình thắc mắc là có thể sử dụng DI trong Selenium. Và hôm nay, mình vô tình thấy bài hướng dẫn về Hooks trên trang automatetheplanet. Đọc sơ về Hooks, mình nghĩ ngay tới việc sử dụng 1 thư viện khá nổi tiếng là Autofac. Nhưng do có sự khác biệt về web application và automation testing nên mình nghĩ BoDi được tích hợp trong Specflow sẽ thích hợp hơn. Vậy Hooks là gì? Việc sử dụng BoDi có phức tạp không?

Hooks là gì?

Hooks (event binding) có thể được sử dụng để thực hiện logic tự động hóa bổ sung trên các sự kiện cụ thể, ví dụ như trước khi thực hiện một scenario. Hooks được sử dụng global nhưng có thể bị hạn chế chỉ chạy cho các feature hoặc scenario với một tag cụ thể. Thứ tự thực hiện của hooks cho cùng một sự kiện là không xác định.
Các sự kiện trong Hooks:
  1. BeforeTestRun
  2. BeforeFeature
  3. BeforeScenario
  4. BeforeScenarioBlock
  5. BeforeStep
  6. AfterStep
  7. AfterScenarioBlock
  8. AfterScenario
  9. AfterFeature
  10. AfterTestRun

Ví dụ

Đầu tiên, bạn cần tải chương trình mẫu ở: Làm quen với SpecFlow+
Hooks cho phép bạn gọi hàm trước hoặc sau scenario.
Thêm mới 1 file hook:
Add => New Item…
Specflow => Special Hooks (event bindings)
Add a new Hooks

Một file hook mới được tạo với mã giả như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TechTalk.SpecFlow;
namespace SpecFlowTutorial
{
    [Binding]
    public sealed class ExampleHooks
    {
        // For additional details on SpecFlow hooks see http://go.specflow.org/doc-hooks
        [BeforeScenario]
        public void BeforeScenario()
        {
            //TODO: implement logic that has to run before executing each scenario
        }
        [AfterScenario]
        public void AfterScenario()
        {
            //TODO: implement logic that has to run after executing each scenario
        }
    }
}
Bạn thêm vào 2 dòng Console để kiểm tra xem event có được gọi trước khi chạy scenario không.
[BeforeScenario]
public void BeforeScenario()
{
 Trace.WriteLine("Before Scenario");
}

[AfterScenario]
public void AfterScenario()
{
 Trace.WriteLine("After Scenario");
}
Kết quả

BoDi là gì?

BoDi là 1 IoC container đơn giản, dễ dàng thêm vào source code. Do BoDi được tích hợp vào Specflow nên bạn dễ dàng sử dụng Dependency Injection để đơn giản hóa việc khởi tạo các đối tượng.

Sử dụng

Đầu tiên bạn xem code bên dưới:
public sealed class ExampleHooks
{
 // For additional details on SpecFlow hooks see http://go.specflow.org/doc-hooks
 private readonly IObjectContainer _objectContainer;
 public ExampleHooks(IObjectContainer objectContainer)
 {
  _objectContainer = objectContainer;
 }

 [BeforeScenario]
 public void BeforeScenario()
 {
  Trace.WriteLine("Before Scenario");
  _objectContainer.RegisterInstanceAs<Calculator>(new Calculator());
 }

 [AfterScenario]
 public void AfterScenario()
 {
  Trace.WriteLine("After Scenario");
 }
}
Ở file CalculatorSteps, bạn thay đổi như sau:
[Binding]
public class CalculatorSteps
{
 private readonly Calculator _calculator;
 public CalculatorSteps(Calculator calculator)
 {
  _calculator = calculator;
 }
 private int result;

 [Given(@"I have entered (.*) into the calculator")]
 public void GivenIHaveEnteredIntoTheCalculator(int number)
 {
  _calculator.FirstNumber = number;            
 }

 [Given(@"I have also entered (.*) into the calculator")]
 public void GivenIHaveAlsoEnteredIntoTheCalculator(int number)
 {
  _calculator.SecondNumber = number;
 }

 [When(@"I press add")]
 public void WhenIPressAdd()
 {
  result = _calculator.Add();
 }
 
 [Then(@"the result should be (.*) on the screen")]
 public void ThenTheResultShouldBeOnTheScreen(int expectedResult)
 {
  Assert.AreEqual(expectedResult, result);
 }
}
Đối tượng được inject vào hàm constructor và không bị thay đổi ở các method bên dưới.

Tham khảo


Hi vọng với bài viết này, các bạn sẽ giảm bớt lượng code lặp lại trong project.
Nhatkyhoctap's blog

Comments

Popular posts from this blog

Lập trình đa luồng với Task

Bài viết được đăng trên Jou Lập trình
Trong phiên bản .NET framework 4.0, Microsoft đã bổ sung nhiều thư viện hỗ trợ việc xử lý đa luồng (multi-threading), nhằm đơn giản hóa việc lập trình lẫn hiệu suất của chương trình. Trong bài viết này, tôi xin hướng dẫn các bạn sử dụng lớp System.Threading.Task.

Tìm hiểu về IdentityServer 4

Trong bài viết này, mình sẽ hướng dẫn các bạn làm quen với thư viện Identity Server 4, và tích hợp các service In-Memory của Identity Server 4 vào Project Web API trong .NET Core.

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize
Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh.
Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.