вторник, 17 марта 2015 г.

Testing of calculator №5. Testing through “new architecture”

Original in Russian: http://programmingmindstream.blogspot.com/2014/05/5.html

Table of contents

Hello, readership.
Alexander kindly provided me with a “platform” for understanding TDD.
What could be better than the insight into code writing through testing under the guidance of the experienced mentor… :)

A short preamble.
On February, 18 Vsevolod Leonov offered. to show Alexander how to make an application that was not intended for testing into a full-testable system.
A simple calculator was chosen as an example application:
The project was insufferably trivial, 4 buttons 3 Edit.

Alexander has written the introductory here. In short, his idea was covering the application with tests before changing the architecture.

First of all, we add tests (DUnit) to the application; the details are described here.
Next, Alexander “visits the form, assigns 2 values to Edit’s and checks the Plus button”.
Stage three would involve expanding the tests from one operation (Plus) to covering all the buttons. Alexander has defined an abstract class - TOperationTest.
A quite interesting discussion took place in the commentaries about abstract class defining; you will learn why and what for from the coming posts :)
In the fourth post Alexander has defined “business-logic” class -  TCalculator that has the functions to perform all operations of calculator.

And so, today we’ll discuss testing of our application’s logic.
After changing the architecture we can directly test the “logic of the application”. That is why the simplest way to do it is writing TCalculatorOperation class inherited from TTestCase and checking all operations. To tell the truth, I have also checked incorrectness of executing one of the operations. However, I believe if readers are interested, we’ll discuss it in the commentaries.
The code:

unit CalculatorOperationTest;
 
interface
 
uses
  TestFrameWork,
  Calculator
  ;
 
 type
  TCalculatorOperationTest = class(TTestCase)
   published
    procedure LogicTestDiv;
    procedure LogicTestMul;
    procedure LogicTestAdd;
    procedure LogicTestSub;
    procedure LogicTestSubError;
  end;//TCalculatorOperationTest
 
implementation
 
  uses
   SysUtils;
 
const
 cA = '5';
 cB = '10';
{ TCalculatorOperationTest }
 
procedure TCalculatorOperationTest.LogicTestDiv;
var
  x1, x2  : string;
  result : Single;
begin
  x1:= cA;
  x2:= cB;
  result := StrToFloat(TCalculator.Divide(x2, x1));
  CheckTrue(2 = result);
end;
 
procedure TCalculatorOperationTest.LogicTestSub;
var
  x1, x2  : string;
  result : Single;
begin
  x1:= cA;
  x2:= cB;
  result := StrToFloat(TCalculator.Sub(x2, x1));
  CheckTrue(5 = result);
 
end;
 
procedure TCalculatorOperationTest.LogicTestSubError;
var
  x1, x2  : string;
  result : Single;
begin
  x1:= cA;
  x2:= cB;
  result := StrToFloat(TCalculator.Sub(x2, x1));
  CheckFalse(7 = result);
end;
 
procedure TCalculatorOperationTest.LogicTestMul;
var
  x1, x2  : string;
  result : Single;
begin
  x1:= cA;
  x2:= cB;
  result := StrToFloat(TCalculator.Mul(x2, x1));
  CheckTrue(50 = result);
end;
 
procedure TCalculatorOperationTest.LogicTestAdd;
var
  x1, x2  : string;
  result : Single;
begin
  x1:= cA;
  x2:= cB;
  result := StrToFloat(TCalculator.Add(x2, x1));
  CheckTrue(15 = result);
end;
 
initialization
 TestFramework.RegisterTest(TCalculatorOperationTest.Suite);
end.

Thus, we have moved from “GUI testing” to “business-logic testing”.

Repository

Комментариев нет:

Отправить комментарий