当前位置: 首页> 教育> 就业 > 如何使用MATLAB写测试(3)combinatorial explosion? 参数化!

如何使用MATLAB写测试(3)combinatorial explosion? 参数化!

时间:2025/7/9 12:57:16来源:https://blog.csdn.net/m0_69824302/article/details/139453269 浏览次数:0次

如何使用MATLAB写测试(3)combinatorial explosion? 参数化!

原文:如何使用MATLAB写测试(3)combinatorial explosion? 参数化! - 知乎 (zhihu.com)

最近我们的俄罗斯实习生有些头大,他为foo程序写的正向测试只有single一种情况。

function out = foo(in)validateattributes(in,{'numeric'},{'nonempty'}); % Returns zeroout = zeros(size(in),'like',in);
end

他的老板看到他的测试后问他,你知道MATLAB中数据类型有几种吗?俄罗斯实习生虽然没读过孔乙己的故事,但至少也知道有double, single, uint8几种常见的类型。于是他尝试更新了下他的测试。

classdef myTest < matlab.unittest.TestCasemethods (Test)function testSingle(test) %function唯一的参数test是你的测试对象% Verifies single input casein        = single(10);             %输入expOut    = zeros(1,'single');      %期待的输出actualOut = foo(in);                %调用待测程序test.verifyEqual(actualOut,expOut); %比较实际输出与期待输出endfunction testDouble(test)% Verifies double input casein        = double(10);             %输入expOut    = zeros(1,'double');      %期待的输出actualOut = foo(in);                %调用待测程序test.verifyEqual(actualOut,expOut); %比较实际输出与期待输出end% Negative test casefunction testEmptyError(test)% Verifies error on empty inputin         = [];expErrorId = 'MATLAB:expectedNonempty';%传入function handle, 给出期待的error idtest.verifyError(@()foo(in),expErrorId);            endend
end

作为一个合格的实习生,他一下就发现了接下来会发生的事情。对于每一个数据类型,他都要写一个完全一样的测试。公司招他来可不是做ctrl+c,ctrl+v的。而且要是以后有更多的测试,每个都需要对不同数据类型做相同的test case, 那要多少啊?

还好我们的数学教育不差

他心想。手上迅速算着帐。

假设MATLAB有N种数据类型,而我为每个数据类型都需要写M个测试,假设M个测试对每个数据类型都是相同的,那我就会有
𝐶𝑁1∗𝑀=𝑁∗𝑀
个测试,这还是以我的程序需要一个输入为前提。
这是如果我的程序需要两个输入,比如foo(x,y)
那我要写的测试数量就变成了
𝐶𝑁1∗𝐶𝑁1∗𝑀=𝑁2∗𝑀
...
如果程序需要k个输入,那要写的测试数量就变成了
𝑁𝑘∗𝑀

想到这里他背后直冒冷汗,难道自己的一生就耗在写测试上了?

MATLAB这么高大上的语言一定不会允许这件事发生的。

他边这么想着边翻阅着文档,突然发现了Parametrized Tests这篇教程。他按部就班地更新了自己的测试

classdef myTest < matlab.unittest.TestCase    properties(TestParameter) %定义测试参数type = {'double','single','uint8'} endmethods (Test)function testInput(test, type) %传入测试参数% Verifies single input casein        = cast(10,type);           %输入expOut    = zeros(1,type);           %期待的输出actualOut = foo(in);                 %调用待测程序test.verifyEqual(actualOut,expOut);  %比较实际输出与期待输出endend
end

跑test

>> result = runtests('myTest')
Running myTest
...
Done myTest
__________result = 1x3 TestResult array with properties:NamePassedFailedIncompleteDurationDetailsTotals:3 Passed, 0 Failed, 0 Incomplete.0.12308 seconds testing time.

注意到了吗,虽然只写了1个test case, 但是结果result中却有3个TestResult。展开看看究竟是什么?

>> result.Nameans =myTest/testInput(supportedClass=double)ans =myTest/testInput(supportedClass=single)ans =myTest/testInput(supportedClass=uint8)

哦!

掌握了基本参数化测试的俄罗斯实习生决定试试更高级的技巧,他为自己的源程序加入了一个新的输入

function out = foo(in1 , in2)assert(isequal(size(in1),size(in2)),'input 1 and input 2 must be of same size'); % ugly but worksvalidateattributes(in1,{'numeric'},{'nonempty'}); validateattributes(in2,{'numeric'},{'nonempty'}); % Cast everything into input 1's classin2 = cast(in2,class(in1));% Returns zeroout = zeros(size(in1),'like',in1) * zeros(size(in2),'like',in2) ;
end

并更新了测试

classdef myTest < matlab.unittest.TestCase    properties(TestParameter) %定义测试参数type1 = {'double','single','uint8'} type2 = {'double','single','uint8'} endmethods (Test)function testInput(test, type1, type2) %传入测试参数% Verifies single input casein1        = cast(10,type1); %输入in2        = cast(10,type2); %输入expOut     = zeros(1,type1); %期待的输出actualOut  = foo(in1,in2);   %调用待测程序test.verifyEqual(actualOut,expOut);  %比较实际输出与期待输出endend
end

跑tests

>> result = runtests('myTest')
Running myTest
.........
Done myTest
__________result = 1x9 TestResult array with properties:NamePassedFailedIncompleteDurationDetailsTotals:9 Passed, 0 Failed, 0 Incomplete.0.10923 seconds testing time.

有9个测试了,心算下……

3个数据类型,2个输入,1个测试方法
𝑁=3,𝑘=2,𝑀=1,𝑁𝑘∗𝑀=32∗1=9

对哦!

这下combinatorial explosion的问题就给计算机去解决吧!我1000刀买来配Oculus Rift的机器跑这点test还是可以的……

有兴趣的玩家(读者 可以阅读如何利用ParameterCombination来减少测试的数量

-参考资料

Create Basic Parameterized Test

Create Advanced Parameterized Test

关键字:如何使用MATLAB写测试(3)combinatorial explosion? 参数化!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: