Chuyển đến nội dung chính

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

Nhận xét

Bài đăng phổ biến từ blog này

[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.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.