Mesečni arhiv: Januarja 2014

Revež je predpomnjenje v JavaScript

[TL;DR. različica: uporablja piškotke za shranjevanje rezultatov asinhron klici; bili rezultati zadnjih asinhron klici takoj in jih nato potrditi po nalaganja strani.]

Sem delal na SharePointovem mestu intranet za stranko, da značilnosti, med drugim, stilizirane sekundarni navigacija, katerih možnosti menija se upravljajo preko rednih stare seznam po meri.  Ideja je, da stranka dobi nadzor nad "svoje" mesto meni brez vpliva ali vpliva globalne navigacije, dal, ki jih je.

(Obstaja nekaj neverjetno subverzivna o dodajanju CEWP, ki kaže na datoteko HTML, ki naloži nekaj CSS in JS bistveno spreminjajo skoraj vse o spletnega mesta obnašanje... ampak to je za drugo delovno mesto)

Šifra tega zal prepost:

Sore spot tukaj je, da vsakič, ko kdorkoli izmed na spletnih straneh zadetkov, to uporabnik spletnega brskalnika je dosegel, da se elementi s seznama.  Ko dev je popolna in testiranje izkazal stvari stabilno in popolne, Ta klic je nepotrebno več kot 99% od takrat redko spremembe v meniju.  Je tudi čudno UI določajo, kateri je splošen v tem krasnem novem svetu spletnih mest hiper-ajaxy-stran postane in šele nato render meniju.  Je živčnosti in moteča v mojem mnenju.  In živčnosti. Tako, predpomnjenje. 

Sem spremenil logika thusly:

  • Poiščite piškotek v brskalnik, ki vsebuje jedilnik, kot sem nazadnje prebral
    • Če najdemo, Render takoj.  Ne čakati na strani konča nakladanja.  (Vi potreba prepričati se vaš HTML strateško dani tukaj, vendar to ni težko narediti).
  • Čakati na strani konča nakladanja in da je Asinhroni klic otovoriti ki gre gor jedilnik reč na seznamu using počitek ali lists.asmx ali karkoli
  • Primerjati, kaj imam proti piškotek
    • Če se ujema, ustavi se
    • Drugače, z uporabo jQuery, dinamično zapolnijo kup, če <Li>je v a <UL>
  • Uporaba CSS storiti vse oblikovanje
  • Dobiček!

Nekateri od vas bodo rekli, "Hej! ni resnično caching tekoč naprej vsepovsod ker berete meni vseeno vsak čas.”  In imaš prav-ne dajem strežnik kakršnokoli odmor.  Ampak ker klic je asinhron in se zgodi, ko je začetno stran HTML tovora popolnoma postane, "meni" bolj odziven na uporabnika.  Meni postane precej toliko, kot stran črpa.  Če se meni zgodi, da sprememba, uporabnik je izpostavljen živčnosti ponovno pripravi menija, ampak samo en čas.

Obstaja nekaj načinov, da bi ta caching učinkovitejši in pomagati strežniku hkrati:

  • V pravilu, da "piškotek cache" velja za najmanj 24 ur ali neki drugi časovni okvir. Dokler je ni poteklo piškotek, uporabite piškotek je meni posnetek in nikoli zadeti strežnik.

No... to je vse, ki pridejo na misel zdaj :). 

Če ima kdo kakšno pametno ideje tukaj bi radi vedeli zanje.

In nenazadnje-to tehniko se lahko uporabijo za druge stvari.  Ta odjemalski strani je število podatkovnih stvari na različnih straneh, Mnogi od njih spreminjajo razmeroma redko (kot enkrat na teden ali enkrat na mesec).  Če ciljate posebnih področjih funkcionalnosti, lahko daš več odgovarajoč UI s potegom vsebine iz lokalnih piškotek trgovine in vračanje takoj.  Zdi hitreje uporabniku, tudi če ne shranjujete strežnik ciklov.  Vi lahko z odločitvijo o nekaterih pogojih in sprožilce, da izničita ta predpomnilnik lokalnih piškotek shrani strežnik ciklov.  To je vse situacijsko in artsy stvari in res najbolj zabavno :). 

</namen>

undefinedNaročite se na moj blog.

Sledite mi na Cvrkutati na http://www.twitter.com/pagalvin

kako: Konfiguriranje enote Test in Test pokritost z QUnit.js in Blanket.js za pisarno 365 SharePoint App

Intro

Bil raziskovati enota testiranja in test zajetje za JavaScript, saj delam na novo SharePoint app za SharePoint online v pisarni 365 Suite.  Poti očitno raziskave me je pripeljala do Qunit.js in prav po tem, za Blanket.js.

QUnit mi nastavite unit testov in jih združite v module.  Modul je samo preprost način za organiziranje ustreznih preskusih. (Ne vem, jaz sem ga uporabljajo, kot je bilo predvideno, vendar deluje za mene tako daleč s majhen nabor testov, ki jih doslej določili).

Blanket.js, ki se integrira z Qunit in to bo pokazal dejanski vrstic JavaScript, ki so bili- in še pomembneje-so bili dejansko izvršeni med teče testov.  To je "zajetje"-proge, da izvajajo so zajete test, medtem ko druge niso.

Med postavljanje ki gre gor dober testnih primerov in pokritost, mi lahko zmanjša tveganje, da ima naša koda skrite napake.  Dobrih časih.

Qunit

Ob predpostavki, da imate Visual Studio projekta nastavite, začnete s prenosom JavaScript paket iz http://qunitjs.com.  Dodajte JavaScript in CSS ustrezne vaša rešitev.  Rudnik pogled tako le:

image

Slika 1

Kot lahko vidite, Sem bil using 1.13.0 v času, ko sem napisal ta blog post. Ne pozabite, da prenesete in dodate datoteki CSS.

Ki s poti, naslednji korak je ustvariti neke vrste test pas in reference Qunit bitov.  Sem testiranje kup funkcij v skriptno datoteko, imenovano "QuizUtil.js", zato sem ustvaril HTML strani, imenovano "QuizUtil_test.html", kot je prikazano:

image Slika 2

Tukaj je koda:

<!DOCTYPE HTML>
<HTML xmlns= "http://www.w3.org/ 1999/xhtml">
<vodja>
    <naslov>QuizUtil test z Qunit</naslov>
    <povezava rel= "stylesheet" href="../CSS/qunit-1.13.0.css" />
    <skript vrsta= text/javascript"" src="QuizUtil.js" podatki zajemajo></skript>
    <skript tipa ="text/javascript" src ="qunit-1.13.0.js"></skript>
    <skript tipa ="text/javascript" src ="blanket.min.js"></skript>

    <skript>
        modul("getIDFromLookup");
        test("QuizUtil getIDFromLookupField", Funkcija () {
            var goodValue = "1;#Paul Galvin";

            enako(getIDFromLookupField(goodValue) + 1, 2), "ID [" + goodValue + "] + 1 2 se";
            enako(getIDFromLookupField(undefined), undefined, "Undefined argument vnosa mora vrniti Nedefiniran rezultat.");
            enako(getIDFromLookupField(""), undefined, "Prazen argument vnosa mora vrniti nedefinirana vrednost.");
            enako(getIDFromLookupField("gobbledigood3-thq;dkvn ada;skfja sdjfbvubvqrubqer0873407t534piutheqw;VN"), undefined,"Naj vedno vrne rezultat kabriolet na celo število");
            enako(getIDFromLookupField("2;#drugo osebo"), "2", "Preverjanje [2;#drugo osebo].");
            enako(getIDFromLookupField("9834524;#dolge vrednosti"), "9834524", "Velike vrednosti test.");
            notEqual(getIDFromLookupField("5;#kdorkoli", 6), 6, "Testiranje a notEqual (5 ni enako 6 za ta vzorec: [5;#kdorkoli]");

        });

        modul("htmlEscape");
        test("QuizUtil htmlEscape()", Funkcija () {
            enako(htmlEscape("<"), "&lt;", "Bežijo manj kot upravljavec ('<')");
            enako(htmlEscape("<razred del =  "someclass">Nekaj besedila</div>"), "&lt;razred del =&quot;SomeClass&quot;&gt;Nekaj besedila&lt;/div&gt;", "Bolj zapletene test niz.");
        });

        modul("getDateAsCaml");
        test("QuizUtil getDateAsCaml()", Funkcija () {
            enako(getDateAsCaml(nove Datum("12/31/2013")), "2013-12-31T:00:00:00", "Testiranje nespremenljivo zapisan datum: [12/31/2013]");
            enako(getDateAsCaml(nove Datum("01/05/2014")), "2014-01-05T:00:00:00", "Testiranje nespremenljivo zapisan datum: [01/05/2014]");
            enako(getDateAsCaml(nove Datum("01/31/2014")), "2014-01-31T:00:00:00", "Testiranje nespremenljivo zapisan datum: [01/31/2014]");
            enako(getTodayAsCaml(), getDateAsCaml(nove Datum()), "getTodayAsCaml() mora biti enak getDateAsCaml(nov datum())");
            enako(getDateAsCaml(»nesmisel vrednost"), undefined, "Poskusite dobiti datum vrednost neumnosti.");
            enako(getDateAsCaml(undefined), undefined, "Poskusite dobiti datum v [undefined] datum.");
        });

        modul("getParameterByName");
        test("QuizUtil getParameterByName (iz niza poizvedbe)", Funkcija () {
            enako(getParameterByName(undefined), undefined, "Poskusite dobiti Nedefiniran parameter vrne undefined.");
            enako(getParameterByName("ne obstaja"), undefined, "Poskušali dobiti vrednost parametra, ko vemo, da je parameter ne obstaja.");

        });

        modul("Piškotki");
        test("QuizUtil različne funkcije piškotek.", Funkcija () {
            enako(setCookie("test", "1", -1), getCookieValue("test"), "Get piškotek nastavim should opus.");
            enako(setCookie("anycookie", "1", -1), True, "Nastavitev veljaven kuhanje should odziv"true".");
            enako(setCookie("noro piškotek ime !@#$%"%\^&*(()?/><.,", "1", -1), True, "Nastavitev slabo piškotek ime naj vrne"false".");
            enako(setCookie(undefined, "1", -1), undefined, "Mimo definirana kot ime piškotka.");
            enako(getCookieValue("ne obstaja"), "", "Piškotek ne obstaja test.");
        });

    </skript>
</vodja>
<telo>
    <div ID= "qunit"></div>
    <div ID= "qunit-stalnica"></div>

</telo>
</HTML>

Obstaja nekaj stvari, ki se dogaja tu:

  1. Navajanje svoj zbornik (QuizUtil.js)
  2. Navajanje Qunity.js
  3. Opredelitev nekaterih modulov (getIDFromLookup, Piškotki, in drugi)
  4. Dajanje a <div> katerega ID je "qunit".

Nato, Sem samo dvigni tostran in dobiš kaj takega:

image

Slika 3

Če pogledaš na vrhu, imate nekaj možnosti, dva, ki so zanimive:

  • Skrivanje opravil teste: Precej očitno.  Lahko pomagajo vaše oči, samo glej problematična področja in ni veliko nereda.
  • Modul: (padajočega): To bo filter preskusi na samo tiste skupine testov, ki jih želite.

Za preskuse, sami – nekaj pripomb:

  • Samoumevno je, da morate pisati kodo tako, da je testirati na prvem mestu.  Z orodjem lahko pomaga izvrševanje discipline. Na primer, Sem imel funkcijo, imenovano "getTodayAsCaml()”.  To ni zelo testirati, saj se noben argument vnosa in test za enakost, bi morali nenehno posodabljanje test kodo, da odražajo trenutni datum.  Sem refactored Dodajanje podatkov vhodni parameter in nato mimo trenutni datum, ko hočem današnji datum v obliki CAML.
  • Qunit okvirni dokumenti svoje testi in zdi zelo močna.  Lahko naredite preproste stvari, kot so testiranje za enakost in ima tudi podporo za style ajax klice ("pravi" ali zasmehovali, using vaš najljubši mocker).
  • Tekoč skozi proces tudi sile, da razmišljajo skozi rob primerih – kaj se dogaja z "neopredeljenih" ali null je prešla v funkcijo.  To pomožen mrtvih preprost test teh scenarijev.  Dobre stvari.

Pokritost z Blanket.js

Blanket.js dopolnjuje Qunit s sledenjem dejanski vrstic kode, ki izvršiti tekom teče vaš testov.  Vključuje pravico v Qunit kljub temu je povsem ločene od app, zelo lepo-res izgleda kot da je en brezšivne app.

To je blanket.js v akciji:

image Slika 4

image

Slika 5

(Dejansko moraš klikniti na "Omogoči pokritost" polje na vrhu [glej sliko 3] v ta namen.)

Označene vrstice na sliki 5 bili izvršeni po katerem koli od mojih testov, zato morate oblikovati test, ki povzročajo jih vršiti če hočem popolno zajetje.

Dobili blanket.js, ki delajo z naslednjim korakom:

  1. Prenesete iz http://blanketjs.org/.
  2. Dodati projektu
  3. Posodobite vaše strani pas test (QuizUtil_test.html v mojem primeru) takole:
    1. Referenčna koda
    2. Okrasite vaš <skript> reference takole:
    <skript vrsta= text/javascript"" src="QuizUtil.js" podatki zajemajo></skript>

Blanket.js dvigne atribut "podatkov-kritje" in ne njeno čarobno.  Kljuke v Qunit, Posodobi UI dodati možnost "Omogoči pokritost" in kot tančica tanka tkanina!

Povzetek (TL; DR)

Uporabo Qunit pisanje testnih primerov.

  • Travnato gričevje to
  • Dodati projektu
  • Pisanje test pas stran
  • Ustvarite vaš testi
    • Nekatere kode biti testable refactor
    • Bodite kreativni!  Razmišljati o crazy, nemogoče scenarijev in test jih nekako.

Uporabite blanket.js, da se zagotovi pokritost

  • Preverite, ali deluje Qunit
  • Travnato gričevje blanket.js ter povečati to v vaš projekt
  • Dodajte vaš test pas stran:
    • Dodajte sklic v blanket.js
    • Dodaj "podatkov-kritje" attribute v vaš <skript> Tag
  • Teči Qunit preskusov.

Nikoli nisem storil vse to pred in imel nekatere nepopolne stvari delajo v nekaj urah. 

Happy testiranje!

</namen>

undefinedNaročite se na moj blog.

Sledite mi na Cvrkutati na http://www.twitter.com/pagalvin