如何让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
相关产品推荐
相关产品推荐

