logo
  • Buy
  • Download
  • Documentation
  • Blog
  • Contact

Blog

19 Dec 2013

DelphiSpec Library Announce

by Roman Yankovsky Leave a comment

Martin Fowler:

That said, I do think that the greatest potential benefit of DSLs comes when business people participate directly in the writing of the DSL code. The sweet spot, however is in making DSLs business-readable rather than business-writeable. If business people are able to look at the DSL code and understand it, then we can build a deep and rich communication channel between software development and the underlying domain.

In this post I’d like to announce DelphiSpec library. It was inspired by Cucumber. Actually, this library is the implementation of Gherkin language in Delphi. This implementation is not complete (consider it as an alpha version). Some features haven’t been implemented yet, but this project is still in development.

In a few words, the essence of the project is that DelphiSpec allows to turn the scenario into the appropriate unit test for DUnit:

Feature: Calculator

Scenario: Add two numbers
  Given I have entered 50 in calculator
    And I have entered 70 in calculator
  When I press Add
  Then the result should be 120 on the screen

Scenario: Add two numbers (fails)
  Given I have entered 50 in calculator
    And I have entered 50 in calculator
  When I press Add
  Then the result should be 120 on the screen

Scenario: Multiply three numbers
  Given I have entered 5 in calculator
    And I have entered 5 in calculator
    And I have entered 4 in calculator
  WHEN I press mul
  Then the result should be 100 on the screen

I’ll underline that these are not tests but scenarios. In other words, this is the Behavior-Driven Development (BDD) in addition to the famous Test-Driven Development (TDD). Such scenarios serve as documentation, automated tests and development-aid – all rolled into one format. You should not describe internal system logic using scenarios: they should describe how user sees an application behavior.

Use of Gherkin is a good choice for DelphiSpec because it’s now considered as de-facto standard in the particular niche and if you took interest in it you can even buy a book with the best practices, tips on writing scenarios and examples in this language. Also there is lots of information on the Internet.

Let’s return to the example (the Calculator). The scenarios execution result in DUnit will look like:

How does this work? Gherkin is very small itself. Actually its only aim is to describe Given-When-Then formula. There are several keywords, all the rest could be customized.

We test a very simple class: a calculator. I will not post its code here, you can find it on github. The interesting thing is: how will the program understand and execute commands like “Given I have entered 50 in calculator”? Here comes the helper class which describes these steps (so-called “step definitions”). This is the helper class itself:

unit SampleCalculatorStepDefs;
 
interface
 
uses
  SampleCalculator, DelphiSpec.Attributes, DelphiSpec.StepDefinitions;
 
type
  [_Feature('calculator')]
  TSampleCalculatorSteps = class(TStepDefinitions)
  private
    FCalc: TCalculator;
  public
    procedure SetUp; override;
    procedure TearDown; override;
 
    [_Given('I have entered (.*) in calculator')]
    procedure EnterInt(Value: string);
 
    [_When('I press Add')]
    procedure AddInt;
 
    [_When('I press Mul')]
    procedure MulInt;
 
    [_Then('the result should be (.*) on the screen')]
    procedure TestResult(Value: string);
  end;
 
implementation
 
uses
  System.SysUtils, TestFramework, DelphiSpec.Core;
 
{ TSampleCalculatorSteps }
 
procedure TSampleCalculatorSteps.AddInt;
begin
  FCalc.Add;
end;
 
procedure TSampleCalculatorSteps.EnterInt(Value: string);
begin
  FCalc.Push(Value.ToInteger);
end;
 
procedure TSampleCalculatorSteps.MulInt;
begin
  FCalc.Mul;
end;
 
procedure TSampleCalculatorSteps.SetUp;
begin
  FCalc := TCalculator.Create;
end;
 
procedure TSampleCalculatorSteps.TearDown;
begin
  FCalc.Free;
end;
 
procedure TSampleCalculatorSteps.TestResult(Value: string);
begin
  if FCalc.Value <> Value.ToInteger then
    raise ETestFailure.Create('Incorrect result on calculator screen');
end;
 
initialization
  RegisterStepDefinitionsClass(TSampleCalculatorSteps);
 
end.

In fact, every step has a type (Given/When/Then) and the regular expression that describes the rest part of the step. Regular expressions help to extract the parameters which will be passed to the class methods to perform the relevant part of the scenario.

The only thing we need to do so that this system works is to add into project file (.dpr) the procedure call which receives the path to a folder which contains “.feature” files to process.

begin
  PrepareDelphiSpecs(TPath.Combine(ExtractFilePath(Application.ExeName), 'features'), True, 'EN');
  DUnitTestRunner.RunRegisteredTests;
end.

The last parameter (“EN”) allows us to specify a language in which we write the script. This is another interesting Gherkin possibility. Since, generally, there is no difference in what language the text is processed using regular expressions; it would be a good idea to translate a few keywords into different languages (using this XML).

So nothing prevents us from writting scenarios in any language:

Функционал: Калькулятор

Сценарий: Сложить два числа
  Допустим я ввожу 50 на калькуляторе
         И я ввожу 70 на калькуляторе
  Когда я нажимаю СЛОЖИТЬ
  Тогда результат на экране должен быть 120

These are the very first steps, but I’m planning to implement full Gherkin functionality.

P.S. There are some comments in G+: https://plus.google.com/u/0/+RomanYankovsky/posts/2S789T49dX8


Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Announcements
  • DelphiAST
  • DelphiSpec
  • FixInsight
  • FMX
  • Other
  • VCL

Recent Posts

  • Find leaks in Delphi with Deleaker
  • FixInsight and the inline directive
  • FixInsight 2017.04 support Delphi 10.2 Tokyo
  • FixInsight 2016.04 support Delphi 10.1 Berlin
  • FixInsight vs FMX in Delphi 10.1 Berlin

Archives

  • January 2020
  • April 2017
  • April 2016
  • March 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • August 2015
  • April 2015
  • March 2015
  • February 2015
  • September 2014
  • August 2014
  • January 2014
  • December 2013
  • October 2013

Recent Comments

  • anapa-poseidon3.ru on FixInsight vs RTL
  • Heat pump on FixInsight vs RTL
  • Suing on FixInsight vs RTL
  • JorgeJag on Find leaks in Delphi with Deleaker
  • Prorabdom on FixInsight vs RTL
  • Home
  • Buy
  • Download
  • Documentation
  • Blog
  • Contact
  • © 2014-2015 SourceOddity|
  • Terms and Conditions|
  • Privacy Policy