2015-03-06 4 views
6

चलो इस सरल परीक्षण कोड पर विचार करें।गो परीक्षण आउटपुट में लाइन नंबर कैसे ठीक करें?

(नोट:। assertSomething यहां सुपर सरल है, लेकिन आम तौर पर मुझे लगता है कि कई चीजों पर विचार करेंगे और त्रुटि के एक से अधिक प्रकार की रिपोर्ट कर सकता है हाथ में इस काम के लिए एक और अधिक विशिष्ट सहायक लिखना चाहते हैं)

:

--- FAIL: TestFoo (0.00s) 
    hello.go:12: Something's not right 
FAIL 
exit status 1 
FAIL kos/hello 0.008s 

मैं दो प्रश्न हैं:

package hello 

import "testing" 

func TestFoo(t *testing.T) { 
    assertSomething(t, 2+2 == 4) // line 6 
    assertSomething(t, 2+3 == 6) // line 7 
} 

func assertSomething(t *testing.T, expected bool) { 
    if !expected { 
     t.Error("Something's not right") // line 12 
    } 
} 

जब मैं go test चलाने के लिए, मैं निम्नलिखित मिल

1) त्रुटि पंक्ति 12 को इंगित करती है - क्यों? t.Error कैसे पता लगाता है कि इसे किस लाइन से बुलाया गया था?

2) सहायक में, मुझे लगता है कि t.Error ढेर स्तर उच्च देखने के मुद्रित करने के लिए लाइन संख्या निर्धारित करने के निर्दिष्ट करने के लिए, ताकि मैं इस तरह एक संदेश प्राप्त होगा चाहते हैं:

--- FAIL: TestFoo (0.00s) 
    hello.go:7: Something's not right 

अजगर की अनुमति देता है उदाहरण के लिए, warnings.warn("message", stacklevel=2) में मैं इसे समकक्ष कैसे कार्यान्वित करूं?

+0

जहां तक ​​1 का संबंध है, यह संभवतः [runtime.Caller] (http://godoc.org/runtime#Caller) का उपयोग इस उद्देश्य के लिए करता है। कुछ स्तरों पर जाने के लिए 'छोड़ें' के लिए एक अलग संख्या की आपूर्ति करें। मुझे यकीन नहीं है कि आप परीक्षण पैकेज कोड को बदले बिना ऐसा करने के लिए 'test.XXX' बता सकते हैं। – jimt

उत्तर

12

आप कर सकते हैं जो आप पूछ रहे हैं, और आप यह पता लगा सकते हैं कि t.Errorlooking at the source code द्वारा काम करता है। फ़ंक्शन decorate वह है जो आप ढूंढ रहे हैं मुझे लगता है।

लेकिन, जहां आपके पास जांच कोड की महत्वपूर्ण मात्रा है, और किसी कारण से यह आपके परीक्षण में डुप्लिकेट हो रहा है, तो इसे एक ऐसे कार्य के रूप में निकालना बेहतर होगा जो परीक्षण में गुजरने से त्रुटि उत्पन्न करता है। और बनाना यह एक "दावा" है। दरअसल, लेखन कार्यों को स्पष्ट रूप से भाषा FAQ में निराश किया जाता है।

package hello 

import "testing" 

func TestFoo(t *testing.T) { 
    if err := checkSomething(2+2 == 4); err != nil { 
     t.Errorf("2+2=4 failed: %s", err) 
    } 
    if err := checkSomething(2+3 == 6); err != nil { 
     t.Errorf("2+3=6 failed: %s", err) 
    } 
} 

func checkSomething(v bool) error { 
    if !v { 
     return errors.New("something's not right") 
    } 
    return nil 
} 

लेकिन मुझे लगता है कि मुहावरेदार परीक्षण कोड कैसा दिखता है। यह टेबल-संचालित है, और मामलों में इनपुट और अपेक्षित आउटपुट शामिल है, जिससे परीक्षण विफल होने पर वास्तव में त्रुटि संदेशों को स्पष्ट किया जाता है।

package hello 

import "testing" 

func TestFoo(t *testing.T) { 
    cases := []struct { 
     a, b, want int 
    }{ 
     {2, 2, 4}, 
     {2, 3, 6}, 
    } 
    for _, c := range cases { 
     if got := operation(c.a, c.b); got != c.want { 
      t.Errorf("operation(%d, %d) = %d, want %d", c.a, c.b, got, c.want) 
     } 
    } 
} 

func operation(a, b int) int { 
    return a + b 
} 
+0

वाह, धन्यवाद। और स्टेटफुल एसिंक कोड का परीक्षण करने के लिए, क्या एक चैनल में कुछ डालने की तुलना में एक और मूर्खतापूर्ण दृष्टिकोण है, मान लीजिए कि किसी अन्य चैनल पर कुछ है, दोहराएं "? कोई भी उदाहरण मैं देख सकता हूं? मुझे नहीं लगता कि मैं उस टेबल-संचालित को लिख सकता हूं। – Kos

+0

हां, अधिक जटिल परीक्षण सहायक (दावा नहीं) उपयोगी हैं और उन एफएक्यू एंट्री में दस्तावेज किए गए बिल्कुल कारणों के लिए कॉल स्तर को समायोजित करने की आवश्यकता है - यदि वे एकाधिक चेक करते हैं, तो वे कई विफलताओं को जोड़ने में सक्षम होना चाहिए। कॉल साइट जोड़ने के लिए जादू दुर्भाग्यवश एक अप्रत्याशित सहायक (सजावट विधि) में दफन किया गया है, इसलिए इस सुविधा को जोड़ने के लिए डुप्लिकेशंस या वैकल्पिक परीक्षण लाइब्रेरी का उचित हिस्सा आवश्यक है। एक उदाहरण के रूप में, आप एक इंटरफेस को लागू करने वाली कई वस्तुओं पर परीक्षणों की एक ही श्रृंखला को दोहराना चाह सकते हैं – stub

संबंधित मुद्दे