Julia Language
इकाई का परीक्षण
खोज…
वाक्य - विन्यास
- @test [expr]
- @test_throws [अपवाद] [expr]
- @testset "[नाम]" शुरू; [परीक्षण]; समाप्त
- Pkg.test ([पैकेज])
टिप्पणियों
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
मैक्रो को @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)
टेस्ट सेट लिखना
संस्करण v0.5 में, परीक्षण सेट मानक पुस्तकालय Base.Test
मॉड्यूल में बनाए गए हैं, और आपको using Base.Test
करने के लिए कुछ विशेष ( using Base.Test
का उपयोग करने के अलावा) करने की आवश्यकता नहीं है।
टेस्ट सेट जूलिया v0.4 के Base.Test
लाइब्रेरी का हिस्सा नहीं हैं। इसके बजाय, आपको BaseTestNext
मॉड्यूल की REQUIRE
है, और अपनी फ़ाइल के लिए using 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
लिए सहायक है। स्पष्ट परीक्षण संगठन के अलावा, परीक्षण सेट बेहतर आउटपुट और अधिक कस्टमाइज़ेबिलिटी प्रदान करते हैं।
एक परीक्षण सेट को परिभाषित करने के लिए, बस @testset
ब्लॉक के साथ @test
s की किसी भी संख्या को @test
:
@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
अभी हमारे दो परीक्षण पास हुए हैं। हम लागू कर सकते हैं in
:
immutable UniversalSet <: Base.AbstractSet end
Base.in(x, ::UniversalSet) = true
यह हमारे कुछ सबसेट परीक्षणों को भी पास कर देता है। हालाँकि, issubset
( ⊆
) फ़ॉलबैक 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.1
, 0.2
, और 0.3
कोई भी उन मानों के रूप में प्रतिनिधित्व नहीं करता है - 1//10
, 2//10
, और 3//10
। इसके बजाय, वे उन मूल्यों से अनुमानित होते हैं जो बहुत करीब हैं। लेकिन जैसा कि ऊपर परीक्षण विफलता में देखा गया है, जब दो सन्निकटन एक साथ जोड़ते हैं, तो परिणाम संभव से थोड़ा बदतर सन्निकटन हो सकता है। इस विषय में और भी बहुत कुछ है जिसे यहाँ नहीं कवर किया जा सकता है।
लेकिन हम किस्मत से बाहर नहीं हैं! यह जांचने के लिए कि फ्लोटिंग पॉइंट नंबर और फ़्लोटिंग पॉइंट अंकगणित के गोलाई का संयोजन लगभग सही है, भले ही सटीक न हो, हम 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
।