Тестирование модулей
Тестирование базовой Julia
Julia активно развивается и имеет обширную тестовую базу для проверки работоспособности на нескольких платформах. Если вы собираете Julia из исходного кода, вы можете запустить эту тестовую базу с помощью make test. В случае бинарной установки тестовую базу можно запустить с помощью Base.runtests().
Base.runtestsФункция
Base.runtests(tests=["all"]; ncores=ceil(Int, Sys.CPU_THREADS / 2),
exit_on_error=false, revise=false, [seed])
Запустить тесты модулей Julia, перечисленные в tests, которые могут быть строкой или массивом строк, используя процессоры ncores. Если exit_on_error равно false, при провале одного теста все оставшиеся тесты в других файлах всё равно будут запущены; в противном случае они будут пропущены, когда exit_on_error == true. Если revise равно true, используется пакет Revise, чтобы загрузить любые изменения в Base или стандартные библиотеки перед запуском тестов. Если начальное значение предоставлено через ключевой аргумент, оно используется для инициализации глобального генератора случайных чисел в контексте выполнения тестов; в противном случае начальное значение выбирается случайным образом.
Базовые модульные тесты
Модуль Test предоставляет простую функциональность модульного тестирования. Модульное тестирование — это способ проверить правильность вашего кода, убедившись, что результаты соответствуют ожидаемым. Это может быть полезно для обеспечения работоспособности кода после внесения изменений и может быть использовано при разработке для спецификации поведения вашего кода в завершенном виде. Также вы можете ознакомиться с документацией по добавлению тестов в ваш пакет Julia.
Простые модульные тесты можно выполнить с помощью макросов @test и @test_throws:
Test.@testМакрос
@test ex @test f(args...) key=val ... @test ex broken=true @test ex skip=true
Проверить, что выражение ex вычисляется до true. Если выполняется внутри @testset, вернуть Pass Result, если это так, Fail Result, если это false, и Error Result, если оно не может быть вычислено. Если выполняется вне @testset, вместо возврата Fail или Error сгенерировать исключение.
Примеры
julia> @test true Test Passed julia> @test [1, 2] + [2, 1] == [3, 3] Test Passed
Форма @test f(args...) key=val... эквивалентна записи @test f(args..., key=val...), что может быть полезно, когда выражение является вызовом с использованием инфиксной синтаксической конструкции, такой как приблизительные сравнения:
julia> @test π ≈ 3.14 atol=0.01 Test Passed
Это эквивалентно менее удобному тесту @test ≈(π, 3.14, atol=0.01). Не допускается передавать более одного выражения, если первое не является выражением вызова, а остальные — присваиваниями (k=v).
Вы можете использовать любые ключи для аргументов key=val, кроме broken и skip, которые имеют специальное значение в контексте @test:
-
broken=condуказывает на тест, который должен пройти, но в настоящее время постоянно терпит неудачу, когдаcond==true. Тестирует, что выражениеexвычисляется доfalseили вызывает исключение. ВозвращаетBrokenResultв случае успеха, илиErrorResultесли выражение вычисляется доtrue. Регулярное@test exвычисляется приcond==false. -
skip=condотмечает тест, который не должен выполняться, но должен включаться в отчет о результатах тестов какBroken, когдаcond==true. Это может быть полезно для тестов, которые периодически завершаются неудачей, или тестов для ещё не реализованной функциональности. Регулярное@test exвычисляется приcond==false.
Примеры
julia> @test 2 + 2 ≈ 6 atol=1 broken=true Test Broken Expression: ≈(2 + 2, 6, atol = 1) julia> @test 2 + 2 ≈ 5 atol=1 broken=false Test Passed julia> @test 2 + 2 == 5 skip=true Test Broken Skipped: 2 + 2 == 5 julia> @test 2 + 2 == 4 skip=false Test Passed
Ключевые аргументы broken и skip требуют как минимум Julia 1.7.
Test.@test_throwsМакрос
@test_throws exception expr
Тестирует, что выражение expr вызывает exception. Исключение может указывать тип, строку, регулярное выражение или список строк, встречающихся в сообщении об ошибке, функцию сопоставления или значение (которое будет проверено на равенство путем сравнения полей). Обратите внимание, что @test_throws не поддерживает форму с ключевым аргументом в конце.
Возможность указать что-либо кроме типа или значения как exception требует Julia v1.8 или более поздней версии.
Примеры
julia> @test_throws BoundsError [1, 2, 3][4]
Test Passed
Thrown: BoundsError
julia> @test_throws DimensionMismatch [1, 2, 3] + [1, 2]
Test Passed
Thrown: DimensionMismatch
julia> @test_throws "Try sqrt(Complex" sqrt(-1)
Test Passed
Message: "DomainError with -1.0:\nsqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x))."
В последнем примере вместо сопоставления одной строки можно было бы использовать:
-
["Try", "Complex"](список строк) -
r"Try sqrt\([Cc]omplex"(регулярное выражение) -
str -> occursin("complex", str)(функция сопоставления)
Например, предположим, что мы хотим проверить, что наша новая функция foo(x) работает как ожидается:
julia> using Test julia> foo(x) = length(x)^2 foo (generic function with 1 method)
Если условие истинно, возвращается Pass:
julia> @test foo("bar") == 9
Test Passed
julia> @test foo("fizz") >= 10
Test Passed
Если условие ложно, то возвращается Fail и генерируется исключение:
julia> @test foo("f") == 20
Test Failed at none:1
Expression: foo("f") == 20
Evaluated: 1 == 20
ERROR: There was an error during testing
Если условие не может быть вычислено из-за возникновения исключения, что происходит в данном случае, так как length не определено для символов, возвращается объект Error и генерируется исключение:
julia> @test foo(:cat) == 1
Error During Test
Test threw an exception of type MethodError
Expression: foo(:cat) == 1
MethodError: no method matching length(::Symbol)
Closest candidates are:
length(::SimpleVector) at essentials.jl:256
length(::Base.MethodList) at reflection.jl:521
length(::MethodTable) at reflection.jl:597
...
Stacktrace:
[...]
ERROR: There was an error during testing
Если мы ожидаем, что при вычислении выражения должно возникнуть исключение, то мы можем использовать @test_throws для проверки этого:
julia> @test_throws MethodError foo(:cat)
Test Passed
Thrown: MethodError
Работа с наборами тестов
Обычно используется большое количество тестов, чтобы убедиться, что функции работают корректно на широком диапазоне входных данных. В случае неудачи теста по умолчанию происходит немедленное генерирование исключения. Однако обычно предпочтительнее сначала выполнить оставшиеся тесты, чтобы лучше понять, сколько ошибок содержится в тестируемом коде.
@testset создаст локальную область видимости при запуске тестов внутри неё.
Макрос @testset может использоваться для группировки тестов в наборы. Все тесты в наборе будут запущены, и в конце набора будет напечатан сводный отчёт. Если какие-либо тесты завершились неудачей или не удалось их вычислить из-за ошибки, набор тестов сгенерирует TestSetException.
Test.@testsetМакрос
@testset [CustomTestSet] [option=val ...] ["description"] begin ... end @testset [CustomTestSet] [option=val ...] ["description $v"] for v in (...) ... end @testset [CustomTestSet] [option=val ...] ["description $v, $w"] for v in (...), w in (...) ... end @testset [CustomTestSet] [option=val ...] ["description $v, $w"] foo()
Начинает новый набор тестов или несколько наборов тестов, если используется цикл for.
Если тип набора тестов не указан, по умолчанию создаётся DefaultTestSet. DefaultTestSet записывает все результаты и, если имеются какие-либо Fail или Error , генерирует исключение в конце верхнеуровневого (не вложенного) набора тестов вместе со сводкой результатов тестов.
Можно указать любой пользовательский тип набора тестов (подтип AbstractTestSet) и он будет использоваться для всех вложенных вызовов @testset . Указанные параметры применяются только к набору тестов, где они указаны. Тип набора тестов по умолчанию принимает два логических параметра:
-
verbose: еслиtrue, сводная информация по результатам вложенных наборов тестов отображается даже
когда все они пройдены (по умолчанию false).
-
showtiming: еслиtrue, отображается время выполнения каждого набора тестов
(по умолчанию true).
@testset foo() требует как минимум Julia 1.8.
Строка описания поддерживает интерполяцию из индексов цикла. Если описание не указано, оно генерируется на основе переменных. Если указан вызов функции, будет использовано её имя. Явные строки описания переопределяют это поведение.
По умолчанию макрос @testset возвращает сам объект набора тестов, хотя это поведение можно настроить в других типах наборов тестов. Если используется цикл for , макрос собирает и возвращает список возвращаемых значений метода finish , который по умолчанию возвращает список объектов наборов тестов, использованных в каждом итерационном шаге.
Перед выполнением тела @testset, неявно вызывается Random.seed!(seed), где seed — текущее начальное значение глобального генератора случайных чисел. Кроме того, после выполнения тела состояние глобального генератора случайных чисел восстанавливается до состояния, существовавшего до вызова @testset. Это предназначено для повышения воспроизводимости в случае сбоя и для обеспечения бесшовных переупорядочений @testset независимо от их влияния на состояние глобального генератора случайных чисел.
Примеры
julia> @testset "trigonometric identities" begin
θ = 2/3*π
@test sin(-θ) ≈ -sin(θ)
@test cos(-θ) ≈ cos(θ)
@test sin(2θ) ≈ 2*sin(θ)*cos(θ)
@test cos(2θ) ≈ cos(θ)^2 - sin(θ)^2
end;
Test Summary: | Pass Total Time
trigonometric identities | 4 4 0.2s
Test.TestSetExceptionТип
TestSetException
Генерируется, когда набор тестов завершается, и не все тесты прошли успешно.
Мы можем поместить наши тесты для функции foo(x) в набор тестов:
julia> @testset "Foo Tests" begin
@test foo("a") == 1
@test foo("ab") == 4
@test foo("abc") == 9
end;
Test Summary: | Pass Total Time
Foo Tests | 3 3 0.0s
Наборы тестов также могут быть вложенными:
julia> @testset "Foo Tests" begin
@testset "Animals" begin
@test foo("cat") == 9
@test foo("dog") == foo("cat")
end
@testset "Arrays $i" for i in 1:3
@test foo(zeros(i)) == i^2
@test foo(fill(1.0, i)) == i^2
end
end;
Test Summary: | Pass Total Time
Foo Tests | 8 8 0.0s
А также вызывать функции:
julia> f(x) = @test isone(x) f (generic function with 1 method) julia> @testset f(1); Test Summary: | Pass Total Time f | 1 1 0.0s
Это можно использовать для факторизации наборов тестов, что облегчает запуск отдельных наборов тестов путём запуска соответствующих функций. Обратите внимание, что в случае функций набор тестов будет получать имя вызываемой функции. В случае, если вложенный набор тестов не содержит неудач, как это произошло здесь, он будет скрыт в сводке, если не будет передан параметр verbose=true:
julia> @testset verbose = true "Foo Tests" begin
@testset "Animals" begin
@test foo("cat") == 9
@test foo("dog") == foo("cat")
end
@testset "Arrays $i" for i in 1:3
@test foo(zeros(i)) == i^2
@test foo(fill(1.0, i)) == i^2
end
end;
Test Summary: | Pass Total Time
Foo Tests | 8 8 0.0s
Animals | 2 2 0.0s
Arrays 1 | 2 2 0.0s
Arrays 2 | 2 2 0.0s
Arrays 3 | 2 2 0.0s
Если у нас есть неудача в тесте, будут отображены только детали неудачных наборов тестов:
julia> @testset "Foo Tests" begin
@testset "Animals" begin
@testset "Felines" begin
@test foo("cat") == 9
end
@testset "Canines" begin
@test foo("dog") == 9
end
end
@testset "Arrays" begin
@test foo(zeros(2)) == 4
@test foo(fill(1.0, 4)) == 15
end
end
Arrays: Test Failed
Expression: foo(fill(1.0, 4)) == 15
Evaluated: 16 == 15
[...]
Test Summary: | Pass Fail Total Time
Foo Tests | 3 1 4 0.0s
Animals | 2 2 0.0s
Arrays | 1 1 2 0.0s
ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken.
Тестирование операторов регистрации
Можно использовать макрос @test_logs для тестирования операторов регистрации или использовать TestLogger.
Test.@test_logsМакрос
@test_logs [log_patterns...] [keywords] expression
Соберите список записей журнала, сгенерированных expression с помощью collect_test_logs, проверьте, что они соответствуют последовательности log_patterns, и верните значение expression. keywords предоставляют некоторую простую фильтрацию записей журнала: ключевое слово min_level управляет минимальным уровнем журнала, который будет собран для теста, ключевое слово match_mode определяет, как будет выполняться соответствие (по умолчанию :all проверяет, что все журналы и шаблоны соответствуют попарно; используйте :any для проверки, что шаблон соответствует хотя бы один раз где-то в последовательности.)
Наиболее полезный шаблон журнала — это простая кортеж формата (level,message). Разное количество элементов кортежа может быть использовано для сопоставления других метаданных журнала, соответствующих аргументам, переданным AbstractLogger через функцию handle_message: (level,message,module,group,id,file,line). Элементы, которые присутствуют, будут сопоставляться попарно с полями записей журнала по умолчанию с использованием ==, со специальными случаями, что Symbol могут использоваться для стандартных уровней журнала, и Regex в шаблоне будут соответствовать строковым или Символьным полям, используя occursin.
Примеры
Рассмотрим функцию, которая записывает предупреждение и несколько сообщений отладки:
function foo(n)
@info "Doing foo with n=$n"
for i=1:n
@debug "Iteration $i"
end
42
end
Мы можем протестировать сообщение info с помощью
@test_logs (:info,"Doing foo with n=2") foo(2)
Если мы также хотели протестировать сообщения отладки, их необходимо включить с помощью ключевого слова min_level:
using Logging @test_logs (:info,"Doing foo with n=2") (:debug,"Iteration 1") (:debug,"Iteration 2") min_level=Logging.Debug foo(2)
Если вы хотите проверить, что генерируются некоторые конкретные сообщения, игнорируя остальные, вы можете установить ключевое слово match_mode=:any:
using Logging @test_logs (:info,) (:debug,"Iteration 42") min_level=Logging.Debug match_mode=:any foo(100)
Макрос может быть связан с @test для тестирования возвращаемого значения:
@test (@test_logs (:info,"Doing foo with n=2") foo(2)) == 42
Если вы хотите проверить отсутствие предупреждений, вы можете опустить указание шаблонов журналов и соответственно установить min_level:
# test that the expression logs no messages when the logger level is warn:
@test_logs min_level=Logging.Warn @info("Some information") # passes
@test_logs min_level=Logging.Warn @warn("Some information") # fails
Если вы хотите проверить отсутствие предупреждений (или сообщений об ошибках) в stderr, которые не генерируются @warn, см. @test_nowarn.
Test.TestLoggerТип
TestLogger(; min_level=Info, catch_exceptions=false)
Создайте TestLogger, который захватывает записанные сообщения в своем поле logs::Vector{LogRecord}.
Установите min_level для управления LogLevel, catch_exceptions для того, чтобы исключить или включить обработку исключений, сгенерированных в процессе создания событий журнала, и respect_maxlog для того, чтобы следовать соглашению о записи сообщений с maxlog=n для некоторого целого n не более n раз.
См. также: LogRecord.
Пример
julia> using Test, Logging
julia> f() = @info "Hi" number=5;
julia> test_logger = TestLogger();
julia> with_logger(test_logger) do
f()
@info "Bye!"
end
julia> @test test_logger.logs[1].message == "Hi"
Test Passed
julia> @test test_logger.logs[1].kwargs[:number] == 5
Test Passed
julia> @test test_logger.logs[2].message == "Bye!"
Test Passed
Test.LogRecordТип
LogRecord
Хранит результаты одного события журнала. Поля:
-
level:LogLevelсообщения журнала -
message: текстовое содержание сообщения журнала -
_module: модуль события журнала -
group: группа журналов (по умолчанию, имя файла, содержащего событие журнала) -
id: идентификатор события журнала -
file: файл, содержащий событие журнала -
line: строка в файле события журнала -
kwargs: любые ключевые аргументы, переданные в событие журнала
Другие макросы тестов
Так как вычисления с плавающей точкой могут быть неточными, вы можете выполнить проверки приблизительного равенства, используя либо @test a ≈ b (где ≈, набираемый с помощью автодополнения \approx, является функцией isapprox) или напрямую использовать isapprox.
julia> @test 1 ≈ 0.999999999 Test Passed julia> @test 1 ≈ 0.999999 Test Failed at none:1 Expression: 1 ≈ 0.999999 Evaluated: 1 ≈ 0.999999 ERROR: There was an error during testing
Вы можете указать относительные и абсолютные погрешности, установив ключевые аргументы rtol и atol функции isapprox, соответственно, после сравнения ≈:
julia> @test 1 ≈ 0.999999 rtol=1e-5 Test Passed
Обратите внимание, что это не специфическая функция ≈, а скорее общая функция макроса @test: @test a <op> b key=val преобразуется макросом в @test op(a, b, key=val). Однако это особенно полезно для тестов ≈.
Test.@inferredМакрос
@inferred [AllowedType] f(x)
Проверяет, что выражение вызова f(x) возвращает значение того же типа, что и выведено компилятором. Это полезно для проверки стабильности типа.
f(x) может быть любым выражением вызова. Возвращает результат f(x) если типы совпадают, и Error Result если обнаружит разные типы.
Необязательно, AllowedType ослабляет тест, сделав его проходящим, когда тип f(x) соответствует выведенному типу с учётом AllowedType, или когда возвращаемый тип является подтипом AllowedType. Это полезно при тестировании стабильности типа функций, возвращающих небольшое объединение типов, например Union{Nothing, T} или Union{Missing, T}.
julia> f(a) = a > 1 ? 1 : 1.0
f (generic function with 1 method)
julia> typeof(f(2))
Int64
julia> @code_warntype f(2)
MethodInstance for f(::Int64)
from f(a) in Main at none:1
Arguments
#self#::Core.Const(f)
a::Int64
Body::UNION{FLOAT64, INT64}
1 ─ %1 = (a > 1)::Bool
└── goto #3 if not %1
2 ─ return 1
3 ─ return 1.0
julia> @inferred f(2)
ERROR: return type Int64 does not match inferred return type Union{Float64, Int64}
[...]
julia> @inferred max(1, 2)
2
julia> g(a) = a < 10 ? missing : 1.0
g (generic function with 1 method)
julia> @inferred g(20)
ERROR: return type Float64 does not match inferred return type Union{Missing, Float64}
[...]
julia> @inferred Missing g(20)
1.0
julia> h(a) = a < 10 ? missing : f(a)
h (generic function with 1 method)
julia> @inferred Missing h(20)
ERROR: return type Int64 does not match inferred return type Union{Missing, Float64, Int64}
[...]
Test.@test_deprecatedМакрос
@test_deprecated [pattern] expression
Если --depwarn=yes, проверит, что expression генерирует предупреждение о устаревании и возвращает значение expression. Строка сообщения журнала будет сопоставлена со значением pattern, которое по умолчанию равно r"deprecated"i.
Если --depwarn=no, просто верните результат выполнения expression. Если --depwarn=error, проверьте, что будет выброшено исключение ErrorException.
Примеры
# Deprecated in julia 0.7 @test_deprecated num2hex(1) # The returned value can be tested by chaining with @test: @test (@test_deprecated num2hex(1)) == "0000000000000001"
Test.@test_warnМакрос
@test_warn msg expr
Проверяет, приводит ли вычисление expr к выводу в stderr, который содержит строку msg или соответствует регулярному выражению msg. Если msg — это булево выражение, проверяет, возвращает ли msg(output) значение true. Если msg — это кортеж или массив, проверяет, что вывод об ошибке содержит/соответствует каждому элементу в msg. Возвращает результат вычисления expr.
См. также @test_nowarn для проверки отсутствия вывода об ошибке.
Примечание: Предупреждения, сгенерированные @warn не могут быть проверены с помощью этого макроса. Используйте @test_logs вместо этого.
Test.@test_nowarnМакрос
@test_nowarn expr
Проверяет, приводит ли вычисление expr к пустому выводу в stderr (нет предупреждений или других сообщений). Возвращает результат вычисления expr.
Примечание: Отсутствие предупреждений, сгенерированных @warn не может быть проверено с помощью этого макроса. Используйте @test_logs вместо этого.
Неисправные тесты
Если тест последовательно терпит неудачу, его можно изменить с помощью макроса @test_broken. Это обозначит тест как Broken , если тест продолжает терпит неудачу, и оповестит пользователя с помощью Error , если тест пройден.
Test.@test_brokenМакрос
@test_broken ex @test_broken f(args...) key=val ...
Указывает на тест, который должен пройти, но в настоящее время последовательно терпит неудачу. Проверяет, что выражение ex вычисляется до false или вызывает исключение. Возвращает Broken Result если это так, или Error Result , если выражение вычисляется до true. Это эквивалентно @test ex broken=true.
Форма @test_broken f(args...) key=val... работает аналогично макросу @test.
Примеры
julia> @test_broken 1 == 2 Test Broken Expression: 1 == 2 julia> @test_broken 1 == 2 atol=0.1 Test Broken Expression: ==(1, 2, atol = 0.1)
Также доступен @test_skip, чтобы пропустить тест без оценки, но учитывая пропущенный тест в отчёте о тестировании. Тест не будет выполнен, но выдаст Broken Result.
Test.@test_skipМакрос
@test_skip ex @test_skip f(args...) key=val ...
Помечает тест, который не должен выполняться, но должен быть включён в отчёт о тестировании как Broken. Это может быть полезно для тестов, которые периодически терпят неудачу, или для тестов ещё не реализованной функциональности. Это эквивалентно @test ex skip=true.
Форма @test_skip f(args...) key=val... работает аналогично макросу @test.
Примеры
julia> @test_skip 1 == 2 Test Broken Skipped: 1 == 2 julia> @test_skip 1 == 2 atol=0.1 Test Broken Skipped: ==(1, 2, atol = 0.1)
Создание пользовательских типов AbstractTestSet
Пакеты могут создавать собственные подтипы AbstractTestSet путём реализации методов record и finish. Подтип должен иметь конструктор с одним аргументом, принимающим строку описания, а все опции передаются в виде ключевых аргументов.
Test.recordФункция
record(ts::AbstractTestSet, res::Result)
Записывает результат в тестовый набор. Эта функция вызывается инфраструктурой @testset каждый раз, когда завершается содержащий @test макрос, и получает результат теста (который может быть Error). Она также будет вызвана с Error если во время выполнения блока теста будет выброшено исключение вне контекста @test.
Test.finishФункция
finish(ts::AbstractTestSet)
Выполните все необходимые окончательные обработки для данного набора тестов. Это вызывается инфраструктурой @testset после выполнения блока тестов.
Пользовательские подтипы AbstractTestSet должны вызывать record у своего родительского элемента (если он есть), чтобы добавить себя в дерево результатов тестов. Это может быть реализовано следующим образом:
if get_testset_depth() != 0
# Attach this test set to the parent test set
parent_ts = get_testset()
record(parent_ts, self)
return self
endTest несет ответственность за поддержание стека вложенных наборов тестов по мере их выполнения, но любая аккумуляция результатов является обязанностью подтипа AbstractTestSet. Вы можете получить доступ к этому стеку с помощью методов get_testset и get_testset_depth. Обратите внимание, что эти функции не экспортируются.
Test.get_testsetФункция
get_testset()
Получить активный набор тестов из локального хранилища задачи. Если активного набора тестов нет, используется резервный набор тестов по умолчанию.
Test.get_testset_depthФункция
get_testset_depth()
Возвращает количество активных наборов тестов, не включая набор тестов по умолчанию.
Test также гарантирует, что вложенные вызовы @testset используют тот же подтип AbstractTestSet , что и их родительский элемент, если явно не указан другой. Он не распространяет никаких свойств набора тестов. Поведение наследования опций может быть реализовано пакетами, использующими инфраструктуру стека, которую предоставляет Test.
Определение базового подтипа AbstractTestSet может выглядеть так:
import Test: Test, record, finish
using Test: AbstractTestSet, Result, Pass, Fail, Error
using Test: get_testset_depth, get_testset
struct CustomTestSet <: Test.AbstractTestSet
description::AbstractString
foo::Int
results::Vector
# constructor takes a description string and options keyword arguments
CustomTestSet(desc; foo=1) = new(desc, foo, [])
end
record(ts::CustomTestSet, child::AbstractTestSet) = push!(ts.results, child)
record(ts::CustomTestSet, res::Result) = push!(ts.results, res)
function finish(ts::CustomTestSet)
# just record if we're not the top-level parent
if get_testset_depth() > 0
record(get_testset(), ts)
end
ts
end
Использование этого набора тестов выглядит следующим образом:
@testset CustomTestSet foo=4 "custom testset inner 2" begin
# this testset should inherit the type, but not the argument.
@testset "custom testset inner" begin
@test true
end
end
Утилиты тестирования
Test.GenericArrayТип
GenericArray может использоваться для тестирования общих API массивов, ориентированных на интерфейс AbstractArray, чтобы убедиться, что функции могут работать с типами массивов помимо стандартного типа Array.
Test.GenericDictТип
GenericDict может использоваться для тестирования общих API словарей, ориентированных на интерфейс AbstractDict, чтобы убедиться, что функции могут работать с ассоциативными типами помимо стандартного типа Dict.
Test.GenericOrderТип
GenericOrder может использоваться для тестирования API, поддерживающих общие упорядоченные типы.
Test.GenericSetТип
GenericSet может использоваться для тестирования общих API множеств, ориентированных на интерфейс AbstractSet, чтобы убедиться, что функции могут работать с типами множеств помимо стандартных типов Set и BitSet.
Test.GenericStringТип
GenericString может использоваться для тестирования общих API строк, ориентированных на интерфейс AbstractString, чтобы убедиться, что функции могут работать со строковыми типами помимо стандартного типа String.
Test.detect_ambiguitiesФункция
detect_ambiguities(mod1, mod2...; recursive=false,
ambiguous_bottom=false,
allowed_undefineds=nothing)
Возвращает вектор пар (Method,Method) неопределенных методов, определенных в указанных модулях. Используйте recursive=true для тестирования во всех подмодулях.
ambiguous_bottom управляет включением в результат только тех неопределённостей, которые вызваны параметрами типа Union{}; в большинстве случаев вы, вероятно, захотите установить это значение в false. Смотрите Base.isambiguous.
См. Test.detect_unbound_args для объяснения allowed_undefineds.
allowed_undefineds требует по крайней мере Julia 1.8.
Test.detect_unbound_argsФункция
detect_unbound_args(mod1, mod2...; recursive=false, allowed_undefineds=nothing)
Возвращает вектор Method , которые могут иметь неопределенные типы параметров. Используйте recursive=true для тестирования во всех подмодулях.
По умолчанию любые неопределенные символы вызывают предупреждение. Это предупреждение можно подавить, указав коллекцию GlobalRef , для которых можно пропустить предупреждение. Например, установка
allow_undefineds = Set([GlobalRef(Base, :active_repl),
GlobalRef(Base, :active_repl_backend)])
позволила бы подавить предупреждения о Base.active_repl и Base.active_repl_backend.
allowed_undefineds требует по крайней мере Julia 1.8.
© 2009–2022 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.8/stdlib/Test/