Введение

Тестирование - один из важнейших аспектов итеративной разработки программного обеспечения. Это связано с тем, что тесты могут автоматически выявить проблемы с программным обеспечением без необходимости его фактического использования. Излишне говорить, что, вероятно, размещение программного обеспечения, которое даже не работает, в репозиторий - плохая идея, и тестирование поможет избежать столкновения с этой проблемой. Реализация тестирования на языке программирования Julia - это реализация, которая, на мой взгляд, довольно крутая и уникальная. Я считаю, что это здорово, потому что он предоставляет очень структурированный и простой способ тестирования программного обеспечения с использованием условных выражений и макросов. Сегодня я хотел пройтись по основам пакета Testing.jl для Джулии, чтобы вы могли убедиться, что ваше программное обеспечение работает, прежде чем совершить огромную ошибку!

Настройка пакета

Чтобы продемонстрировать пакет тестирования Джулии, нам сначала нужно создать новый проект. Чтобы создать новый проект, мы можем использовать Pkg.generate () или команду generate в Pkg REPL. Оказавшись в REPL Джулии, я нажму] и сгенерирую наш новый проект под названием «Образец».

julia> ]
(@v1.6) pkg> generate sample

Затем я вернусь из этого REPL и нажму; для входа в Bash REPL. После этого мы войдем в нашу новую папку Project.

julia> ;
shell> cd sample

Теперь я вставлю cd в исходную папку и файл sample.jl в nano, добавив новую функцию, которую мы можем протестировать.

shell> cd src
/home/emmett/dev/julia/sample/src
shell> nano sample.jl

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

mean(x) = sum(x) / length(x)
function mae(actual,pred)
    l = length(actual)
    lp = length(pred)
    if l != lp
        throw(ArgumentError("The array shape does not match!"))
    end
    result = actual-pred
    maeunf = mean(result)
    if maeunf < 0
        maeunf = (maeunf - maeunf) - maeunf
    end
    return(maeunf)
end
function mse(y,ŷ)
    diff = y .- ŷ
    diff = diff .^ 2
    Σdiff = sum(diff)
    return(Σdiff)
end
function correlationcoeff(x,y)
    n = length(x)
    yl = length(y)
    @assert n == yl DimensionMismatch("These Arrays are not the same size.")
    xy = x .* y
    sx = sum(x)
    sy = sum(y)
    sxy = sum(xy)
    x2 = x .^ 2
    y2 = y .^ 2
    sx2 = sum(x2)
    sy2 = sum(y2)
    ((n*sxy) - (sx * sy)) / (sqrt((((n*sx2)-(sx^2)) * ((n*sy2)-(sy^2)))))
end
function r2(actual,pred)
    l = length(actual)
    lp = length(pred)
    if l != lp
        throw(ArgumentError("The array shape does not match!"))
    end
    r = correlationcoeff(actual,pred)
    rsq = r^2
    rsq = rsq * 100
    return(rsq)
end
export r2, mae, mse

Затем я использовал ctrl + O, чтобы освободить этот новый буфер, и теперь мы можем приступить к собственному тестированию этих функций!

Тестирование

Теперь, когда у нас действительно есть пакет для тестирования, мы можем приступить к настройке нашей тестовой среды. С пакетами Julia и тестирование, и документация считаются отдельными пакетами по отношению к исходному пакету. Имея это в виду, мы собираемся снова использовать команду generate, чтобы создать оба этих каталога проекта. Мы активируем эту новую тестовую среду, а затем добавим тестовую зависимость в ее виртуальную среду.

shell> cd ..
/home/emmett/dev/julia/sample
(@v1.6) pkg> activate test
  Activating new environment at `~/dev/julia/sample/test/Project.toml`
(test) pkg> add Test
    Updating registry at `~/.julia/registries/General`
   Resolving package versions...
    Updating `~/dev/julia/sample/test/Project.toml`
  [8dfed614] + Test
    Updating `~/dev/julia/sample/test/Manifest.toml`
  [2a0f44e3] + Base64
  [b77e0a4c] + InteractiveUtils
  [56ddb016] + Logging
  [d6f4376e] + Markdown
  [9a3f8284] + Random
  [9e88b42a] + Serialization
  [8dfed614] + Test
(test) pkg>

Теперь мы можем написать наши алгоритмы тестирования. Первая функция внутри пакета - MAE. Чтобы выполнить тест, нам нужно запустить набор тестов. Это делается с помощью макроса тестового набора. После макроса мы предоставляем строку в качестве первого параметра, а затем мы предоставляем выражение в качестве второго параметра. Строка - это заголовок нашего тестового набора, а выражение - это код, который будет выполнять наш тест. Мы можем создать такое выражение, используя начальный и конечный блоки. Все это вместе выглядит примерно так:

using Test
include("../src/sample.jl")
using Main.sample
@testset "MAE tests" begin
end

Мы начнем эти тесты с теста, в котором они равны, для этого сценария MAE должно быть равно одному. Тестовый макрос принимает единственный аргумент, и этот аргумент является логическим. Давайте воспользуемся поразрядным оператором типа bool для MAE двух равных массивов, который должен быть равен нулю.

x = [5, 10, 15]
y = [5, 10, 15]
@test mae(x, y) == 0

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

x, y = [4, 10, 15], [5, 10, 15]
    @test mae(x, y) == mean([1, 0, 0])

Для финального набора тестов, который выглядит так:

using Main.sample: r2, mae, mse, mean
@testset "MAE Tests" begin
    x = [5, 10, 15]
    y = [5, 10, 15]
    @test mae(x, y) == 0
    x, y = [4, 10, 15], [5, 10, 15]
    @test mae(x, y) == mean([1, 0, 0])
end

Затем мы начнем новый набор тестов для функции MSE. Мы проведем один тест на утверждение и один нулевой тест, как и раньше.

@testset "MSE Tests" begin
x = [5, 10, 15]
y = [5, 10, 15]
@test mse(x, y) == 0
y = [4, 10, 15]
y2 = [6, 10, 15]
@test mse(x, y) == mse(x, y2)
end

Далее мы протестируем нашу функцию r². Поскольку наша функция r² предназначена для возврата в процентах, мы оба проверим тип возврата как Float64, а затем проверим, меньше ли оно 1.

@testset "R2 Tests" begin
x = randn(50)
y = randn(50)
@test r2(x, y) <= 1
@test typeof(r2(x, y)) == Float64

Теперь мы можем запустить наши тесты, вернувшись к REPL и включив этот код.

include("test/test.jl")

Вывод

Независимо от того, какое программное обеспечение вы создаете, всегда будет важно его протестировать. У Джулии есть довольно крутой метод тестирования программного обеспечения, который использует макросы и делает тесты очень организованными. Я действительно предпочитаю этот стиль многим другим стилям тестирования, и я думаю, что Джулия упрощает тестирование, используя эту методологию. Большое спасибо за чтение моей статьи, и я надеюсь, что предоставленная информация полезна для улучшения работы вашего программного обеспечения! Спасибо за чтение!