मासिक अभिलेख: जनवरी 2014

गरीब आदमी जावास्क्रिप्ट में कैशिंग है

[TL;डॉ. संस्करण: async कॉल के परिणामों को संग्रहीत करने के लिए कुकीज़ का उपयोग करें; पिछले async कॉल का परिणाम तुरंत प्रस्तुत करना और फिर उन्हें पृष्ठ-लोड करने के बाद मान्य करें।]

मैं SharePoint इंट्रानेट साइट पर एक ग्राहक के लिए काम कि सुविधाओं कर दिया गया है, अन्य बातों के अलावा, एक stylized माध्यमिक नेवीगेशन जिसका मेनू विकल्पों के माध्यम से एक नियमित रूप से पुराने कस्टम सूची प्रबंधित कर रहे हैं।  विचार है कि ग्राहक को प्रभावित करने वाले या वैश्विक नेविगेशन द्वारा इसे बाहर डाल द्वारा प्रभावित किया जा रहा बिना "उनके" साइट मेनू नियंत्रण करने के लिए हो जाता है.

(वहाँ कुछ अविश्वसनीय रूप से एक CEWP कि बताते हैं कि कुछ सीएसएस और जे एस एक साइट के व्यवहार के बारे में लगभग सब कुछ मौलिक परिवर्तन करने के लिए लोड करता है, लेकिन है कि एक और पोस्ट के लिए किसी HTML फ़ाइल को जोड़ने के बारे में विध्वंसक है)

यह बहुत आसान के लिए कोड:

  • पेज लोड हो रहा है खत्म करो और एक async बाकी या lists.asmx या जो कुछ भी का उपयोग कर एक सूची से मेनू आइटम को लोड करने के लिए कॉल करने के लिए प्रतीक्षा करें
  • JQuery का उपयोग, गतिशील रूप से अगर एक गुच्छा आबाद <li>एक माता पिता के अंदर है <उल> (इस tecnnique की एक सरलीकृत विवरण के लिए ईसाई Pinder लेख यहाँ देखें)
  • सभी स्वरूपण करने के लिए सीएसएस का उपयोग करें
  • लाभ!

है गले में हाजिर यहाँ यह है कि हर बार किसी को भी साइट के पृष्ठों में से एक हिट, उस उपयोगकर्ता के वेब ब्राउज़र सूची से आइटम प्राप्त करने के लिए पहुँच रहा है।  एक बार देव पूरा हो गया है और परीक्षण किया जा करने के लिए बातें साबित हो गया है स्थिर और पूर्ण करें, इस कॉल अनावश्यक है अधिक से अधिक 99% समय के बाद से मेनू शायद ही कभी बदल जाता है।  यह भी एक अजीब UI प्रभावित इस बहादुर नई दुनिया में हाइपर ajaxy वेब साइटों की आम है जो है – पृष्ठ renders और केवल तब मेनू प्रदान करता है।  यह चिड़चिड़ा और मेरे विचार में ध्यान भंग है।  और चिड़चिड़ा. तो, कैशिंग। 

मैं तर्क thusly संशोधित:

  • यह देखो कि के रूप में मैं पिछले मेनू में होते हैं जो ब्राउज़र में एक कुकी के लिए पढ़ें
    • अगर पाया, यह तुरंत प्रस्तुत करना।  पेज लोडिंग समाप्त करने के लिए इंतजार मत करो।  (आप की जरूरत है अपने HTML रणनीतिक यहाँ रखा है यह सुनिश्चित करने के लिए, लेकिन ऐसा करना कठिन नहीं है).
  • पेज लोड हो रहा है खत्म करो और एक async बाकी या lists.asmx या जो कुछ भी का उपयोग कर एक सूची से मेनू आइटम को लोड करने के लिए कॉल करने के लिए प्रतीक्षा करें
  • क्या मैं कुकी के खिलाफ मिल गया की तुलना करें
    • यदि यह मैच, रुको
    • अन्यथा, jQuery का उपयोग, गतिशील रूप से अगर एक गुच्छा आबाद <li>है में एक <उल>
  • सभी स्वरूपण करने के लिए सीएसएस का उपयोग करें
  • लाभ!

आप में से कुछ कहने के लिए जा रहे हैं, "अरे! चूंकि आप मेनू पढ़ रहे हैं वैसे भी कोई वास्तविक कैशिंग यहाँ पर जा रहा है हर एक बार.”  और तुम ठीक कह रहे हैं-मैं किसी भी प्रकार के तोड़ सर्वर नहीं दे रहा हूँ।  लेकिन renders HTML पेलोड पूरी तरह से क्योंकि कॉल async है और पृष्ठ प्रारंभिक के बाद होता है, यह "उपयोगकर्ता के लिए और अधिक उत्तरदायी लगता"।  अधिक खींचता है पृष्ठ के रूप में सुंदर मेनू renders.  यदि मेनू में परिवर्तन होता है, उपयोगकर्ता एक नर्वस पुनः आरेखित मेनू के लिए अधीन है, लेकिन केवल उस एक बार.

वहाँ कुछ तरीके इस कैशिंग और अधिक प्रभावी बनाने के लिए और एक ही समय में बाहर सर्वर मदद कर रहे हैं:

  • एक नियम है कि "कुकी"कैश की एक न्यूनतम के लिए मान्य है में डाल दिया 24 घंटे या कुछ अन्य समय सीमा. वहाँ तक है कोई समयसीमा समाप्त कुकी, कुकी मेनू स्नैपशॉट का उपयोग करें और कभी नहीं सर्वर हिट.

.. ठीक है कि सभी कि मन अभी आया है :). 

अगर किसी को किसी भी चालाक विचारों यहाँ है मैं उन्हें पता है कि प्यार होता.

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

</अंत>

undefinedमेरे ब्लॉग के लिए सदस्यता लें.

मेरे चहचहाना पर का पालन करें http://www.twitter.com/pagalvin

कैसे करना है: इकाई परीक्षण और परीक्षण कवरेज QUnit.js और Blanket.js के साथ एक कार्यालय के लिए कॉन्फ़िगर करें 365 SharePoint अनुप्रयोग

परिचय

मैं इकाई परीक्षण तलाश रहा है और कवरेज के लिए जावास्क्रिप्ट परीक्षण के रूप में मैं कार्यालय में SharePoint ऑनलाइन के लिए एक नया SharePoint app पर काम 365 सुइट।  मुझे करने के लिए स्पष्ट अनुसंधान रास्तों का नेतृत्व किया Qunit.js और उस के बाद का अधिकार, करने के लिए Blanket.js.

QUnit मुझे ऊपर इकाई परीक्षण सेट करें और उन्हें में मॉड्यूल समूह हैं।  एक मॉड्यूल अभी संबंधित परीक्षणों को व्यवस्थित करने के लिए एक सरल तरीका है. (मुझे यकीन नहीं है मैं यह उद्देश्य के रूप में उपयोग कर रहा हूँ, लेकिन यह मेरे लिए अभी तक मैं इस तरह अभी तक परिभाषित किया परीक्षणों के छोटे सेट के साथ कार्य करना है).

Blanket.js Qunit के साथ एकीकृत करता है और यह मेरे जावास्क्रिप्ट के वास्तविक लाइनों है कि थे- और अधिक महत्वपूर्ण बात है-वास्तव में परीक्षण चलाने के पाठ्यक्रम में क्रियान्वित थे नहीं दिखाएगा।  इस 'कवरेज'-लाइनों है कि निष्पादित परीक्षण द्वारा कवर कर रहे हैं जबकि अन्य नहीं हैं.

अप अच्छा परीक्षण मामलों की स्थापना और कवरेज देखने के बीच, हम कि हमारे कोड दोष छिपा है जोखिम को कम कर सकते हैं।  गुड टाइम्स.

Qunit

मान लें आप अपने दृश्य स्टूडियो है प्रोजेक्ट सेट अप, जावास्क्रिप्ट पैकेज से डाउनलोड करके प्रारंभ करें http://qunitjs.com.  जावास्क्रिप्ट और इसी सीएसएस करने के लिए अपने समाधान जोड़ें।  मेरा इस तरह दिखता है:

image

चित्रा 1

जैसा कि आप देख सकते हैं, मैं इस्तेमाल कर रहा था 1.13.0 समय पर मैंने लिखा है इस ब्लॉग पोस्ट. डाउनलोड करें और सीएसएस फ़ाइल जोड़ने के लिए मत भूलना.

कि जिस तरह से बाहर, टेस्ट हार्नेस के कुछ प्रकार बनाने के लिए और Qunit बिट्स को संदर्भित करने के लिए अगले कदम है।  मैं तो मैं "के रूप में दिखाया गया QuizUtil_test.html" नामक एक HTML पृष्ठ बनाया "QuizUtil.js" नामक एक स्क्रिप्ट फ़ाइल में एक गुच्छा कार्यों का परीक्षण कर रहा हूँ:

image चित्रा 2

यहाँ कोड है:

<!DOCTYPE html>
<html xmlns"http =://www.w3.org/ 1999/xhtml">
<सिर>
    <शीर्षक>Qunit साथ QuizUtil टेस्ट</शीर्षक>
    <लिंक रिलायंस एनर्जी"stylesheet =" href="../CSS/qunit-1.13.0.css" />
    <स्क्रिप्ट प्रकारपाठ/जावास्क्रिप्ट"=" एसआरसी="QuizUtil.js" डेटा-कवर></स्क्रिप्ट>
    <स्क्रिप्ट प्रकार ="पाठ/जावास्क्रिप्ट" src ="qunit-1.13.0.js"></स्क्रिप्ट>
    <स्क्रिप्ट प्रकार ="पाठ/जावास्क्रिप्ट" src ="blanket.min.js"></स्क्रिप्ट>

    <स्क्रिप्ट>
        मॉड्यूल("getIDFromLookup");
        टेस्ट("QuizUtil getIDFromLookupField", समारोह () {
            var goodValue = "1;#पॉल Galvin";

            बराबर(getIDFromLookupField(goodValue) + 1, 2), "की ID [" + goodValue + "] + 1 2 होना चाहिए";
            बराबर(getIDFromLookupField(अपरिभाषित), अपरिभाषित, "अपरिभाषित इनपुट तर्क अपरिभाषित परिणाम लौट जाना चाहिए।");
            बराबर(getIDFromLookupField(""), अपरिभाषित, "खाली इनपुट तर्क कोई अनिर्धारित मान वापस आ जाना चाहिए।");
            बराबर(getIDFromLookupField("gobbledigood3-thq;dkvn एडीए;skfja sdjfbvubvqrubqer0873407t534piutheqw;वी. एन."), अपरिभाषित,"हमेशा एक परिणाम परिवर्तनीय एक पूर्णांक के लिए वापस चाहिए");
            बराबर(getIDFromLookupField("2;#कुछ अन्य व्यक्ति"), "2", 'की जाँच [2;#कुछ अन्य व्यक्ति].");
            बराबर(getIDFromLookupField("9834524;#लंबे मान"), "9834524", "बड़े मान परीक्षण।");
            notEqual(getIDFromLookupField("5;#किसी को भी", 6), 6, "एक notEqual परीक्षण (5 इसके बराबर नहीं है 6 इस नमूने के लिए: [5;#किसी को भी]");

        });

        मॉड्यूल("htmlEscape");
        टेस्ट("QuizUtil htmlEscape()", समारोह () {
            बराबर(htmlEscape("<"), "&लेफ्टिनेंट;", "ऑपरेटर की तुलना में एक कम से बचने ('<')");
            बराबर(htmlEscape("<div वर्ग =  "someclass">कुछ पाठ</div>"), "&लेफ्टिनेंट;div वर्ग =&quot;someclass&quot;&जी. टी.;कुछ पाठ&लेफ्टिनेंट;/div&जी. टी.;", "और अधिक जटिल परीक्षण स्ट्रिंग।");
        });

        मॉड्यूल("getDateAsCaml");
        टेस्ट("QuizUtil getDateAsCaml()", समारोह () {
            बराबर(getDateAsCaml(नई दिनांक("12/31/2013")), "2013-12-31T:00:00:00", "हार्ड कोडित दिनांक का परीक्षण: [12/31/2013]");
            बराबर(getDateAsCaml(नई दिनांक("01/05/2014")), "2014-01-05T:00:00:00", "हार्ड कोडित दिनांक का परीक्षण: [01/05/2014]");
            बराबर(getDateAsCaml(नई दिनांक("01/31/2014")), "2014-01-31T:00:00:00", "हार्ड कोडित दिनांक का परीक्षण: [01/31/2014]");
            बराबर(getTodayAsCaml(), getDateAsCaml(नई दिनांक()), "getTodayAsCaml() getDateAsCaml बराबर होना चाहिए(नई तारीख())");
            बराबर(getDateAsCaml("बकवास मान"), अपरिभाषित, "एक बकवास मान की तारीख करने के लिए प्रयास करें।");
            बराबर(getDateAsCaml(अपरिभाषित), अपरिभाषित, "की तारीख करने के लिए प्रयास करें [अपरिभाषित] दिनांक।");
        });

        मॉड्यूल("getParameterByName");
        टेस्ट("QuizUtil getParameterByName (से क्वेरी स्ट्रिंग)", समारोह () {
            बराबर(getParameterByName(अपरिभाषित), अपरिभाषित, "करने के लिए कोशिश अपरिभाषित पैरामीटर अपरिभाषित लौट जाना चाहिए।");
            बराबर(getParameterByName("मौजूद नहीं है"), अपरिभाषित, "जब हम जानते हैं कि पैरामीटर मौजूद नहीं पैरामीटर मान प्राप्त करने के लिए प्रयास करें।");

        });

        मॉड्यूल("कुकीज़");
        टेस्ट("QuizUtil विभिन्न कुकी कार्य।", समारोह () {
            बराबर(setCookie(टेस्ट"", "1", -1), getCookieValue(टेस्ट""), "जाओ मैं सेट कुकी काम करना चाहिए।");
            बराबर(setCookie("anycookie", "1", -1), सच है, "एक मान्य खाना पकाने की स्थापना 'सच' लौट जाना चाहिए।");
            बराबर(setCookie("पागल कुकी का नाम !@#$%"%\^&*(()?/><.,", "1", -1), सच है, "एक बुरा कुकी नाम की स्थापना 'झूठी' लौट जाना चाहिए।");
            बराबर(setCookie(अपरिभाषित, "1", -1), अपरिभाषित, "कुकी नाम के रूप में अनिर्धारित गुजर रहा।");
            बराबर(getCookieValue("मौजूद नहीं है"), "", "कुकी टेस्ट मौजूद नहीं है।");
        });

    </स्क्रिप्ट>
</सिर>
<शरीर>
    <div आईडी"qunit ="></div>
    <div आईडी= "qunit-स्थिरता"></div>

</शरीर>
</html>

वहाँ कई चीज़ें यहाँ क्या हो रहा हैं:

  1. मेरे कोड को संदर्भित (QuizUtil.js)
  2. Qunity.js संदर्भित
  3. कुछ मॉड्यूल को परिभाषित करना (getIDFromLookup, कुकीज़, और दूसरों)
  4. रखकर एक <div> जिसका आईडी "qunit" है.

तब, मैं सिर्फ इस पृष्ठ ऊपर खींचने के लिए और आप इस तरह कुछ मिल:

image

चित्रा 3

यदि आप शीर्ष के पार देखो, आपके पास कुछ विकल्प हैं, जिनमें से दो रोचक हैं:

  • परीक्षण पारित छुपाएँ: बहुत स्पष्ट है।  आपकी आँख बस समस्या क्षेत्रों और अव्यवस्था की नहीं एक बहुत कुछ देखने में मदद कर सकते हैं.
  • मॉड्यूल: (ड्रॉप डाउन): यह परीक्षण आप चाहते हैं की सिर्फ उन समूहों के लिए नीचे परीक्षण को फ़िल्टर करेंगे.

परीक्षण के रूप में खुद-कुछ टिप्पणियाँ:

  • यह कि आप ऐसी है कि यह पहली जगह में testable है अपने कोड लिखने के लिए की आवश्यकता है कहे बिना जाता है।  उपकरण का उपयोग करके उस अनुशासन को लागू मदद कर सकते हैं. उदाहरण के लिए, मैं एक समारोह "getTodayAsCaml कहा जाता था()”.  यह बहुत testable नहीं के बाद से यह कोई इनपुट तर्क लेता है और यह समानता के लिए परीक्षण करने के लिए, हम लगातार परीक्षण कोड वर्तमान दिनांक को प्रतिबिंबित करने के लिए अद्यतन करने के लिए की आवश्यकता होगी।  मैं इसे एक डेटा इनपुट पैरामीटर जोड़ने तो वर्तमान दिनांक जब मैं CAML स्वरूप में आज की तिथि चाहते हैं गुजर द्वारा refactored.
  • Qunit फ्रेमवर्क दस्तावेज़ अपने स्वयं के परीक्षण और यह बहुत मजबूत लगता है।  यह समानता के लिए परीक्षण की तरह सरल बातें कर सकते हैं और भी ajax शैली कॉल के लिए समर्थन किया है (दोनों "असली" या ठट्ठा अपने पसंदीदा mocker का उपयोग कर).
  • इस प्रक्रिया के माध्यम से जा रहे भी बढ़त मामले – क्या "अनिर्धारित" के साथ होता है के माध्यम से लगता है कि करने के लिए आप बलों या null एक समारोह में पारित कर दिया गया है।  यह मर बाहर इन परिदृश्यों का परीक्षण करने के लिए सरल बनाता है।  अच्छी चीजें.

Blanket.js के साथ कवरेज

Blanket.js Qunit ट्रैकिंग कोड के वास्तविक लाइनों है कि आपके परीक्षण चलाने के पाठ्यक्रम के दौरान निष्पादित द्वारा पूरक।  यह अधिकार तो भले ही यह एक पूरी अलग app है Qunit में एकीकृत, यह अच्छी तरह से खेलता-यह वास्तव में लग रहा है जैसे कि यह एक निर्बाध app है.

इस क्रिया में blanket.js है:

image चित्रा 4

image

चित्रा 5

(आप वास्तव में ऊपर "कवरेज को सक्षम करें" चेकबॉक्स पर क्लिक करने के लिए है [आंकड़ा देखें 3] यह सक्षम करने के लिए।)

चित्रा में हाइलाइट की गई रेखाएँ 5 मेरा परीक्षण के किसी भी द्वारा निष्पादित नहीं किया गया है, तो मैं एक परीक्षा है कि यदि मैं पूर्ण कवरेज चाहते हैं निष्पादित करने के लिए उन्हें कारण ईजाद करना करने की आवश्यकता.

इन चरणों का पालन करके काम कर blanket.js हो जाओ:

  1. इसे से डाउनलोड करें http://blanketjs.org/.
  2. यह आपके प्रोजेक्ट के लिए जोड़ें
  3. अपने टेस्ट हार्नेस पृष्ठ अद्यतन करें (मेरे मामले में QuizUtil_test.html) इस प्रकार:
    1. संदर्भ कोड
    2. सजाने के लिए अपने <स्क्रिप्ट> इस तरह का संदर्भ:
    <स्क्रिप्ट प्रकारपाठ/जावास्क्रिप्ट"=" एसआरसी="QuizUtil.js" डेटा-कवर></स्क्रिप्ट>

Blanket.js को "डेटा-आवरण" विशेषता ऊपर उठाता है और अपने जादू करता है।  यह Qunit में हुक, "कवरेज को सक्षम करें" विकल्प जोड़ने के लिए यूआई अद्यतन करता है और voila!

सारांश (TL; डॉ.)

लिखने के अपने परीक्षण के मामलों के लिए Qunit का उपयोग करें.

  • यह डाउनलोड करें
  • यह आपके प्रोजेक्ट के लिए जोड़ें
  • लिखने के एक परीक्षण हार्नेस पृष्ठ
  • अपने परीक्षण बनाएँ
    • Testable किया जा करने के लिए अपने कोड के कुछ refactor
    • रचनात्मक होना!  पागल के बारे में सोचो, असंभव परिदृश्यों और उन्हें वैसे भी परीक्षण.

कवरेज सुनिश्चित करने के लिए blanket.js का उपयोग करें

  • सुनिश्चित करें कि Qunit कार्य कर रहा है
  • Blanket.js डाउनलोड और यह आपके प्रोजेक्ट के लिए जोड़ें
  • यह अपने टेस्ट हार्नेस पेज जोड़ें:
    • Blanket.js के लिए एक संदर्भ जोड़ें
    • एक "डेटा-आवरण" विशेषता को जोड़ने अपने <स्क्रिप्ट> टैग
  • भागो अपने Qunit परीक्षण.

मैं कभी इस से पहले के किसी भी किया था और कुछ मामूली सामान घंटे की एक मुट्ठी भर में काम कर रहा था। 

खुश परीक्षण!

</अंत>

undefinedमेरे ब्लॉग के लिए सदस्यता लें.

मेरे चहचहाना पर का पालन करें http://www.twitter.com/pagalvin