Spec-Zone.ru › Julia 1.7

Тестирование юнит-уровня

Тестирование базовой 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 или в стандартных библиотеках перед запуском тестов. Если seed предоставлен в качестве ключевого аргумента, он используется для инициализации глобального генератора случайных чисел в контексте запуска тестов; в противном случае seed выбирается случайным образом.

исходный код

Основные юнит-тесты

Модуль Test предоставляет простую функциональность тестирования юнит-уровня. Юнит-тестирование — это способ проверки корректности вашего кода, проверяя, соответствуют ли результаты вашим ожиданиям. Это может быть полезно для обеспечения корректной работы кода после внесения изменений и может использоваться при разработке для описания поведения вашего кода после завершения разработки.

Простые юнит-тесты могут быть выполнены с помощью макросов @test и @test_throws.

Test.@testМакрос

@test ex
@test f(args...) key=val ...
@test ex broken=true
@test ex skip=true

Проверяет, что выражение ex вычисляется до значения true. Возвращает Pass Result, если это так, Fail Result, если это false, и Error Result, если его нельзя вычислить.

Примеры

julia> @test true
Test Passed
  Expression: true

julia> @test [1, 2] + [2, 1] == [3, 3]
Test Passed
  Expression: [1, 2] + [2, 1] == [3, 3]
   Evaluated: [3, 3] == [3, 3]

Форма @test f(args...) key=val... эквивалентна записи @test f(args..., key=val...), что может быть полезно, когда выражение является вызовом с использованием инфиксной синтаксической конструкции, например, приближенных сравнений:

julia> @test π ≈ 3.14 atol=0.01
Test Passed
  Expression: ≈(π, 3.14, atol = 0.01)
   Evaluated: ≈(π, 3.14; atol = 0.01)

Это эквивалентно более громоздкому тесту @test ≈(π, 3.14, atol=0.01). Недопустимо предоставлять более одного выражения, если первое не является выражением вызова, а остальные — присваиваниями (k=v).

Вы можете использовать любые ключи для аргументов key=val, за исключением broken и skip, которые имеют специальное значение в контексте @test:

  • broken=cond указывает тест, который должен пройти, но в настоящее время постоянно терпит неудачу при cond==true. Проверяет, что выражение ex вычисляется до значения false или вызывает исключение. Возвращает Broken Result если это так, или Error Result если выражение вычисляется до 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
  Expression: ≈(2 + 2, 5, atol = 1)
   Evaluated: ≈(4, 5; atol = 1)

julia> @test 2 + 2 == 5 skip=true
Test Broken
  Skipped: 2 + 2 == 5

julia> @test 2 + 2 == 4 skip=false
Test Passed
  Expression: 2 + 2 == 4
   Evaluated: 4 == 4

Ключевые аргументы broken и skip требуют по крайней мере Julia 1.7.

исходный код

Test.@test_throwsМакрос

@test_throws exception expr

Проверяет, что выражение expr вызывает исключение exception. Исключение может указывать либо тип, либо значение (которое будет проверено на равенство путем сравнения полей). Обратите внимание, что @test_throws не поддерживает форму с trailing ключевыми словами.

Примеры

julia> @test_throws BoundsError [1, 2, 3][4]
Test Passed
  Expression: ([1, 2, 3])[4]
      Thrown: BoundsError

julia> @test_throws DimensionMismatch [1, 2, 3] + [1, 2]
Test Passed
  Expression: [1, 2, 3] + [1, 2]
      Thrown: DimensionMismatch
исходный код

Например, предположим, что мы хотим проверить, что наша новая функция 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
  Expression: foo("bar") == 9
   Evaluated: 9 == 9

julia> @test foo("fizz") >= 10
Test Passed
  Expression: foo("fizz") >= 10
   Evaluated: 16 >= 10

Если условие ложно, возвращается 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
  Expression: foo(:cat)
      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

Начинает новый набор тестов или несколько наборов тестов, если предоставлен цикл for.

Если тип набора тестов не указан, по умолчанию создаётся DefaultTestSet. DefaultTestSet записывает все результаты и, если есть какие-либо Fail или Error выбрасывает исключение в конце верхнего уровня (не вложенного) набора тестов, вместе со сводным отчетом о результатах теста.

Любой пользовательский тип набора тестов (подтип AbstractTestSet) может быть указан, и он также будет использоваться для всех вложенных вызовов @testset. Указанные параметры применяются только к набору тестов, где они указаны. Тип набора тестов по умолчанию принимает логический параметр verbose: если true, сводный отчет результатов вложенных наборов тестов отображается даже при их успешном завершении (по умолчанию false).

Строка описания допускает интерполяцию из индексов цикла. Если описание не предоставлено, оно строится на основе переменных.

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

Перед выполнением тела @testset, происходит неявный вызов Random.seed!(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
trigonometric identities |    4      4
исходный код

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
Foo Tests     |    3      3

Наборы тестов также могут быть вложены:

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
Foo Tests     |    8      8

В случае, если вложенный набор тестов не содержит ошибок, как произошло здесь, он будет скрыт в сводном отчете, если не задан параметр 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
Foo Tests     |    8      8
  Animals     |    2      2
  Arrays 1    |    2      2
  Arrays 2    |    2      2
  Arrays 3    |    2      2

Если у нас есть ошибки в тестах, будут показаны только подробности о неудачных наборах тестов:

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
Foo Tests     |    3     1      4
  Animals     |    2            2
  Arrays      |    1     1      2
ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken.

Другие макросы тестов

Поскольку вычисления с плавающей точкой могут быть неточными, вы можете выполнить проверки приблизительного равенства, используя либо @test a ≈ b (где ≈, набираемый через автодополнение \approx, — функция isapprox) или непосредственно использовать isapprox.

julia> @test 1 ≈ 0.999999999
Test Passed
  Expression: 1 ≈ 0.999999999
   Evaluated: 1 ≈ 0.999999999

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
  Expression: ≈(1, 0.999999, rtol = 1.0e-5)
   Evaluated: ≈(1, 0.999999; rtol = 1.0e-5)

Обратите внимание, что это не особая функция ≈, а общая функция макроса @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_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:

@test_logs (:info,"Doing foo with n=2") (:debug,"Iteration 1") (:debug,"Iteration 2") min_level=Logging.Debug foo(2)

Если вы хотите протестировать, что некоторые определенные сообщения генерируются, игнорируя остальные, вы можете установить ключевое слово match_mode=:any:

@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.@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 в случае неудачи. Это эквивалентно @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
end
исходный код

Test несёт ответственность за поддержание стека вложенных наборов тестов по мере их выполнения, но любая аккумуляция результатов является ответственностью подтипа 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)

Возвращает вектор пар (Method,Method) неоднозначных методов, определенных в указанных модулях. Используйте recursive=true для тестирования во всех подмодулях.

ambiguous_bottom управляет включением неоднозначностей, возникающих только из-за Union{} параметров типа; в большинстве случаев вы, вероятно, захотите установить это значение в false. См. Base.isambiguous.

исходный код

Test.detect_unbound_argsФункция

detect_unbound_args(mod1, mod2...; recursive=false)

Возвращает вектор Method которые могут иметь свободные параметры типа. Используйте recursive=true для тестирования во всех подмодулях.

исходный код

© 2009–2021 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.7.0/stdlib/Test/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API