У меня есть несколько модульных тестов для кода, который выполняет очень незначительные манипуляции с изображениями (объединение нескольких маленьких изображений в большее изображение). Когда я запускал тесты, я заметил, что три из четырех из них не сработали на линии, где они читали изображение из каталога (сбой с ошибкой индекса за пределами).
Однако, если я запущу его снова, они все пройдут. Когда я писал код, я заметил, что всякий раз, когда я устанавливаю точку останова в своем коде, мне приходится запускать модульные тесты дважды, потому что (после самого первого раза) они будут выполняться через тесты без каких-либо точек останова.
У меня есть репо, организованное следующим образом:
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 теста предположительно проходят, они на самом деле вообще не выполняются. И тем не менее, если я снова прогоню тесты, они все пройдут. Запустите его в 4-й раз, и они снова терпят неудачу.
Сначала я подумал, что, возможно, модульные тесты выполнялись слишком быстро (только как-то при четных прогонах?) и он запускал модульные тесты до завершения функций addpath/genpath в настройке, поэтому я добавил оператор паузы и повторно провел тесты, но у меня была та же проблема, только на этот раз он ждал необходимое количество секунд, прежде чем продолжить и потерпеть неудачу. Если я запущу его снова, никаких проблем — все мои тесты пройдены.
Я совершенно не понимаю, почему это происходит; Я использую vanilla matlab (R2018a), работающий на машине с Win10, и у меня нет ничего необычного. Я чувствую, что вы должны иметь возможность запускать свои модульные тесты столько раз, сколько захотите, и ожидать одного и того же результата! Есть что-то, что я как-то упустил из виду? Или это какая-то странная особенность?
addpath
. Я бы вычислил абсолютный путь с помощьюmfilename
,fileparts
иfullfile
, а не..
. - person Cris Luengo   schedule 23.04.2020runtests('unit_tests')
из командной строки, это дает мне разное количество пройденных неудачных тестов (2 вместо 3), в то время какruntests('unit_tests\unit_tests.m')
всегда дает правильный результат. - person asdf   schedule 23.04.2020filepath = regexp(fileparts(which(mfilename)), '\unit_tests', 'split');
иaddpath(genpath(filepath{1}));
, однако по какой-то непостижимой причине это на самом деле ухудшило ситуацию. Теперь он успешно работает только один раз (нажатие кнопки использует только один разruntests('unit_tests\unit_tests.m')
) Есть ли у вас какие-либо предложения по правильному методу? - person asdf   schedule 23.04.2020fullfile(fileparts(fileparts(mfilename('fullpath'))),'src')
должно строить правильный путь, если я не ошибаюсь. - person Cris Luengo   schedule 23.04.2020