【发布时间】:2020-08-06 04:33:03
【问题描述】:
我对代码进行了一些单元测试,这些代码正在执行一些非常小的图像处理(将几个小图像组合成一个更大的图像)。当我运行测试时,我注意到其中四分之三在他们从目录中读取图像的那一行失败(失败并出现索引越界错误)。
但是,如果我再次运行它,它们都会通过。当我也在编写代码时,我注意到每当我在代码中设置断点时,我都必须运行两次单元测试,因为(在第一次之后)它会运行测试而不会遇到任何断点。
我的仓库是这样组织的:
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_tests\unit_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 函数完成之前运行单元测试,所以我添加了一个pause 语句并重新运行测试,但我遇到了同样的问题,只是这次它会等待必要的秒数,然后再继续并失败。如果我再次运行它,没问题 - 我的所有测试都通过了。
我完全不知道为什么会这样;我正在使用在 Win10 机器上运行的 vanilla matlab (R2018a),并且没有任何花哨的东西。我觉得您应该能够根据需要多次运行单元测试并期望得到相同的结果!有什么我刚刚忽略的吗?还是这是一些奇怪的功能?
【问题讨论】:
-
看起来您用于运行测试的命令两次不同。
-
我觉得应该怪
addpath。我会用mfilename和fileparts和fullfile计算绝对路径,而不是使用..。 -
@CrisLuengo - 我不敢相信我忽略了它,但你是完全正确的 - 它们正在使用两个不同的命令运行!我正在使用“运行测试”按钮并错误地认为它使用的是相同的命令。有趣的是,如果我从命令行运行
runtests('unit_tests')两次,它会给我不同数量的通过失败测试(2 而不是 3),而runtests('unit_tests\unit_tests.m')总是给出正确的输出。 -
我尝试将 addpath 更改为
filepath = regexp(fileparts(which(mfilename)), '\unit_tests', 'split');和addpath(genpath(filepath{1}));,但是由于某些深不可测的原因,这实际上使情况变得更糟。现在只运行一次成功(点击按钮只使用runtests('unit_tests\unit_tests.m')一次)您对正确的方法有什么建议吗? -
如果我没记错的话,
fullfile(fileparts(fileparts(mfilename('fullpath'))),'src')之类的东西应该会构建正确的路径。
标签: matlab unit-testing alternating