Arsip bulanan: Januari 2014

Orang miskin di Caching di JavaScript

[TL;DR versi: menggunakan cookies untuk menyimpan hasil async panggilan; membuat hasil masa lalu async panggilan segera dan kemudian memvalidasi mereka setelah beban halaman.]

Saya telah bekerja pada situs SharePoint intranet untuk klien yang fitur, di antara hal lain, navigasi sekunder yang bergaya pilihan menu yang dikelola melalui daftar kustom tua biasa.  Idenya adalah bahwa klien mendapatkan untuk mengontrol menu situs "mereka" tanpa mempengaruhi atau sedang dipengaruhi oleh navigasi global yang dikeluarkan oleh itu.

(ada sesuatu yang sangat subversif tentang menambahkan CEWP yang menunjuk ke sebuah file HTML yang memuat beberapa CSS dan JS untuk secara fundamental mengubah hampir segala sesuatu tentang perilaku situs... tapi itu untuk pos lain)

Kode untuk ini cukup sederhana:

Sini tempat sakit adalah bahwa setiap kali ada hits salah satu halaman situs, browser web pengguna yang menjangkau untuk mendapatkan item dari daftar.  Setelah dev lengkap dan pengujian telah membuktikan hal-hal yang stabil dan lengkap, panggilan ini tidak perlu lebih dari 99% waktu sejak menu jarang berubah.  Ini juga memiliki mempengaruhi UI aneh yang umum dalam ini dunia baru yang berani situs web hiper-ajaxy-halaman menulisnya dan hanya kemudian membuat menu.  Sangat gelisah dan mengganggu dalam pandangan saya.  Dan gelisah. Jadi, caching. 

Aku diubah logika thusly:

  • Mencari cookie di browser yang berisi menu aku terakhir membacanya
    • Jika ditemukan, membuat itu segera.  Jangan menunggu untuk halaman untuk selesai loading.  (Anda perlu memastikan bahwa HTML Anda ditempatkan secara strategis di sini, Tapi itu tidak sulit untuk dilakukan).
  • Menunggu halaman selesai loading dan membuat async panggilan untuk memuat menu item dari daftar menggunakan sisa atau lists.asmx atau apa pun
  • Membandingkan apa yang saya Dapatkan terhadap cookie
    • Jika cocok, Stop
    • Jika tidak, menggunakan jQuery, dinamis mengisi setumpuk jika <Li>di dalam <UL>
  • Gunakan CSS untuk melakukan semua format
  • Keuntungan!

Beberapa dari Anda akan mengatakan, "Hei! ada tidak ada nyata caching terjadi di sini karena Anda sedang membaca menu tetap setiap kali.”  Dan kau benar-aku tidak memberikan server jenis istirahat.  Namun karena panggilan async dan terjadi setelah halaman awal muatan HTML sepenuhnya menuliskan, ia "merasa" lebih responsif terhadap pengguna.  Menu menuliskan cukup banyak seperti halaman yang menarik.  Jika menu terjadi perubahan, pengguna terkena gelisah menggambar ulang menu, tetapi hanya satu kali.

Ada beberapa cara untuk membuat ini caching lebih efektif dan membantu keluar server pada saat yang sama:

  • Dimasukkan ke dalam aturan "cookie cache" itu berlaku untuk minimal 24 jam atau beberapa jangka waktu lain. Selama ada kuki tidak kedaluwarsa, menggunakan cookie menu snapshot dan tidak pernah memukul server.

Yah... itu semua yang datang ke pikiran sekarang :). 

Jika seseorang memiliki ide-ide cerdas di sini saya ingin tahu mereka.

Dan terakhir-teknik ini dapat digunakan untuk hal-hal lain.  Halaman ini klien memiliki sejumlah hal data-driven pada berbagai halaman, banyak dari mereka mengubah relatif jarang (seperti satu minggu sekali atau sebulan sekali).  Jika Anda menargetkan daerah tertentu dari fungsi, Anda dapat memberikan UI lebih responsif dengan konten menarik dari toko lokal cookie dan rendering segera.  Rasanya lebih cepat kepada pengguna bahkan jika Anda tidak menyelamatkan server setiap siklus.  Anda dapat Simpan siklus server oleh memutuskan pada beberapa kondisi dan memicu untuk membatalkan cache lokal cookie ini.  Itulah semua situasional dan barang-barang berseni dan benar-benar yang paling menyenangkan :). 

</akhir>

undefinedBerlangganan ke blog saya.

Ikuti saya di kegugupan di http://www.twitter.com/pagalvin

Bagaimana caranya: Mengkonfigurasi Unit pengujian dan cakupan uji dengan QUnit.js dan Blanket.js untuk kantor 365 Aplikasi SharePoint

Intro

Aku sudah menjelajahi pengujian unit dan menguji cakupan untuk JavaScript ketika bekerja pada sebuah aplikasi SharePoint baru untuk SharePoint online di kantor 365 Suite.  Jalur penelitian jelas mendorong saya untuk Qunit.js dan kanan setelah itu, untuk Blanket.js.

Kebun buah-buahan biarkan aku membuat unit test dan mengelompokkan mereka ke dalam modul.  Module adalah cara yang mudah untuk mengatur tes terkait. (Saya tidak yakin saya menggunakan sebagaimana dimaksud, Tapi itu bekerja bagi saya begitu jauh dengan set kecil tes saya sejauh ini telah didefinisikan).

Blanket.js terintegrasi dengan kebun buah-buahan dan ia akan menampilkan jalur sebenarnya JavaScript yang itu- dan lebih penting-tidak benar-benar dilaksanakan dalam menjalankan tes.  Ini adalah "cakupan"-baris yang dieksekusi dilindungi oleh tes sementara yang lain tidak.

Antara pengaturan kasus uji yang baik dan melihat cakupan, kita dapat mengurangi risiko bahwa kode kita telah tersembunyi Cacat.  Baik kali.

Kebun buah-buahan

Dengan asumsi Anda memiliki Visual Studio proyek mengatur, Mulailah dengan men-download paket JavaScript dari http://qunitjs.com.  Menambahkan JavaScript dan CSS yang sesuai untuk solusi Anda.  Tambang terlihat seperti ini:

image

Gambar 1

Seperti Anda dapat melihat, Saya menggunakan 1.13.0 pada saat saya menulis posting blog ini. Jangan lupa untuk men-download dan menambahkan CSS file.

Yang keluar dari jalan, langkah berikutnya adalah untuk menciptakan semacam harness tes dan referensi bit kebun buah-buahan.  Saya menguji banyak fungsi dalam file skrip bernama "QuizUtil.js" Jadi saya membuat halaman HTML yang disebut "QuizUtil_test.html" seperti yang ditunjukkan:

image Gambar 2

Berikut adalah kode:

<!DOCTYPE HTML>
<HTML xmlns= "http://www.w3.org/ 1999/xhtml">
<kepala>
    <judul>QuizUtil tes dengan kebun buah-buahan</judul>
    <link rel= "stylesheet" href="../CSS/qunit-1.13.0.CSS" />
    <script jenis= text/javascript"" src="QuizUtil.js" data-cover></script>
    <script type ="text/javascript" src ="kebun buah-buahan-1.13.0.js"></script>
    <script type ="text/javascript" src ="blanket.min.js"></script>

    <script>
        modul("getIDFromLookup");
        tes("QuizUtil getIDFromLookupField", fungsi () {
            var goodValue = "1;#Paul Galvin";

            sama(getIDFromLookupField(goodValue) + 1, 2), "ID [" + goodValue + "] + 1 harus menjadi 2";
            sama(getIDFromLookupField(terdefinisi), terdefinisi, "Undefined masukan argumen harus kembali undefined hasil.");
            sama(getIDFromLookupField(""), terdefinisi, "Kosong masukan argumen harus mengembalikan nilai undefined.");
            sama(getIDFromLookupField("gobbledigood3-thq;dkvn ada;skfja sdjfbvubvqrubqer0873407t534piutheqw;VN"), terdefinisi,"Harus selalu kembali hasil konversi ke Integer");
            sama(getIDFromLookupField("2;#beberapa orang lain"), "2", "Memeriksa [2;#beberapa orang lain].");
            sama(getIDFromLookupField("9834524;#nilai panjang"), "9834524", "Nilai besar ujian.");
            notEqual(getIDFromLookupField("5;#siapa pun", 6), 6, "Pengujian notEqual (5 tidak sama dengan 6 untuk contoh ini: [5;#siapa pun]");

        });

        modul("htmlEscape");
        tes("QuizUtil htmlEscape()", fungsi () {
            sama(htmlEscape("<"), "&lt;", "Escaping kurang dari operator ('<')");
            sama(htmlEscape("<div kelas =  "someclass">Beberapa teks</div>"), "&lt;div kelas =&quot;someclass&quot;&gt;Beberapa teks&lt;/div&gt;", "Lebih kompleks tes string.");
        });

        modul("getDateAsCaml");
        tes("QuizUtil getDateAsCaml()", fungsi () {
            sama(getDateAsCaml(baru Tanggal("12/31/2013")), "2013-12-31T:00:00:00", "Pengujian kode keras tanggal: [12/31/2013]");
            sama(getDateAsCaml(baru Tanggal("01/05/2014")), "2014-01-05T:00:00:00", "Pengujian kode keras tanggal: [01/05/2014]");
            sama(getDateAsCaml(baru Tanggal("01/31/2014")), "2014-01-31T:00:00:00", "Pengujian kode keras tanggal: [01/31/2014]");
            sama(getTodayAsCaml(), getDateAsCaml(baru Tanggal()), "getTodayAsCaml() harus sama dengan getDateAsCaml(Tanggal baru())");
            sama(getDateAsCaml("nilai omong kosong"), terdefinisi, "Mencoba untuk mendapatkan tanggal nilai omong kosong.");
            sama(getDateAsCaml(terdefinisi), terdefinisi, "Mencoba untuk mendapatkan tanggal [terdefinisi] tanggal.");
        });

        modul("getParameterByName");
        tes("QuizUtil getParameterByName (dari string kueri)", fungsi () {
            sama(getParameterByName(terdefinisi), terdefinisi, "Mencoba untuk mendapatkan parameter terdefinisi harus kembali undefined.");
            sama(getParameterByName("tidak ada"), terdefinisi, "Cobalah untuk mendapatkan nilai parameter ketika kita tahu parameter yang tidak ada.");

        });

        modul("Cookies");
        tes("QuizUtil berbagai fungsi kuki.", fungsi () {
            sama(setCookie("ujian", "1", -1), getCookieValue("ujian"), "Dapatkan saya menetapkan cookie harus bekerja.");
            sama(setCookie("anycookie", "1", -1), benar, "Pengaturan memasak sah harus kembali 'benar'.");
            sama(setCookie("nama cookie gila !@#$%"%\^&*(()?/><.,", "1", -1), benar, "Menetapkan nama buruk cookie harus kembali 'palsu'.");
            sama(setCookie(terdefinisi, "1", -1), terdefinisi, "Lewat undefined sebagai nama cookie.");
            sama(getCookieValue("tidak ada"), "", "Cookie tidak ada tes.");
        });

    </script>
</kepala>
<bodyHTMLan >><  kuat >  pesan yang kuat.</strong>  </body>  </html> ">
    <div id= "kebun buah-buahan"></div>
    <div id= "kebun buah-buahan-fixture"></div>

</bodyHTMLan >><  kuat >  pesan yang kuat.</strong>  </body>  </html> ">
</HTML>

Ada beberapa hal yang terjadi di sini:

  1. Kode saya referensi (QuizUtil.js)
  2. Referensi Qunity.js
  3. Mendefinisikan beberapa modul (getIDFromLookup, Cookie, dan lain-lain)
  4. Menempatkan <div> ID Apakah "kebun buah-buahan".

Kemudian, Aku hanya menarik Halaman ini dan Anda mendapatkan sesuatu seperti ini:

image

Gambar 3

Jika Anda melihat di atas, Anda memiliki beberapa pilihan, dua di antaranya menarik:

  • Sembunyikan lulus tes: Cukup jelas.  Dapat membantu mata Anda hanya melihat area masalah dan tidak banyak kekacauan.
  • Modul: (drop-down): Ini akan menyaring tes ke kelompok-kelompok tersebut hanya tes yang Anda inginkan.

Untuk tes sendiri – beberapa komentar:

  • Tak usah dikatakan bahwa Anda perlu untuk menulis kode Anda sedemikian rupa sehingga hal ini dapat diuji di tempat pertama.  Menggunakan alat dapat membantu menegakkan disiplin. Misalnya, Aku punya fungsi yang disebut "getTodayAsCaml()”.  Ini bukan sangat diuji karena ini membutuhkan tidak ada argumen masukan dan mengujinya untuk kesetaraan, kita perlu terus-menerus memperbarui kode tes untuk mencerminkan tanggal saat ini.  Saya direfractor dengan menambahkan data input parameter kemudian melewati tanggal saat ini ketika aku ingin tanggal dalam CAML format.
  • Dokumen-dokumen kerangka kerja kebun buah-buahan tes sendiri, dan tampaknya cukup kuat.  Ini dapat melakukan hal-hal sederhana seperti pengujian untuk kesetaraan dan juga memiliki dukungan untuk panggilan gaya ajax ("nyata" atau diejek menggunakan mocker favorit Anda).
  • Melalui proses juga memaksa Anda untuk memikirkan edge kasus-apa yang terjadi dengan "undefined" atau null dilewatkan ke dalam fungsi.  Itu membuatnya mati sederhana untuk menguji skenario ini keluar.  Bagus.

Cakupan dengan Blanket.js

Blanket.js melengkapi kebun buah-buahan pelacakan sebenarnya baris kode yang mengeksekusi selama menjalankan tes Anda.  Ini mengintegrasikan kanan ke kebun buah-buahan jadi meskipun itu adalah sebuah aplikasi seluruh terpisah, It memutar baik-itu benar-benar tampak seperti satu app mulus.

Ini adalah blanket.js dalam aksi:

image Gambar 4

image

Gambar 5

(Anda benar-benar harus klik pada kotak centang "Aktifkan cakupan" di bagian atas [Lihat gambar 3] untuk mengaktifkan ini.)

Baris yang disorot dalam gambar 5 belum dilaksanakan oleh salah satu tes, Jadi saya perlu menyusun tes yang menyebabkan mereka untuk melaksanakan jika saya ingin cakupan penuh.

Dapatkan blanket.js bekerja dengan mengikuti langkah-langkah:

  1. Men-download dari http://blanketjs.org/.
  2. Tambahkan ke proyek Anda
  3. Memperbarui halaman percobaan Anda memanfaatkan (QuizUtil_test.html dalam kasus saya) sebagai berikut:
    1. Referensi kode
    2. Menghias Anda <script> referensi seperti ini:
    <script jenis= text/javascript"" src="QuizUtil.js" data-cover></script>

Blanket.js mengambil atribut "data-penutup" dan melakukan keajaiban.  Kait ke kebun buah-buahan, Update UI untuk menambahkan opsi "Aktifkan cakupan" dan voila!

Ringkasan (TL; DR)

Menggunakan kebun buah-buahan untuk menulis Anda uji kasus.

  • Men-download
  • Tambahkan ke proyek Anda
  • Menulis sebuah halaman harness tes
  • Membuat tes Anda
    • Refactor beberapa kode Anda harus diuji
    • Menjadi kreatif!  Pikirkan gila, mungkin skenario dan menguji mereka tetap.

Gunakan blanket.js untuk memastikan cakupan

  • Memastikan kebun buah-buahan bekerja
  • Download blanket.js dan menambahkannya ke proyek Anda
  • Tambahkan ke halaman Anda baju zirah tes:
    • Menambahkan referensi ke blanket.js
    • Menambahkan atribut "data-penutup" untuk Anda <script> Tag
  • Menjalankan tes kebun buah-buahan Anda.

Saya tidak pernah melakukan hal ini sebelum dan memiliki beberapa hal dasar yang bekerja dalam beberapa jam. 

Pengujian bahagia!

</akhir>

undefinedBerlangganan ke blog saya.

Ikuti saya di kegugupan di http://www.twitter.com/pagalvin