Matlab 单元测试在通过和失败之间交替(通过"odd"运行,"even"失败)



我对正在进行一些非常小的图像操作(将几个小图像组合成一个大图像(的代码进行了一些单元测试。当我运行测试时,我注意到四分之三的测试在从目录读取图像的行上失败(由于索引越界错误而失败(。

然而,如果我再次运行它,它们都会通过。当我写代码的时候,我注意到每当我在代码中设置断点时,我都必须运行两次单元测试,因为(在第一次之后(它会在不碰到任何断点的情况下运行完测试。

我的回购是这样组织的:

src/
/* source code .m files are in here */
unit_tests/
images/
squares/
- img1.png
- img2.png
...
- imgn.png
- unit_tests.m

在我的设置中(在unit_tests.m中(有一行代码用于生成和添加所有代码的路径:

function tests = unit_tests()
addpath(genpath('..'));    
tests = functiontests(localfunctions);
end

单元测试都有这样的格式:

function testCompositeImage_2x3(testCase)
squares = dir('images/squares/*.png');
num_images = length(squares);
img = imread([squares(1).folder filesep squares(1).name]); % all same size squares
rows = 2;
cols = 3;
buffer = 2;
for idx = 1:num_images - (rows*cols)
imarray = cell(1,(rows*cols));
n = 1;
for ii = idx:idx +(rows*cols) -1
imarray{n} = imread([squares(ii).folder filesep squares(ii).name]);
n = n + 1;
end
newimg = createCompositeImage(rows,cols,imarray, buffer);
expCols = cols*size(img,1) + (cols+1)*2*buffer;
expRows = rows*size(img,2) + (rows+1)*2*buffer;
assert(checksize(newimg, expRows, expCols, 3) == true);
end
end

("checksize"只是我写的一个助手,它返回布尔值b/c断言不比较矩阵(

当我启动一个新的matlab会话并运行单元测试(使用编辑器选项卡中的"运行测试"按钮(时,它们会通过以下输出:

>> runtests('unit_testsunit_tests.m')
Running unit_tests
.......
Done unit_tests
__________

ans = 
1×7 TestResult array with properties:
Name
Passed
Failed
Incomplete
Duration
Details
Totals:
7 Passed, 0 Failed, 0 Incomplete.
0.49467 seconds testing time.

第二次运行(再次按下按钮(:

>> runtests('unit_tests')
Running unit_tests
..
================================================================================
Error occurred in unit_tests/testCompositeImage_2x2 and it did not run to completion.
---------
Error ID:
---------
'MATLAB:badsubscript'
--------------
Error Details:
--------------
Index exceeds array bounds.
Error in unit_tests>testCompositeImage_2x2 (line 47)
img = imread([squares(1).folder filesep squares(1).name]); % all same size
================================================================================
/*similar error info for the other two failing tests...*/
...
Done unit_tests
__________
Failure Summary:
Name                               Failed  Incomplete  Reason(s)
==================================================================
unit_tests/testCompositeImage_2x2    X         X       Errored.
------------------------------------------------------------------
unit_tests/testCompositeImage_2x3    X         X       Errored.
------------------------------------------------------------------
unit_tests/testCompositeImage_3x2    X         X       Errored.

ans = 
1×7 TestResult array with properties:
Name
Passed
Failed
Incomplete
Duration
Details
Totals:
4 Passed, 3 Failed (rerun), 3 Incomplete.
0.0072287 seconds testing time.

事实上,它基本上在第一行就失败了,因为它没有从文件夹中读取任何内容,这让我怀疑,即使其他4项测试本应通过,但实际上它们根本没有运行。然而,如果我再次运行测试,它们都通过了。运行第四次,它们再次失败。

起初,我认为单元测试可能执行得太快了(只在偶数次运行时执行?(,而且它在设置中的addpath/genpath函数完成之前就在运行单元测试,所以我添加了一个暂停语句并重新运行了测试,但我也遇到了同样的问题,只是这次它会等待必要的秒数,然后继续运行并失败。如果我再次运行它,没有问题-我所有的测试都通过了。

我完全不知道为什么会发生这种事;我使用的是在Win10机器上运行的香草matlab(R2018a(,没有任何花哨的东西。我觉得你应该能够随心所欲地运行单元测试,并期望得到相同的结果!是不是有什么我忽略了?或者这是什么奇怪的特征?

添加我的修复程序,以防其他人遇到同样的问题。

正如克里斯所指出的,这条线

addpath(genpath('..'));

导致GUI进入一种奇怪的状态,按下"运行测试"按钮在调用runtests('unit_testsunit_tests.m')runtests('unit_tests')之间交替,这反过来又导致测试交替通过和失败。这似乎不是路径变量本身的问题(因为它总是至少包含必要的目录(,而是matlab本身固有的问题。我能找到的最接近问题根源的方法是调用genpath函数中的(编译的(dir函数。

"正确"的解决方案是从unit_tests函数中完全删除该行,并将其添加到setupOnce函数中:

function tests = unit_tests()
tests = functiontests(localfunctions);
end
function setupOnce(testCase)
addpath(genpath('..'));
end

不需要setupOnce功能的破解(不推荐(如下:

function tests = unit_tests()
pth = fullfile(fileparts(fileparts(mfilename('fullpath'))),'src');
paths = regexp(genpath(pth), ';', 'split');
for idx = 1:length(paths) - 1 % last element is empty
addpath(paths{idx});
end
end

我需要重新启动matlab才能使更改生效。这适用于我在Win10上运行r2018a的设置。

相关内容

  • 没有找到相关文章

最新更新