exponenta event banner

Запись модульных тестов на основе сценариев

В этом примере показано, как написать сценарий, который проверяет создаваемую функцию. В примере функция вычисляет углы прямого треугольника, и для проверки функции создается единичный тест на основе сценария.

Создание функции reyTri для тестирования

Создайте эту функцию в файле, rightTri.m, в текущей папке MATLAB ®. Эта функция принимает длины двух сторон треугольника в качестве входных данных и возвращает три угла соответствующего прямого треугольника. Входные стороны являются двумя более короткими кромками треугольника, а не гипотенузой.

function angles = rightTri(sides)

A = atand(sides(1)/sides(2));
B = atand(sides(2)/sides(1));
hypotenuse = sides(1)/sind(A);
C = asind(hypotenuse*sind(A)/sides(1));

angles = [A B C];

end

Создать тестовый сценарий

В рабочей папке создайте новый сценарий, rightTriTest.m. Каждый единичный тест проверяет различные выходные данные rightTri функция. Сценарий тестирования должен соответствовать следующим соглашениям:

  • Имя тестового файла должно начинаться или заканчиваться словом «test», которое не учитывает регистр. Если имя файла не начинается или не заканчивается словом «test», то в некоторых случаях тесты в файле могут игнорироваться.

  • Поместите каждый единичный тест в отдельный раздел файла сценария. Каждая секция начинается с двух процентных знаков (%%), и текст, следующий в той же строке, становится именем тестового элемента. Если текст не следует за %%MATLAB присваивает тесту имя. Если MATLAB обнаруживает сбой теста, он по-прежнему выполняет оставшиеся тесты.

  • В тестовом сценарии раздел общей переменной состоит из любого кода, который появляется перед первым явно выраженным разделом кода (первая строка начинается с %%). Тесты совместно используют переменные, определенные в этом разделе. В рамках теста можно изменить значения этих переменных. Однако в последующих тестах значение сбрасывается до значения, определенного в разделе общих переменных.

  • В разделе общих переменных (первый раздел кода) определите любые предварительные условия, необходимые для тестов. Если входы или выходы не соответствуют этому предварительному условию, MATLAB не выполняет ни одного из тестов. MATLAB помечает тесты как неуспешные и неполные.

  • При запуске сценария в качестве теста переменные, определенные в одном тесте, недоступны в других тестах, если они не определены в разделе общих переменных (первый раздел кода). Аналогично, переменные, определенные в других рабочих пространствах, недоступны для тестов.

  • Если файл сценария не содержит разделов кода, MATLAB генерирует один тестовый элемент из полного содержимого файла сценария. Имя тестового элемента совпадает с именем файла сценария. В этом случае, если MATLAB сталкивается с неуспешным тестом, он останавливает выполнение всего сценария.

В rightTriTest.m, запишите четыре теста для проверки выходных данных rightTri. Используйте assert для проверки различных условий. В разделе общих переменных определите четыре треугольные геометрии и определите предварительное условие, что rightTri функция возвращает прямоугольный треугольник.

% test triangles
tri = [7 9];
triIso = [4 4];
tri306090 = [2 2*sqrt(3)];
triSkewed = [1 1500];

% preconditions
angles = rightTri(tri);
assert(angles(3) == 90,'Fundamental problem: rightTri not producing right triangle')

%% Test 1: sum of angles
angles = rightTri(tri);
assert(sum(angles) == 180)
 
angles = rightTri(triIso);
assert(sum(angles) == 180)
 
angles = rightTri(tri306090);
assert(sum(angles) == 180)
 
angles = rightTri(triSkewed);
assert(sum(angles) == 180)

%% Test 2: isosceles triangles
angles = rightTri(triIso);
assert(angles(1) == 45)
assert(angles(1) == angles(2))
 
%% Test 3: 30-60-90 triangle
angles = rightTri(tri306090);
assert(angles(1) == 30)
assert(angles(2) == 60)
assert(angles(3) == 90)

%% Test 4: Small angle approximation
angles = rightTri(triSkewed);
smallAngle = (pi/180)*angles(1); % radians
approx = sin(smallAngle);
assert(approx == smallAngle, 'Problem with small angle approximation')

Тест 1 проверяет суммирование углов треугольника. Если суммирование не равно 180 градусам, assert выдает ошибку.

Тест 2 проверяет, что если две стороны равны, соответствующие углы равны. Если непрямые углы не равны 45 градусам, assert функция выдает ошибку.

Тест 3 проверяет, что если стороны треугольника 1 и sqrt(3)углы 30, 60 и 90 градусов. Если это условие не соответствует действительности, assert выдает ошибку.

Тест 4 проверяет приближение малого угла. Малоугловая аппроксимация утверждает, что для малых углов синус угла в радианах примерно равен углу. Если это неправда, assert выдает ошибку.

Выполнить тесты

Выполните команду runtests для выполнения четырех тестов в rightTriTest.m. runtests выполняет каждый тест в каждом кодовом разделе по отдельности. Если тест 1 завершается неуспешно, MATLAB по-прежнему выполняет оставшиеся тесты. При выполнении rightTriTest в качестве сценария вместо использования runtestsMATLAB останавливает выполнение всего сценария, если он сталкивается с неуспешным утверждением. Кроме того, при выполнении тестов с помощью runtests функция MATLAB обеспечивает информационную диагностику тестов.

result = runtests('rightTriTest');
Running rightTriTest
..
================================================================================
Error occurred in rightTriTest/Test3_30_60_90Triangle and it did not run to completion.
    ---------
    Error ID:
    ---------
    'MATLAB:assertion:failed'
    --------------
    Error Details:
    --------------
    Error using rightTriTest (line 31)
    Assertion failed.
================================================================================
.
================================================================================
Error occurred in rightTriTest/Test4_SmallAngleApproximation and it did not run to completion.
    ---------
    Error ID:
    ---------
    ''
    --------------
    Error Details:
    --------------
    Error using rightTriTest (line 39)
    Problem with small angle approximation
================================================================================
.
Done rightTriTest
__________

Failure Summary:

     Name                                        Failed  Incomplete  Reason(s)
    ===========================================================================
     rightTriTest/Test3_30_60_90Triangle           X         X       Errored.
    ---------------------------------------------------------------------------
     rightTriTest/Test4_SmallAngleApproximation    X         X       Errored.

Тест для 30-60-90 треугольник и тест для аппроксимации малого угла проваливаются при сравнении чисел с плавающей запятой. Обычно при сравнении значений с плавающей запятой задается допуск для сравнения. В тестах 3 и 4 MATLAB выдает ошибку при неуспешном подтверждении и не завершает тест. Поэтому тест помечается как оба Failed и Incomplete.

Для предоставления диагностической информации (Error Details) это более информативно, чем 'Assertion failed' (Тест 3), рассмотрите возможность передачи сообщения assert (как в тесте 4). Также можно рассмотреть возможность использования функциональных модульных тестов.

Создать новую версию теста для использования допуска

Сохранить rightTriTest.m как rightTriTolTest.mи пересмотреть тест 3 и тест 4 для использования допуска. В тестах 3 и 4 вместо того, чтобы утверждать, что углы равны ожидаемому значению, утверждайте, что разница между фактическим и ожидаемым значениями меньше или равна указанному допуску. Определите допуск в разделе общих переменных сценария теста, чтобы он был доступен для обоих тестов.

При тестировании единиц измерения на основе сценариев вручную убедитесь, что разница между двумя значениями меньше заданного допуска. Если вместо этого записать функциональный единичный тест, можно получить доступ к встроенным ограничениям для указания допуска при сравнении значений с плавающей запятой.

% test triangles
tri = [7 9];
triIso = [4 4];
tri306090 = [2 2*sqrt(3)];
triSkewed = [1 1500];

% Define an absolute tolerance
tol = 1e-10; 
 
% preconditions
angles = rightTri(tri);
assert(angles(3) == 90,'Fundamental problem: rightTri not producing right triangle')

%% Test 1: sum of angles
angles = rightTri(tri);
assert(sum(angles) == 180)
 
angles = rightTri(triIso);
assert(sum(angles) == 180)
 
angles = rightTri(tri306090);
assert(sum(angles) == 180)
 
angles = rightTri(triSkewed);
assert(sum(angles) == 180)

%% Test 2: isosceles triangles
angles = rightTri(triIso);
assert(angles(1) == 45)
assert(angles(1) == angles(2))
 
%% Test 3: 30-60-90 triangle
angles = rightTri(tri306090);
assert(abs(angles(1)-30) <= tol)
assert(abs(angles(2)-60) <= tol)
assert(abs(angles(3)-90) <= tol)

%% Test 4: Small angle approximation
angles = rightTri(triSkewed);
smallAngle = (pi/180)*angles(1); % radians
approx = sin(smallAngle);
assert(abs(approx-smallAngle) <= tol, 'Problem with small angle approximation')

Повторите тесты.

result = runtests('rightTriTolTest');
Running rightTriTolTest
....
Done rightTriTolTest
__________

Все тесты проходят.

Создайте таблицу результатов теста.

rt = table(result)
rt =

  4×6 table

                          Name                           Passed    Failed    Incomplete    Duration       Details   
    _________________________________________________    ______    ______    __________    _________    ____________

    {'rightTriTolTest/Test1_SumOfAngles'            }    true      false       false         0.02373    {1×1 struct}
    {'rightTriTolTest/Test2_IsoscelesTriangles'     }    true      false       false       0.0047332    {1×1 struct}
    {'rightTriTolTest/Test3_30_60_90Triangle'       }    true      false       false       0.0051982    {1×1 struct}
    {'rightTriTolTest/Test4_SmallAngleApproximation'}    true      false       false       0.0049869    {1×1 struct}

См. также

|

Связанные темы