![]() |
Dsharp unit testing , AV nicht verstanden
ich möchte unit testing mit Unterstützung des D# Frameworks durchführen. mein erstes sample sieht wie folgt aus
Delphi-Quellcode:
unit Unit_TCustomtestCase; interface uses TestFramework, Types, Generics.Collections, Classes, SysUtils, DSharp.Testing.DUnit; type TCustomParams = class StartFolder: String; StartValue: Integer; StartParam: Real; end; type TCustomtestCase = class(TTestCase) private FtestParam: TCustomParams; protected procedure SetUp; override; procedure TearDown; override; published [TestCase('''c:\temp'',1 ,3.1415')] [TestCase('''d:\temp'',1 ,3.1415')] [TestCase('''e:\temp'',1 ,3.1415')] [TestCase('''f:\temp'',1 ,3.1415')] procedure InittestParams(StartFolder: String; StartValue: Integer; StartParam: Real); end; implementation { TCustomtestCase } procedure TCustomtestCase.InittestParams(StartFolder: String; StartValue: Integer; StartParam: Real); begin FtestParam.StartFolder := StartFolder; FtestParam.StartValue := StartValue; FtestParam.StartParam := StartParam; checkEquals(FtestParam.StartParam, StartValue); end; procedure TCustomtestCase.SetUp; begin inherited; FtestParam := TCustomParams.Create; end; procedure TCustomtestCase.TearDown; begin inherited; FtestParam.Free; end; initialization RegisterTest(TCustomtestCase.Suite); end. Wenn ich das Schlüsselwort Zitat:
Verwende ich Zitat:
Was mache ich denn falsch? |
AW: Dsharp unit testing , AV nicht verstanden
Wäre es nicht sinnvoller, gleich mit DUnitX zu testen.
|
AW: Dsharp unit testing , AV nicht verstanden
|
AW: Dsharp unit testing , AV nicht verstanden
Zitat:
Zitat:
Getestet habe ich sowohl mit den Ständen aus master und feature/spring4d-compatibility und auf XE und XE5. Welche Version von DSharp benutzt du auf welcher Delphi Version? Und wo genau kommt die AV? Nachtrag: Ich bekomm zwar keine AV aber ich seh, wo das Problem ist (und die Tests sollten ja eigentlich rot sein ^^). Erstens müssen die Argumente durch ein Semikolon getrennt werden und der String muss nicht doppelt gequotet werden. Dann gibt es derzeit noch die kleine Niggeligkeit, dass das Float umwandeln von den locale Settings auf deinem System abhängig ist. Ich musste für korrekte Werte das also so schreiben:
Delphi-Quellcode:
Für einen Punkt als Dezimaltrenner muss DSharp.Core.Reflection.ConvStr2Float entsprechend angepasst werden.
[TestCase('c:\temp;1;3,1415')]
[TestCase('d:\temp;1;3,1415')] [TestCase('e:\temp;1;3,1415')] [TestCase('f:\temp;1;3,1415')] Du kannst dir aber auch eine eigene Attribut Klasse für deinen Test bauen (leider unterstützt Delphi keine open arrays in Attributen, daher der zugegebenermaßen hässliche Workaround mit nem String - den macht DUnitX übrigens auch nicht anders), die sähe dann so aus:
Delphi-Quellcode:
Dann kannst du über deinen Test schreiben:
type
CustomParamsTestCaseAttribute = class(TestCaseAttribute) public constructor Create(StartFolder: String; StartValue: Integer; StartParam: Real); end; constructor CustomParamsTestCaseAttribute.Create(StartFolder: String; StartValue: Integer; StartParam: Real); begin SetLength(FValues, 3); FValues[0] := StartFolder; FValues[1] := StartValue; FValues[2] := StartParam; end;
Delphi-Quellcode:
[CustomParamsTestCase('c:\temp', 1, 3.1415)]
[CustomParamsTestCase('d:\temp', 1, 3.1415)] [CustomParamsTestCase('e:\temp', 1, 3.1415)] [CustomParamsTestCase('f:\temp', 1, 3.1415)] |
AW: Dsharp unit testing , AV nicht verstanden
@Stevie
Da wollte ich gerade diese Beschränkungen zur Sprache bringen, da nimmst du mir doch alles aus dem Mund :D Trotz dieser Niggeligkeiten ein cooles Feature :thumb: |
AW: Dsharp unit testing , AV nicht verstanden
Ich nutze für die DSharp TestCase Attribute einen kleinen generator den ich irgendwann mal des nächtens geschrieben habe.
Bitte nicht über die Codequalität streiten, er leistet mir gute Dienste. :wink: Benötigt wird außerdem Spring4D weil ich dessen IList verwende. Zur Benutzung: Variable von TTestAttributeGenerator erzeugen, "Name" ist der Name für das generierte Attribut und die IList<TPair<string,string>> sind die Argumente für das Attribut. TPair<string,string> ist dabei Name und Typ als String. Beispiel:
Delphi-Quellcode:
Und das generiert dann diesen Code:
procedure Test;
var args: IList<TPair<string,string>>; generator: TTestAttributeGenerator; begin args := TCollections.CreateList<TPair<string,string>>; args.Add(TPair<string,string>.Create('StartFolder', 'string')); args.Add(TPair<string,string>.Create('StartValue', 'Integer')); args.Add(TPair<string,string>.Create('StartParam', 'Real')); generator := TTestAttributeGenerator.Create('CustomParamsTestCase', args); Clipboard.AsText := 'type' + sLineBreak + generator.GetIntf() + sLineBreak + sLineBreak + generator.GetImpl(); end;
Delphi-Quellcode:
Und hier der Source Code:
type
CustomParamsTestCaseAttribute = class(TestCaseAttribute) public constructor Create(StartFolder: string; StartValue: Integer; StartParam: Real); end; { CustomParamsTestCaseAttribute } constructor CustomParamsTestCaseAttribute.Create(StartFolder: string; StartValue: Integer; StartParam: Real); begin SetLength(FValues, 3); FValues[0] := TValue.From<string>(StartFolder); FValues[1] := TValue.From<Integer>(StartValue); FValues[2] := TValue.From<Real>(StartParam); end;
Delphi-Quellcode:
unit uTestAttributeGenerator;
interface uses SysUtils, Generics.Collections, Spring.Collections; type TTestAttributeGenerator = record private fName: string; fArgs: IList<TPair<string,string>>; fIntf: string; fImpl: string; procedure EnsureGenerated; public constructor Create(const Name: string; const Args: IList<TPair<string,string>>); function GetIntf: string; function GetImpl: string; end; implementation uses StrUtils; const AttributeName = '$(Name)'; AttributeArg = '$(Arg)'; ArgCount = '$(ArgCount)'; ArgIndex = '$(ArgIndex)'; ArgName = '$(ArgName)'; ArgType = '$(ArgType)'; ArgAssign = '$(ArgAssign)'; ResolvedAttributeArg = ArgName + ': ' + ArgType; ResolvedAttributeArgMultiple = ResolvedAttributeArg + '; ' + AttributeArg; ResolvedArgAssign = 'FValues[' + ArgIndex + '] := TValue.From<' + ArgType + '>(' + ArgName + ');'; ResolvedArgAssignMutli = ResolvedArgAssign + sLineBreak + ' ' + ArgAssign; AttributeTemplateIntf = ' ' + AttributeName + 'Attribute = class(TestCaseAttribute)' + sLineBreak + ' public' + sLineBreak + ' constructor Create(' + AttributeArg + ');' + sLineBreak + ' end;'; AttributeTemplateImpl = '{ ' + AttributeName + 'Attribute }' + sLineBreak + '' + sLineBreak + 'constructor ' + AttributeName + 'Attribute.Create(' + AttributeArg + ');' + sLineBreak + 'begin' + sLineBreak + ' SetLength(FValues, ' + ArgCount + ');' + sLineBreak + ' ' + ArgAssign + sLineBreak + 'end;'; { TTestAttributeGenerator } constructor TTestAttributeGenerator.Create(const Name: string; const Args: IList<TPair<string,string>>); begin if Name = '' then raise EArgumentException.Create('Argument [Name] can''t be empty'); if not Assigned(Args) then raise EArgumentNilException.Create('Argument [Args] has to be assigned'); if Args.Count = 0 then raise EArgumentException.Create('Argument [Args] can''t be empty'); fName := Name; fArgs := Args; fIntf := AttributeTemplateIntf; fImpl := AttributeTemplateImpl; end; function TTestAttributeGenerator.GetIntf: string; begin EnsureGenerated(); Result := fIntf; end; function TTestAttributeGenerator.GetImpl: string; begin EnsureGenerated(); Result := fImpl; end; procedure TTestAttributeGenerator.EnsureGenerated; var i: Integer; s: string; begin if not Assigned(fArgs) then Exit; // replace AttributeName fIntf := StringReplace(fIntf, AttributeName, fName, [rfReplaceAll]); fImpl := StringReplace(fImpl, AttributeName, fName, [rfReplaceAll]); // replace Argument count fIntf := StringReplace(fIntf, ArgCount, IntToStr(fArgs.Count), [rfReplaceAll]); fImpl := StringReplace(fImpl, ArgCount, IntToStr(fArgs.Count), [rfReplaceAll]); for i := 0 to Pred(fArgs.Count) do begin // replace Arg s := IfThen(i = Pred(fArgs.Count), ResolvedAttributeArg, ResolvedAttributeArgMultiple); fIntf := StringReplace(fIntf, AttributeArg, s, [rfReplaceAll]); fImpl := StringReplace(fImpl, AttributeArg, s, [rfReplaceAll]); // replace Assign s := IfThen(i = Pred(fArgs.Count), ResolvedArgAssign, ResolvedArgAssignMutli); fIntf := StringReplace(fIntf, ArgAssign, s, [rfReplaceAll]); fImpl := StringReplace(fImpl, ArgAssign, s, [rfReplaceAll]); // replace Argument Name fIntf := StringReplace(fIntf, ArgName, fArgs[i].Key, [rfReplaceAll]); fImpl := StringReplace(fImpl, ArgName, fArgs[i].Key, [rfReplaceAll]); // replace Argument Type fIntf := StringReplace(fIntf, ArgType, fArgs[i].Value, [rfReplaceAll]); fImpl := StringReplace(fImpl, ArgType, fArgs[i].Value, [rfReplaceAll]); // replace Argument Index fIntf := StringReplace(fIntf, ArgIndex, IntToStr(i), [rfReplaceAll]); fImpl := StringReplace(fImpl, ArgIndex, IntToStr(i), [rfReplaceAll]); end; fArgs := nil; end; end. |
AW: Dsharp unit testing , AV nicht verstanden
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für die schnelle Hilfe , ich habe mich für den einfachsten Weg entschieden
Wir haben im Team alles WIn 7 mit Lang=german Punkt oder Komma sollte kein Thema für uns werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:20 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