![]() |
DUnit - Vorgehensweise
Hallo,
ich habe folgenden Testcase:
Delphi-Quellcode:
Im Testschritt TestAddBuffer füge ich dem fInBuffer einen Buffer hinzu.
TestTInBuffer = class(TTestCase)
strict private FInBuffer: TInBuffer; public procedure SetUp; override; procedure TearDown; override; published procedure TestIsEmpty; procedure TestAddBuffer; procedure TestGetBuffer; procedure TestBufferUpperLimit; procedure TestBufferLowerLimit; end;
Delphi-Quellcode:
Im Testschritt TestGetBuffer will ich den Buffer wieder auslesen.
procedure TestTInBuffer.TestAddBuffer;
var buffer: TBuffer; begin buffer := TBuffer.Create; fInBuffer.add(buffer); checkEquals(false,fInBuffer.isEmpty); end;
Delphi-Quellcode:
Wenn fInBuffer keinen Buffer enthält - gibt fInBuffer nil als Ergenis zurück.
procedure TestTInBuffer.TestGetBuffer;
var buffer: TBuffer; begin buffer := fInBuffer.get; checkEquals(true, assigned(buffer)); buffer.Free; end; Der Testschritt schlägt fehl. Ändere ich den Testschritt so ab:
Delphi-Quellcode:
Dann schägt der Testschritt nicht mehr fehl.
procedure TestTInBuffer.TestGetBuffer;
var buffer: TBuffer; buffer1: TBuffer; begin buffer1 := TBuffer.create; fInBuffer.add(buffer1); buffer := fInBuffer.get; checkEquals(true, assigned(buffer)); buffer.Free; end; Frage: Warum ist das so? Bleiben Änderungen der Test-Klasse (hier fInBuffer) zwischen den einzelnen Testschritten nicht erhalten? Grüße Klaus |
AW: DUnit - Vorgehensweise
Für jeden Testschritt wird eine neue TestCase-Instanz erstellt.
Und das ist auch gut so, denn was du niemals machen solltest, einen Test-Schritt von einem anderen Test-Schritt abhängig machen. Wenn dem so sein sollte, dann musst du das auch so schreiben
Delphi-Quellcode:
procedure TestTInBuffer.TestGetBuffer;
var buffer: TBuffer; begin TestAddBuffer; buffer := fInBuffer.get; checkEquals(true, assigned(buffer)); buffer.Free; end; |
AW: DUnit - Vorgehensweise
.. danke - das Wissen hat mir gefehlt.
Grüße Klaus |
AW: DUnit - Vorgehensweise
Ich weiß, dass es sich in der Praxis kaum vermeiden lässt, die Funktionalität einer Methode mit dem Aufruf einer anderen abzuprüfen.
Dennoch sollte man die Interaktion in einem Unittest auf ein Mindestmaß reduzieren. Im schlimmsten Fall haste nämlich sonst Bugs in 2 Methoden die sich gegenseitig aufheben und deine Tests sind prima grün, aber nix funktioniert. |
AW: DUnit - Vorgehensweise
Dass man eine Methode mit der anderen testet, ist manchmal sogar notwendig und gewollt. Man muß nur sicher stellen, dass die testende Methode auch getestet ist.
|
AW: DUnit - Vorgehensweise
Die Reihenfolge der Testausführung darf keine Rolle spielen. Wenn du die Add- und Remove-Funktionalität testen willst, dann würde ich den Code duplizieren (in diesem sehr einfachen Fall). Das verstößt zwar gegen DRY, aber im Sinne der Schritte im Test (Arrange-Act-Assert) haben die Arrangements in den beiden Tests nichts miteinander zu tun.
Der Test 'TestGetBuffer' hat sein eigenes 'Arrange'. Zufällig ist das heute identisch mit dem Arrange des 'TestAddBuffer', abe morgen willst du deinen 'TestAddBuffer' vielleicht anders gestalten. Was ich mir vorstellen kann, sind kleine Arrangement-Methoden, damit der Arrange-Code nicht zu offt dupliziert wird, so etwa:
Delphi-Quellcode:
Function TestTInBuffer.AddSampleToBuffer : TBuffer;
begin result := TBuffer.Create; fInBuffer.add(result); end; procedure TestTInBuffer.TestAddBuffer; begin AddSampleToBuffer; checkEquals(false,fInBuffer.isEmpty); end; procedure TestTInBuffer.TestGetBuffer; var buffer: TBuffer; begin AddSampleToBuffer; buffer := fInBuffer.get; checkEquals(true, assigned(buffer)); buffer.Free; end; |
AW: DUnit - Vorgehensweise
Man sollte sich auch von der Vorstellung lösen, dass es pro Klasse auch genau nur einen TestCase geben muss/darf.
Wenn alle Test-Methode den gleichen Ausgangs-Zustand haben müssen, dann wird dieser in der Methode
Delphi-Quellcode:
festgelegt. Gibt es jetzt Test-Methoden, die damit nichts anfangen können, dann ist das wohl ein anderer Fall, also gibt es einen neuen TestCase.
SetUp
Ein TestCase ist (oh Wunder) eine Klasse, mit allem was dazugehört. Die kann man auch ableiten. Da baut man sich z.B. eine Liste mit Test-Methoden auf und leitet von dieser Klasse ein paar weitere ab, weil man dort per
Delphi-Quellcode:
einfach die gleichen Prüfungen auf andere Ausgang-Zustände loslassen möchte. Das könnte ja der Fall sein, wenn ich mehrere Interface-Implementierungen testen möchte. Die Tests sind die gleichen nur die konkreten Implementierungen eben nicht.
SetUp
Delphi-Quellcode:
TTestIFoo = class( TTestCase )
private Foo : IFoo; published procedure TestFoosBar; // testet das Interface end; TTestIFoo_TSimpleFoo = class( TTestIFoo ) protected procedure SetUp; end; procedure TTestIFoo_TSimpleFoo.SetUp; begin Foo := TSimpleFoo.Create(); // erzeugt das Interface end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz