簡體   English   中英

我可以將一個集合傳遞給DUnitX中的測試用例嗎?

[英]Can I pass a set to a test case in DUnitX?

我正在嘗試在運行測試后檢查對象的狀態。 該狀態包含在一組中。 是否可以使用DUnitX屬性將預期狀態傳遞給測試用例,以便我可以對所有不同的輸入使用相同的測試?

我試圖將集合作為常量或集合傳遞,但在我的測試例程中,它總是以空集的形式到達。

  • 這有可能使用屬性嗎?
  • 你如何測試集合是否相同?

示例代碼:

type
  TResult = (resOK,resWarn,resError);
  TResultSet = set of TResult;

const
  cErrWarn : TResultSet = [resWarn];

type
  [TestFixture]
  TMyTest = class(TBaseTest)
    [Test]
    [TestCase('Demo1','InputA,[resWarn]')] // <-- tried as a set
    [TestCase('Demo2','InputB,cErrWarn')]  // <-- tried as a constant

    procedure Test(Input:string; ExpectedResult: TResultSet);
  end;

procedure TMyTest.Test(Input:string; ExpectedResult: TResultSet);
begin
  // ExpectedResult is always the empty set []
  RunTests(MyObject(Input));
  Assert.AreEqual(ExpectedResult, MyObject.ResultSet);
end;

我還試圖將Expected結果定義為數組,但是DUnitX甚至不再調用測試。 可能那只是“太多”

    procedure Test(Input:string; ExpectedResult: array of TResult);

到目前為止我能想出的最好的方法是使用以下方法。 獲取最多三個樣本(在此處插入您喜歡的整數...)預期狀態並單獨檢查這些狀態。 這並不是我所希望的,但它確實可以解決問題。

    procedure Test(Input:string; R1,R2,R3: TResult);

非常感謝幫助。 :)

您正在使用TestCaseAttribute指定要傳遞給測試方法的參數。 但是,它根本不支持將集合作為參數傳遞。 通過查看DUnitX.Utils單元中聲明的常量Conversions ,您可以看到這是如此。 它將任何轉換映射到ConvFail的集合。

因此,如果要使用屬性指定此數據,則需要擴展測試框架。 您可以從CustomTestCaseSourceAttribute派生自己的后代,並重寫GetCaseInfoArray來解碼您的set參數。 作為一個粗略的例子,你可以使用這個:

type
  MyTestCaseAttribute = class(CustomTestCaseSourceAttribute)
  private
    FCaseInfo: TestCaseInfoArray;
  protected
    function GetCaseInfoArray: TestCaseInfoArray; override;
  public
    constructor Create(const ACaseName: string; const AInput: string; const AExpectedResult: TResultSet);
  end;

constructor MyTestCaseAttribute.Create(const ACaseName, AInput: string; const AExpectedResult: TResultSet);
begin
  inherited Create;
  SetLength(FCaseInfo, 1);
  FCaseInfo[0].Name := ACaseName;
  SetLength(FCaseInfo[0].Values, 2);
  FCaseInfo[0].Values[0] := TValue.From<string>(AInput);
  FCaseInfo[0].Values[1] := TValue.From<TResultSet>(AExpectedResult);
end;

function MyTestCaseAttribute.GetCaseInfoArray: TestCaseInfoArray;
begin
  Result := FCaseInfo;
end;

然后,您可以將以下屬性添加到測試方法中:

[MyTestCase('Demo2', 'InputB', [resWarn])]
procedure Test(Input: string; ExpectedResult: TResultSet);

為了簡單起見,我在這里避免使用RTTI,但使用RTTI可以為您提供更大的靈活性。 您將參數作為字符串傳遞,並使用RTTI對其進行解碼,就像DUnitX中的代碼一樣。 這意味着每次要使用set參數時都不需要編寫定制屬性。

更好的方法是在DUnitX中通過將Conversions地圖擴展到封面集來實現它,並將其作為補丁提交。 我相信別人會發現它很有用。

將此轉換函數添加到DUnitX.Utils並將其放入tkUString to tkSet的Conversions矩陣中(由於StringToSetTValue限制,這僅適用於最多32個元素的集合,對於最多256個元素的較大集合,需要更多代碼雖然):

function ConvStr2Set(const ASource: TValue; ATarget: PTypeInfo; out AResult: TValue): Boolean;
begin
  TValue.Make(StringToSet(ATarget, ASource.AsString), ATarget, AResult);
  Result := True;
end;

您還需要為參數使用不同的分隔符char,否則它將錯誤地拆分:

[TestCase('Demo1','InputA;[resWarn,resError]', ';')]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM