2013-02-12 7 views
9

क्या स्कैलाटेस्ट परीक्षण के भीतर से वर्तमान में निष्पादन परीक्षण के नाम तक पहुंच बनाना संभव है? (और मैं इसे कैसे करना होगा?)अंदरूनी परीक्षण से स्कैलाटेस्ट टेस्ट नाम एक्सेस करें?

पृष्ठभूमि:

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

उदाहरण:

(http://www.artima.com/docs-scalatest-2.0.M5/#org.scalatest.FreeSpec मैं किसी भी मालूम होता है प्रासंगिक समारोह यहां नहीं मिला):

"QuotaCharger can" - { 
    "charge and decline quota consumers" - { 

     "charge a per site IP number (guest user)" in { 
     // ... Here, a guest user post very many comments until it's over quota. 
     // This takes a little while, and there are many similar tests. 

     // ---> Here <--- I'd like to access the string: 
     // "charge a per site IP number (guest user)", 
     // is that possible somehow? 
     } 

उत्तर

8

ऐसा करने का इच्छित तरीका है मिश्रण के साथ ओवरराइड करना और परीक्षण डेटा कैप्चर करना। इस उपयोग के मामले में, फ़िक्स्चर में फ़िक्स्चर के साथ ओवरराइड करना बेहतर है। फ्रीस्पेक ताकि आप एक var का उपयोग करने के बजाय परीक्षण डेटा को प्रत्येक परीक्षण में पास कर सकें। कि की जानकारी यहां है:

http://www.artima.com/docs-scalatest-2.0.M5/org/scalatest/FreeSpec.html#withFixtureNoArgTest

जब मैं आज सुबह मुझे एहसास हुआ ScalaTest एक विशेषता है कि यह करता है होना चाहिए अपने प्रश्न को देखा, तो मैं बस एक जोड़ा। यह 2.0.एम 6 में होगा, अगली मील का पत्थर रिलीज होगा, लेकिन इस बीच आप स्थानीय प्रतिलिपि का उपयोग कर सकते हैं। संदेश यह है:

import org.scalatest._ 

/** 
* Trait that when mixed into a <code>fixture.Suite</code> passes the 
* <code>TestData</code> passed to <code>withFixture</code> as a fixture into each test. 
* 
* @author Bill Venners 
*/ 
trait TestDataFixture { this: fixture.Suite => 

    /** 
    * The type of the fixture, which is <code>TestData</code>. 
    */ 
    type FixtureParam = TestData 

    /** 
    * Invoke the test function, passing to the the test function to itself, because 
    * in addition to being the test function, it is the <code>TestData</code> for the test. 
    * 
    * <p> 
    * To enable stacking of traits that define <code>withFixture(NoArgTest)</code>, this method does not 
    * invoke the test function directly. Instead, it delegates responsibility for invoking the test function 
    * to <code>withFixture(NoArgTest)</code>. 
    * </p> 
    * 
    * @param test the <code>OneArgTest</code> to invoke, passing in the 
    * <code>TestData</code> fixture 
    */ 
    def withFixture(test: OneArgTest) { 
    withFixture(test.toNoArgTest(test)) 
    } 
} 

आप इस तरह यह प्रयोग करेंगे:

import org.scalatest._ 

class MySpec extends fixture.FreeSpec with TestDataFixture { 
    "this technique" - { 
    "should work" in { td => 
     assert(td.name == "this technique should work") 
    } 
    "should be easy" in { td => 
     assert(td.name == "this technique should be easy") 
    } 
    } 
} 
+0

मुझे लगता है कि मैं 'def currentTestName: स्ट्रिंग' दृष्टिकोण वास्तव में पसंद करता हूं, कि आप किसी भी पैरामीटर को पास किए बिना कहीं से भी एक्सेस कर सकते हैं (और केवल डिबगिंग उद्देश्यों के लिए फ़ंक्शन हस्ताक्षर संशोधित कर सकते हैं)। मेरे दृष्टिकोण से, परीक्षण का नाम वास्तव में परीक्षण का हिस्सा नहीं है - यह केवल डीबगिंग जानकारी है। लेकिन जब यह परीक्षण ('td => ') के पैरामीटर के रूप में प्रकट होता है तो यह परीक्षण का हिस्सा प्रतीत होता है। – KajMagnus

+1

क्या होगा यदि आपका परीक्षण "वास्तविक" स्थिरता पैरामीटर लेता है? फिर या तो आपको प्रत्येक टेस्ट में 2 पैरामीटर स्वीकार करने की आवश्यकता होगी? {केस (टीडी, realTestData) => ...} में '" परीक्षण नाम "। या शायद परीक्षण में 'realTestData' पास करना भी संभव नहीं होगा? चूंकि परीक्षण में पारित एकमात्र पैरामीटर वह होगा जो परीक्षण नाम (डीबगिंग उद्देश्यों के लिए) प्रदान करता है। – KajMagnus

+0

खैर, ध्यान रखें कि currentTestName केवल तभी काम करता है जब परीक्षण अनुक्रमिक रूप से चलते हैं, जो तब तक सत्य होगा जब तक आप समानांतर परीक्षण निष्पादन में मिश्रण न करें। उस स्थिति में, आप नियमित फ्रीस्पेक में फ़िक्स्चर के साथ बस एक var सेट कर सकते हैं। यदि परीक्षण अनुक्रमिक रूप से निष्पादित किए जाते हैं, तो टोपी दृष्टिकोण भी काम करेगा, और यह अस्थायी रूप से डीबगिंग के लिए कम घुसपैठ करता है। मैं मान रहा था कि यह हमेशा के लिए वहां जा रहा था। –

2

अपनी खुद की विशेषता बनाएँ, कहते हैं कि RichFreeSpec करते हैं।

trait RichFreeSpec extends Free { 
    protected final class RichFreeSpecStringWrapper(name: scala.Predef.String) { 
    def in(f: String => scala.Unit) { 
     def f2 = f(name) 
     new WordSpecStringWrapper(string).in(f2) 
    } 
    } 

    protected implicit def convertToRichFreeSpecStringWrapper(n: scala.Predef.String): = { 
    new RichFreeSpecStringWrapper(n) 
    } 
} 

बस से उपयोग करें:

"sth" in { testName => 
    ... 
} 

बेशक, आप आगे जाकर पूरा नाम पदानुक्रम लागू कर सकते हैं।

+0

धन्यवाद! दरअसल यह काम नहीं करता था: प्रत्येक बार {...} 'रनों में' नवीनतम परीक्षण नाम ", 'currentTestName' को" सबसे हालिया परीक्षण नाम "में बदल दिया जाता है, और जब वास्तविक परीक्षण ब्लॉक (' {.. के अंदर .. ।} ') चलता है, 'currentTestName' हमेशा वही होता है, अर्थात्' "सबसे हालिया परीक्षण नाम" '। – KajMagnus

+0

आपके उत्तर के लिए धन्यवाद, मुझे प्रासंगिक कक्षाएं मिलीं और कुछ के साथ आ सकता है :-) इसलिए +1, क्योंकि उत्तर उपयोगी था। (... मैं 2 दिनों के बाद अपना जवाब स्वीकार करूंगा (कुछ सीमा)) – KajMagnus

+0

मेरी गलती के लिए खेद है। फिक्स्ड। – Jakozaur

1

यहां एक समाधान है। FreeSpec के बजाय इस वर्ग को बढ़ाएं। लाइसेंस: CC0

संपादित करें: यह समवर्ती परीक्षणों के साथ काम नहीं करता है।

(इस दृष्टिकोण और दूसरे उत्तर के बीच का अंतर यह है कि 1) यहां currentTestName फ़ील्ड है, और दूसरे उत्तर में परीक्षण नाम परीक्षण निकाय को पास किया जाता है, और 2) इस परीक्षण नाम में सभी परीक्षण शामिल हैं शाखा के नाम वास्तविक परीक्षा नाम + concatenated, जबकि अन्य जवाब के परीक्षण नाम ठीक वैसे ही परीक्षण का नाम (परीक्षण शाखा के नाम के बिना) है।)

(ओह, आप मेरी प्यारी getOrDie के बजाय getOrElse ... उपयोग करने की आवश्यकता होगी।)

/** 
* Adds a field `currentTestName` that you can use inside a FreeSpec test, 
* if you for example have many tests that take rather long, and you wonder 
* which one is currently running. 
*/ 
trait RichFreeSpec extends FreeSpec { 

    private var _currentTestName: Option[String] = None 
    def currentTestName = _currentTestName getOrDie "DwE90RXP2" 

    protected override def runTest(testName: String, args: org.scalatest.Args) { 
    _currentTestName = Some(testName) 
    super.runTest(testName, args) 
    } 
} 
संबंधित मुद्दे