サーチ…


構文

  • @test [expr]
  • @test_throws [例外] [expr]
  • @testset "[name]" begin; [テスト];終わり
  • Pkg.test([package])

備考

Base.Testの標準ライブラリー資料には、これらの例に示されている以上の追加資料が含まれています。

パッケージのテスト

パッケージの単体テストを実行するには、 Pkg.test関数を使用します。 MyPackageという名前のパッケージの場合、コマンドは次のようになります。

julia> Pkg.test("MyPackage")

期待される出力は次のようになります。

INFO: Computing test dependencies for MyPackage...
INFO: Installing BaseTestNext v0.2.2
INFO: Testing MyPackage
Test Summary: | Pass  Total
  Data        |   66     66
Test Summary: | Pass  Total
  Monetary    |  107    107
Test Summary: | Pass  Total
  Basket      |   47     47
Test Summary: | Pass  Total
  Mixed       |   13     13
Test Summary: | Pass  Total
  Data Access |   35     35
INFO: MyPackage tests passed
INFO: Removing BaseTestNext v0.2.2

明らかに、異なるパッケージが異なるフレームワークを使用するため、上記と正確に一致するとは期待できません。

このコマンドは、クリーンな環境でパッケージのtest/runtests.jlファイルを実行します。

インストールされたすべてのパッケージを一度にテストできます。

julia> Pkg.test()

しかし、これは通常、非常に長い時間がかかります。

簡単なテストの作成

ユニットテストはパッケージ内のtest/runtests.jlファイルで宣言されています。通常、このファイルは

using MyModule
using Base.Test

テストの基本単位は@testマクロです。このマクロは一種のアサーションのようなものです。ブール式は@testマクロでテストできます:

@test 1 + 1 == 2
@test iseven(10)
@test 9 < 10 || 10 < 9

私たちはREPLで@testマクロを試すことができます:

julia> using Base.Test

julia> @test 1 + 1 == 2
Test Passed
  Expression: 1 + 1 == 2
   Evaluated: 2 == 2

julia> @test 1 + 1 == 3
Test Failed
  Expression: 1 + 1 == 3
   Evaluated: 2 == 3
ERROR: There was an error during testing
 in record(::Base.Test.FallbackTestSet, ::Base.Test.Fail) at ./test.jl:397
 in do_test(::Base.Test.Returned, ::Expr) at ./test.jl:281

テストマクロは、ループや関数など、どこからでも使用できます。

# For positive integers, a number's square is at least as large as the number
for i in 1:10
    @test i^2 ≥ i
end

# Test that no two of a, b, or c share a prime factor
function check_pairwise_coprime(a, b, c)
    @test gcd(a, b) == 1
    @test gcd(a, c) == 1
    @test gcd(b, c) == 1
end

check_pairwise_coprime(10, 23, 119)

テストセットの作成

0.5.0

バージョンv0.5では、テストセットは標準ライブラリのBase.Testモジュールに組み込まれており、 using Base.Testを使用する以外に特別な操作を行う必要はありません。

0.4.0

テストセットはJulia v0.4のBase.Testライブラリの一部ではありません。代わりに、あなたがする必要がREQUIRE BaseTestNextモジュールを、および追加using BaseTestNext 、あなたのファイルに。バージョン0.4と0.5の両方をサポートするには、

if VERSION ≥ v"0.5.0-dev+7720"
    using Base.Test
else
    using BaseTestNext
    const Test = BaseTestNext
end

関連する@testテストセットにまとめると@testです。より明確なテスト構成に加えて、テストセットはより良い出力とカスタマイズ性を提供します。

テストセットを定義するには、任意の数の@test@testsetブロックで@testsetます:

@testset "+" begin
    @test 1 + 1 == 2
    @test 2 + 2 == 4
end

@testset "*" begin
    @test 1 * 1 == 1
    @test 2 * 2 == 4
end

これらのテスト・セットを実行すると、次の出力が出力されます。

Test Summary: | Pass  Total
  +           |    2      2

Test Summary: | Pass  Total
  *           |    2      2

テストセットに失敗したテストが含まれていても、テストセット全体が完了して実行され、失敗が記録され、レポートされます。

@testset "-" begin
    @test 1 - 1 == 0
    @test 2 - 2 == 1
    @test 3 - () == 3
    @test 4 - 4 == 0
end

このテストセットを実行すると、

-: Test Failed
  Expression: 2 - 2 == 1
   Evaluated: 0 == 1
 in record(::Base.Test.DefaultTestSet, ::Base.Test.Fail) at ./test.jl:428
    ...
-: Error During Test
  Test threw an exception of type MethodError
  Expression: 3 - () == 3
  MethodError: no method matching -(::Int64, ::Tuple{})
    ...
Test Summary: | Pass  Fail  Error  Total
  -           |    2     1      1      4
ERROR: Some tests did not pass: 2 passed, 1 failed, 1 errored, 0 broken.
    ...

テストセットはネストすることができ、任意の深い組織

@testset "Int" begin
    @testset "+" begin
        @test 1 + 1 == 2
        @test 2 + 2 == 4
    end
    @testset "-" begin
        @test 1 - 1 == 0
    end
end

テストに合格すると、最も外側のテストセットの結果のみが表示されます。

Test Summary: | Pass  Total
  Int         |    3      3

しかし、テストが失敗すると、正確なテストセットへのドリルダウンと失敗を引き起こすテストが報告されます。

@testsetマクロはforループと共に使用して、一度に多くのテストセットを作成できます。

@testset for i in 1:5
    @test 2i == i + i
    @test i^2 == i * i
    @test i ÷ i == 1
end

報告書

Test Summary: | Pass  Total
  i = 1       |    3      3
Test Summary: | Pass  Total
  i = 2       |    3      3
Test Summary: | Pass  Total
  i = 3       |    3      3
Test Summary: | Pass  Total
  i = 4       |    3      3
Test Summary: | Pass  Total
  i = 5       |    3      3

一般的な構造は、外部テストでテストコンポーネントまたはタイプを設定することです。これらの外部テストセット内で、内部テストはテスト動作を設定します。たとえば、すべてを含むシングルトンインスタンスを持つUniversalSet型を作成したとします。型を実装する前に、 テスト駆動開発原則を使用してテストを実装することができます。

@testset "UniversalSet" begin
    U = UniversalSet.instance
    @testset "egal/equal" begin
        @test U === U
        @test U == U
    end

    @testset "in" begin
        @test 1 in U
        @test "Hello World" in U
        @test Int in U
        @test U in U
    end

    @testset "subset" begin
        @test Set() ⊆ U
        @test Set(["Hello World"]) ⊆ U
        @test Set(1:10) ⊆ U
        @test Set([:a, 2.0, "w", Set()]) ⊆ U
        @test U ⊆ U
    end
end

その後、テストに合格するまで機能を実装することができます。最初のステップは、タイプを定義することです:

immutable UniversalSet <: Base.AbstractSet end

私たちのテストのうち2つだけが今すぐ通過します。私たちは以下を実装inことができます:

immutable UniversalSet <: Base.AbstractSet end
Base.in(x, ::UniversalSet) = true

これはまた、私たちのサブセットテストのいくつかを合格させます。しかし、fallbackは要素に対して反復しようとするため、 issubset )fallbackはUniversalSetでは機能しません。すべてのセットに対してissubset trueに戻す特殊化を定義することは簡単です。

immutable UniversalSet <: Base.AbstractSet end
Base.in(x, ::UniversalSet) = true
Base.issubset(x::Base.AbstractSet, ::UniversalSet) = true

そして、今、私たちのテストはすべてパスします!

例外のテスト

テストの実行中に発生した例外はテストに失敗し、テストがテストセットに含まれていない場合は、テストエンジンを終了します。ほとんどの場合、例外は望ましい結果ではないため、通常、これは良いことです。しかし、時には、特定の例外が発生したことを具体的にテストしたい場合もあります。 @test_throwsマクロはこれを容易にします。

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

間違った例外がスローされた場合、 @test_throwsは失敗します。

julia> @test_throws TypeError [1, 2, 3][4]
Test Failed
  Expression: ([1,2,3])[4]
    Expected: TypeError
      Thrown: BoundsError
ERROR: There was an error during testing
 in record(::Base.Test.FallbackTestSet, ::Base.Test.Fail) at ./test.jl:397
 in do_test_throws(::Base.Test.Threw, ::Expr, ::Type{T}) at ./test.jl:329

例外がスローされない場合、 @test_throwsも失敗します:

julia> @test_throws BoundsError [1, 2, 3, 4][4]
Test Failed
  Expression: ([1,2,3,4])[4]
    Expected: BoundsError
  No exception thrown
ERROR: There was an error during testing
 in record(::Base.Test.FallbackTestSet, ::Base.Test.Fail) at ./test.jl:397
 in do_test_throws(::Base.Test.Returned, ::Expr, ::Type{T}) at ./test.jl:329

浮動小数点の近似等価のテスト

次のような取引は何ですか?

julia> @test 0.1 + 0.2 == 0.3
Test Failed
  Expression: 0.1 + 0.2 == 0.3
   Evaluated: 0.30000000000000004 == 0.3
ERROR: There was an error during testing
 in record(::Base.Test.FallbackTestSet, ::Base.Test.Fail) at ./test.jl:397
 in do_test(::Base.Test.Returned, ::Expr) at ./test.jl:281

誤差は、のいずれことに起因する0.10.2 、及び0.3 -丁度それらの値としてコンピュータで表現される1//102//10 、及び3//10 。代わりに、それらは非常に近い値で近似されます。しかし、上のテストの失敗に見られるように、2つの近似を足し合わせると、結果は可能なものよりもわずかに悪い近似になる可能性があります。ここで扱うことができないこのテーマにはるかに多くがあります。

しかし、運が悪いわけではありません!浮動小数点数と浮動小数点演算への丸めの組み合わせがほぼ正確であることをテストするために、正確でない場合でもisapprox関数(演算子対応)を使用できます。だから私たちはテストを書き直すことができます

julia> @test 0.1 + 0.2 ≈ 0.3
Test Passed
  Expression: 0.1 + 0.2 ≈ 0.3
   Evaluated: 0.30000000000000004 isapprox 0.3

もちろん、もし私たちのコードが完全に間違っていたとしても、テストはそれを引き継いでいます:

julia> @test 0.1 + 0.2 ≈ 0.4
Test Failed
  Expression: 0.1 + 0.2 ≈ 0.4
   Evaluated: 0.30000000000000004 isapprox 0.4
ERROR: There was an error during testing
 in record(::Base.Test.FallbackTestSet, ::Base.Test.Fail) at ./test.jl:397
 in do_test(::Base.Test.Returned, ::Expr) at ./test.jl:281

isapprox関数は、浮動小数点型の数値と精度のサイズに基づいたヒューリスティックを使用して、許容されるエラーの量を決定します。これはすべての状況に適しているわけではありませんが、ほとんどの場合に機能し、独自のバージョンのisapprox実装するために多くの労力を節約します。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow