The Test submodule
Functions to help test implementations of MOI. See The Test submodule for more details.
MathOptInterface.Test.Config — TypeConfig(
::Type{T} = Float64;
atol::Real = Base.rtoldefault(T),
rtol::Real = Base.rtoldefault(T),
optimal_status::MOI.TerminationStatusCode = MOI.OPTIMAL,
infeasible_status::MOI.TerminationStatusCode = MOI.INFEASIBLE,
exclude::Vector{Any} = Any[],
) where {T}Return an object that is used to configure various tests.
Configuration arguments
atol::Real = Base.rtoldefault(T): Control the absolute tolerance used when comparing solutions.rtol::Real = Base.rtoldefault(T): Control the relative tolerance used when comparing solutions.optimal_status = MOI.OPTIMAL: Set toMOI.LOCALLY_SOLVEDif the solver cannot prove global optimality.infeasible_status = MOI.INFEASIBLE: Set toMOI.LOCALLY_INFEASIBLEif the solver cannot prove global infeasibility.exclude = Vector{Any}: Pass attributes or functions toexcludeto skip parts of tests that require certain functionality. Common arguments include:MOI.deleteto skip deletion-related testsMOI.optimize!to skip optimize-related testsMOI.ConstraintDualto skip dual-related testsMOI.VariableNameto skip setting variable namesMOI.ConstraintNameto skip setting constraint names
Example
For a nonlinear solver that finds local optima and does not support finding dual variables or constraint names:
julia> config = MOI.Test.Config(
Float64;
optimal_status = MOI.LOCALLY_SOLVED,
exclude = Any[
MOI.ConstraintDual,
MOI.VariableName,
MOI.ConstraintName,
MOI.delete,
],
);MathOptInterface.Test.runtests — Functionruntests(
model::MOI.ModelLike,
config::Config;
include::Vector{Union{String,Regex}} = String[],
exclude::Vector{Union{String,Regex}} = String[],
warn_unsupported::Bool = false,
exclude_tests_after::VersionNumber = v"999.0.0",
verbose::Bool = false,
test_module = MathOptInterface.Test,
)Run all tests in test_module, which defaults to MathOptInterface.Test, on model.
Configuration arguments
configis aTest.Configobject that can be used to modify the behavior of tests.- If
includeis not empty, only run tests if an element fromincludeoccursinthe name of the test. - If
excludeis not empty, skip tests if an element fromexcludeoccursinthe name of the test. excludetakes priority overinclude.- If
warn_unsupportedisfalse,runtestswill silently skip tests that fail with aMOI.NotAllowedError,MOI.UnsupportedError, orRequirementUnmeterror. (The latter is thrown when an@requiresstatement returnsfalse.) Whenwarn_unsupportedistrue, a warning will be printed. For most cases the default behavior,false, is what you want, since these tests likely test functionality that is not supported bymodel. However, it can be useful to runwarn_unsupported = trueto check you are not skipping tests due to a missingsupports_constraintmethod or equivalent. exclude_tests_afteris a version number that excludes any tests to MOI added after that version number. This is useful for solvers who can declare a fixed set of tests, and not cause their tests to break if a new patch of MOI is released with a new test.verboseis aBoolthat controls whether the name of the test is printed before executing it. This can be helpful when debugging.test_moduleis aModulewhere all the functions starting withtest_are considered as tests.
See also: setup_test.
Example
config = MathOptInterface.Test.Config()
MathOptInterface.Test.runtests(
model,
config;
include = ["test_linear_", r"^test_model_Name$"],
exclude = ["VariablePrimalStart"],
warn_unsupported = true,
verbose = true,
exclude_tests_after = v"0.10.5",
)MathOptInterface.Test.setup_test — Functionsetup_test(::typeof(f), model::MOI.ModelLike, config::Config)Overload this method to modify model before running the test function f on model with config. You can also modify the fields in config (for example, to loosen the default tolerances).
This function should either return nothing, or return a function which, when called with zero arguments, undoes the setup to return the model to its previous state. You do not need to undo any modifications to config.
This function is most useful when writing new tests of the tests for MOI, but it can also be used to set test-specific tolerances, etc.
See also: runtests
Example
function MOI.Test.setup_test(
::typeof(MOI.Test.test_linear_VariablePrimalStart_partial),
mock::MOIU.MockOptimizer,
::MOI.Test.Config,
)
MOIU.set_mock_optimize!(
mock,
(mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 0.0]),
)
mock.eval_variable_constraint_dual = false
function reset_function()
mock.eval_variable_constraint_dual = true
return
end
return reset_function
endMathOptInterface.Test.version_added — Functionversion_added(::typeof(function_name))Returns the version of MOI in which the test function_name was added.
This method should be implemented for all new tests.
See the exclude_tests_after keyword of runtests for more details.
MathOptInterface.Test.@requires — Macro@requires(x)Check that the condition x is true. Otherwise, throw an RequirementUnmet error to indicate that the model does not support something required by the test function.
Example
@requires MOI.supports(model, MOI.Silent())
@test MOI.get(model, MOI.Silent())MathOptInterface.Test.RequirementUnmet — TypeRequirementUnmet(msg::String) <: ExceptionAn error for throwing in tests to indicate that the model does not support some requirement expected by the test function.
MathOptInterface.Test.HS071 — TypeHS071(
enable_hessian::Bool,
enable_hessian_vector_product::Bool = false,
)An MOI.AbstractNLPEvaluator for the problem:
\[\begin{aligned} \text{min} \ & x_1 * x_4 * (x_1 + x_2 + x_3) + x_3 \\ \text{subject to}\ & x_1 * x_2 * x_3 * x_4 \ge 25 \\ & x_1^2 + x_2^2 + x_3^2 + x_4^2 = 40 \\ & 1 \le x_1, x_2, x_3, x_4 \le 5 \end{aligned}\]
The optimal solution is [1.000, 4.743, 3.821, 1.379].