AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Massentests mit DUnitX

Ein Thema von manumeter44 · begonnen am 19. Mär 2021 · letzter Beitrag vom 20. Mär 2021
Antwort Antwort
manumeter44

Registriert seit: 19. Mär 2021
1 Beiträge
 
#1

Massentests mit DUnitX

  Alt 19. Mär 2021, 07:55
Schönen guten Tag zusammen,
ich bin gerade dabei mich in DUnitX einzuarbeiten und frage mich, ob es in diesem Test-Framework von Delphi möglich ist Massentests ohne ewig langen Code hinzubekommen.

Beispiel:
Ich habe eine Funktion vorliegen welche einfach nur 2 Werte, die als Eingangsparameter mitgegeben werden addieren soll:
function TCalc.Add(x, y: Real): Real;
begin
Result := x + y;
end;

Und diese Funktion soll nun nicht mit "nur" 2 [TestCase] auf ihre Richtigkeit hin überprüft werden sondern mehrere Male.Ich stelle mir das etwa so vor:
[Test]
[TestCase('Add Test','0,0,0')]
[TestCase('Add Test','0,1,1')]
[TestCase('Add Test','0,2,2')]
[TestCase('Add Test','0,3,3')]
[TestCase('Add Test','0,4,4')]
.
.
.
.
.
[TestCase('Add Test','10,10,20')]
procedure TestAdd(Value1, Value2, Expected: Real);

Die Frage, die sich mir nun stellt ist: Wie ist es möglich (wie oben drüber dargestellt) so viele Testfälle darzustellen ohne diese explizit einzeln zu definieren? Kann man TestCases irgendwie durchloopen oder eine andere Möglichkeit sich bei "Massentests" im Code kurz zu halten?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.152 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 06:10
Wie wäre es mit...


Delphi-Quellcode:
begin
  for I:=0 to 1000 do
    begin
      if Add(A,B) <> C then
        begin
          Assert.Fail;
          exit;
        end;
   end;
   Assert.Pass;
end;
Und A und B kannst Du dann entsprechen vorgeben, errechnen.. was auch immer
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.600 Beiträge
 
Delphi 12 Athens
 
#3

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 09:55
Der Nachteil bei dem Ansatz mit der for-Schleife ist, dass der Test beim ersten Fehler abbricht und Fehler in höheren Schleifendurchgängen erst entdeckt werden, wenn der Fehler behoben wurde. Aus diesem Grund wurden ja überhaupt dieses TestCase-Attribut erfunden.

Man kann das aber auch mit einem TestDataProvider lösen (hier zur Übersicht alles in einer Unit):
Delphi-Quellcode:
unit TestUnit1;

interface

uses
  DUnitX.Types, DUnitX.InternalDataProvider, DUnitX.TestDataProvider, DUnitX.TestFramework;

type
  TCalcSourceProvider = class(TTestDataProvider)
  private
    FMaxTest: Integer;
  public
    constructor Create; override;
    function GetCaseCount(const methodName: string): Integer; override;
    function GetCaseName(const methodName: string): string; override;
    function GetCaseParams(const methodName: string; const caseNumber: Integer): TValueArray; override;
  end;

type
  [TestFixture]
  TCalcTestObject = class
  public
    [Test]
    [TestCaseProvider(TCalcSourceProvider)] // alternativ auch: [TestCaseProvider('CalcSourceProvider')] (siehe initialization)
    procedure TestAdd(Value1, Value2, Expected: Double);
  end;

implementation

constructor TCalcSourceProvider.Create;
begin
  inherited;
  FMaxTest := 11*11;
end;

function TCalcSourceProvider.GetCaseCount(const methodName: string): Integer;
begin
  Result := FMaxTest;
end;

function TCalcSourceProvider.GetCaseName(const methodName: string): string;
begin
  Result := methodName;
end;

function TCalcSourceProvider.GetCaseParams(const methodName: string; const caseNumber: Integer): TValueArray;
var
  A: Double;
  B: Double;
begin
  A := caseNumber div 11;
  B := caseNumber mod 11;
  Result := TValueArray.Create(A, B, A + B);
end;

procedure TCalcTestObject.TestAdd(Value1, Value2, Expected: Double);
begin
  { Hier testen wir erstmal, ob unser Dataprovider überhaupt funktioniert. Wenn das klappt, ersetzen wir das mit dem Test der TCalc-Methode Add }
  Assert.AreEqual(Expected, Value1 + Value2, 0.1);
end;

initialization
  TestDataProviderManager.RegisterProvider('CalcSourceProvider', TCalcSourceProvider);
  TDUnitX.RegisterTestFixture(TCalcTestObject);
end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.211 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 11:53
Der Nachteil bei dem Ansatz mit der for-Schleife ist, dass der Test beim ersten Fehler abbricht und Fehler in höheren Schleifendurchgängen erst entdeckt werden, wenn der Fehler behoben wurde. Aus diesem Grund wurden ja überhaupt dieses TestCase-Attribut erfunden.
Wenn man solche Tests hat, sollte die SW-(Version/Hotfix/Release) erst freigegeben werden wenn keine der Tests fehl schlagen.
D.h. dieser Schleifen-Ansatz hätte für die Veröffentliche SW-Version keinen Nachteil.

Und diese Schleifenansatz hat den Vorteil das man eine großen Menge an Fällen testen kann. Das alles in tausenden Zeilen Attribute zu schreiben kostet nur zeit das zu schreiben.
Der Attribut-Weg ist ja Fälle gedacht, in denen ich spezielle Werte testen will, aber nicht eine ganzen größeren Block.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.159 Beiträge
 
Delphi 12 Athens
 
#5

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 12:18
Die Frage ist doch auch woher die Testdaten dann eigentlich kommen.
Eine vorgegebene Tabelle, empirische Daten, per Zufall, oder gibt es sogar eine Formel ?

Ich bin prinzipiell etwas gegen vorgegebene Tabellen, denn damit ist meist die Idee des Testers verbunden, und seltene Fälle werden nie erkannt.
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.152 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 14:42
Uwe's Ansatz mit dem Provider finde ich richtig gut (+1) - kannte ich noch nicht - aber "meine" Schleife reicht mir in der Regel..
Wenn ein Unittest fehl schlägt, dann fixe ich diesen... Wenn mir Testinsight anzeigt das 1000 fehlgeschlagen sind, hilft mir das nicht weiter,
sondern frustriert eher. I.d.R. fixed man doch einen Fehler nach dem anderen.

Wobei ich keinen Sinn darin sehe 1+1 1+2 1+3 1+4 und so weiter zu testen...
Das ist ein Computer, wenn er 1+1 rechnen kann, kann er auch 1+n rechnen. Es geht doch dann eher um die Corner-Cases... 1+0 1+-1 1+65568 1+0.5 oder was auch immer...

Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.600 Beiträge
 
Delphi 12 Athens
 
#7

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 15:38
Und diese Schleifenansatz hat den Vorteil das man eine großen Menge an Fällen testen kann. Das alles in tausenden Zeilen Attribute zu schreiben kostet nur zeit das zu schreiben.
Eben dafür gibt es ja auch den TestDataProvider.

Im übrigen ist der Ansatz, die Testdaten von extern zu bekommen gar nicht mal so abwegig, das nennt sich dann zum Beispiel "data driven testing" - da kann man tolle Sachen mit machen
In der Tat! Ich benutze das z.B. für die Parser-Tests bei MMX. Die Testdaten sind ja in der Regel Code-Schnipsel oder ganze Units. Mit einem TestDataProvider, der einfach die Dateien in einem Verzeichnis auflistet, brauche ich nur eine neue Datei in das entsprechende Verzeichnis zu legen und schon laufen alle Tests auch mit dem neuen Code-Schnipsel - ohne dass ich das Testprojekt überhaupt neu compilieren muss. Das ist ganz praktisch, wenn man als Folder das Source-Verzeichnis von Delphi angibt. Da kommen schon mal ein paar Dateien zusammen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.211 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 16:18
Und diese Schleifenansatz hat den Vorteil das man eine großen Menge an Fällen testen kann. Das alles in tausenden Zeilen Attribute zu schreiben kostet nur zeit das zu schreiben.
Eben dafür gibt es ja auch den TestDataProvider.
Kannte ich nicht. Muss ich mir mal anschauen

Sind noch bei uns drüber auch die restlichen DUnit-Tests durch DUnitX-Tests zu ersetzen.
Mit Kopplung an Jenkins gibt da wenigstens eine gute Auswertung. Und mittlweile gibts die passende Unit auch direkt im git-Repository (DUnitX.Loggers.XML.JUnit.pas)
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.159 Beiträge
 
Delphi 12 Athens
 
#9

AW: Massentests mit DUnitX

  Alt 20. Mär 2021, 16:28
Mit einem TestDataProvider, der einfach die Dateien in einem Verzeichnis auflistet, brauche ich nur eine neue Datei in das entsprechende Verzeichnis zu legen und schon laufen alle Tests auch mit dem neuen Code-Schnipsel
Ja, das Filesystem ist eine gute Lösung für solche Dinge.
Man kann sich andere Arten von TestDaten auch z.B. über eine Datenbank hereinladen.
Die hätte den Vorteil "remote" konfigurierbar und erweiterbar zu sein.

So ein TestDataProvider macht viel Sinn, und nicht nur für Massentests.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:49 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 by Thomas Breitkreuz