You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让DUnitX的Setup过程接收测试参数,无需弃用Setup/TearDown?

单元测试Setup接收测试用例参数的优化方案

问题背景

我认为单元测试的最佳实践是将测试通用代码(如对象创建、初始化等)放在Setup过程中,现有测试类结构如下:

[TestFixture]
TMY_Testcases = class
private
  FTestConfigParameter: TParameter;
public
  [Setup]
  procedure Setup;
  [TearDown]
  procedure TearDown;

  [Test]
  [TestCase('CreateTrue', 'True')]
  [TestCase('CreateFalse', 'False')]
  procedure Test_DoMyTest (Createflag : Boolean);
end; 

我的测试对象有多组参数,且对象创建逻辑在Setup过程中。想让Setup运行时能接收这些测试用例参数,但目前的临时方案会导致Setup和TearDown被弃用:

[Setup]
procedure Setup;
[TearDown]
procedure TearDown;

procedure MySetup(MyParameter : TParameter);

[TestCase('CreateWithParameter', 'False,Parameter_AsString')]
procedure Test_DoMyTest (Createflag : Boolean, Parameter : TParameter);

优化方案

方案1:拆分通用与参数化初始化逻辑

保留Setup/TearDown处理通用无依赖的初始化/清理,在测试方法内处理参数解析和参数相关的初始化:

[TestFixture]
TMY_Testcases = class
private
  FTestConfigParameter: TParameter;
  // 通用无参数依赖的初始化
  procedure CommonSetup;
  // 依赖参数的初始化逻辑
  procedure ParameterizedSetup(const AParameter: TParameter);
public
  [Setup]
  procedure Setup;
  [TearDown]
  procedure TearDown;

  [Test]
  [TestCase('CreateWithParam1', 'True,ParamValue1')]
  [TestCase('CreateWithParam2', 'False,ParamValue2')]
  procedure Test_DoMyTest(CreateFlag: Boolean; ParamAsString: string);
end;

procedure TMY_Testcases.Setup;
begin
  // 所有测试用例共享的初始化工作,比如基础环境配置、通用对象创建
  CommonSetup;
end;

procedure TMY_Testcases.CommonSetup;
begin
  // 这里放置不依赖测试参数的通用逻辑
end;

procedure TMY_Testcases.ParameterizedSetup(const AParameter: TParameter);
begin
  FTestConfigParameter := AParameter;
  // 基于参数的对象创建、初始化逻辑
end;

procedure TMY_Testcases.Test_DoMyTest(CreateFlag: Boolean; ParamAsString: string);
var
  Param: TParameter;
begin
  // 将TestCase传递的字符串参数转换为TParameter类型
  Param := TParameter.Create(ParamAsString);
  try
    // 执行参数化初始化
    ParameterizedSetup(Param);
    // 核心测试逻辑
    // ...
  finally
    Param.Free;
  end;
end;

procedure TMY_Testcases.TearDown;
begin
  // 通用清理工作,比如释放通用资源、恢复环境
  FTestConfigParameter.Free;
  FTestConfigParameter := nil;
end;

这种方式既保留了Setup/TearDown的通用能力,又能让每个测试用例传递专属参数,避免弃用标准的Setup/TearDown流程。

方案2:抽离核心测试逻辑

将核心测试逻辑封装为私有方法,每个TestCase对应一个测试方法负责参数转换和调用核心逻辑,Setup/TearDown正常处理通用工作:

[TestFixture]
TMY_Testcases = class
private
  FTestConfigParameter: TParameter;
  // 核心测试逻辑
  procedure Internal_DoMyTest(CreateFlag: Boolean; const AParameter: TParameter);
public
  [Setup]
  procedure Setup;
  [TearDown]
  procedure TearDown;

  [Test]
  [TestCase('CreateTrue_Param1', 'True,Param1')]
  procedure Test_DoMyTest_Param1(CreateFlag: Boolean; ParamAsString: string);

  [Test]
  [TestCase('CreateFalse_Param2', 'False,Param2')]
  procedure Test_DoMyTest_Param2(CreateFlag: Boolean; ParamAsString: string);
end;

procedure TMY_Testcases.Setup;
begin
  // 通用初始化,比如创建基础服务、配置环境
end;

procedure TMY_Testcases.TearDown;
begin
  FTestConfigParameter.Free;
  FTestConfigParameter := nil;
end;

procedure TMY_Testcases.Internal_DoMyTest(CreateFlag: Boolean; const AParameter: TParameter);
begin
  FTestConfigParameter := AParameter;
  // 执行核心测试逻辑
end;

procedure TMY_Testcases.Test_DoMyTest_Param1(CreateFlag: Boolean; ParamAsString: string);
var
  Param: TParameter;
begin
  Param := TParameter.Create(ParamAsString);
  try
    Internal_DoMyTest(CreateFlag, Param);
  finally
    Param.Free;
  end;
end;

procedure TMY_Testcases.Test_DoMyTest_Param2(CreateFlag: Boolean; ParamAsString: string);
var
  Param: TParameter;
begin
  Param := TParameter.Create(ParamAsString);
  try
    Internal_DoMyTest(CreateFlag, Param);
  finally
    Param.Free;
  end;
end;

这种方式通过拆分测试入口和核心逻辑,让每个TestCase对应独立的测试方法,同时保留标准的Setup/TearDown流程,代码结构更清晰。

内容的提问来源于stack exchange,提问作者Franz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:20:18