Seni Pengujian Tata Letak Dengan Kerangka Galen

Diterbitkan: 2022-03-10
Ringkasan cepat Saat mendesain antarmuka pengguna grafis, selalu ada pertanyaan terbuka: Bagaimana kita mengotomatiskan pengujian untuk itu? Dan bagaimana kami memastikan tata letak situs web tetap responsif dan ditampilkan dengan benar di semua jenis perangkat dengan berbagai resolusi? Ditambah lagi komplikasi yang timbul dari konten dinamis, persyaratan untuk internasionalisasi dan lokalisasi, dan itu menjadi tantangan nyata. Pada artikel ini, saya akan memandu Anda melalui teknik pengujian tata letak baru yang menarik. Menggunakan Galen Framework , saya akan memberikan tutorial terperinci untuk menulis tes tata letak umum yang bermakna, yang dapat dijalankan di browser apa pun dan di perangkat apa pun dan pada saat yang sama digunakan sebagai satu sumber kebenaran dalam dokumentasi desain Anda.

Saat merancang antarmuka pengguna grafis, selalu ada pertanyaan terbuka: Bagaimana kami mengotomatiskan pengujian untuk itu? Dan bagaimana kami memastikan tata letak situs web tetap responsif dan ditampilkan dengan benar di semua jenis perangkat dengan berbagai resolusi? Ditambah lagi komplikasi yang timbul dari konten dinamis, persyaratan untuk internasionalisasi dan lokalisasi, dan itu menjadi tantangan nyata.

Pada artikel ini, saya akan memandu Anda melalui teknik pengujian tata letak baru yang menarik. Menggunakan Galen Framework, saya akan memberikan tutorial terperinci untuk menulis tes tata letak umum yang bermakna, yang dapat dijalankan di browser apa pun dan di perangkat apa pun dan pada saat yang sama digunakan sebagai satu sumber kebenaran dalam dokumentasi desain Anda.

Bacaan Lebih Lanjut tentang SmashingMag:

  • Pengembangan Berbasis Tes Visual Untuk Desain Antarmuka Responsif
  • Dasar-dasar Otomasi Uji Untuk Aplikasi, Game, dan Web Seluler
  • Kerangka Kerja Tes-Otomasi Beragam Untuk Aplikasi Asli Bereaksi

Saya juga akan mendemonstrasikan bagaimana saya membuat pengujian yang dioptimalkan untuk halaman pesan di situs web iklan baris kami, Marktplaats. Kita akan belajar bagaimana memperluas sintaks Galen dengan bahasa kita sendiri, bagaimana meningkatkan kode pengujian dan bagaimana mengubah rutinitas pengujian tata letak menjadi seni.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Pengantar Kerangka Galen

Kerangka Galen dibahas setahun yang lalu dalam "Pengembangan Berbasis Tes Visual untuk Desain Antarmuka Responsif." Pada saat itu, sintaksnya terbatas. Ini telah meningkat pesat sejak dan mendapatkan banyak fitur baru, yang akan kita lihat di sini.

Jika Anda tidak terbiasa dengan Galen Framework, ini adalah alat untuk pengujian tata letak dan pengujian fungsional yang responsif dan lintas-browser, dengan bahasa pengujiannya sendiri, bernama Galen Specs. Ini didasarkan pada Selenium WebDriver dan juga memiliki API JavaScript kaya yang memungkinkan Anda bekerja dengan WebDriver secara langsung. Karena Anda memiliki kendali atas WebDriver, Anda dapat menjalankan pengujian di browser apa pun, di cloud (SauceLabs, BrowserStack, PerfectoMobile, dll.) atau di perangkat seluler nyata menggunakan Appium.

Menginstal dan Menjalankan

Menyiapkan Kerangka Galen itu mudah. Cukup jalankan perintah berikut untuk menginstalnya melalui npm:

 npm install -g galenframework-cli

Jika Anda tidak menggunakan npm, cukup unduh arsip Kerangka Galen terbaru, ekstrak paket dan ikuti petunjuk instalasi.

Setelah terinstal, Galen Framework dapat diluncurkan dengan berbagai cara. Misalnya, Anda dapat menggunakan perintah check untuk meluncurkan tes cepat satu halaman. Untuk perintah ini, Anda perlu menyediakan file .gspec dengan validasi tata letak Anda, dan kemudian Anda dapat menjalankannya seperti ini:

 galen check loginPage.gspec --url https://example.com --size 1024x768 --include desktop --htmlreport reports

Perintah ini akan meluncurkan browser, membuka URL yang ditentukan, mengubah ukuran jendela browser menjadi 1024 × 768 piksel dan menjalankan semua validasi yang dideklarasikan dalam file loginPage.gspec . Hasilnya, Anda akan mendapatkan laporan HTML terperinci.

Mengelola Test Suite

Di dunia nyata, aplikasi web yang sebenarnya tidak hanya terdiri dari halaman statis. Cukup sering Anda harus melakukan beberapa tindakan untuk sampai ke tempat yang ingin Anda periksa. Dalam hal ini, Galen menawarkan rangkaian pengujian JavaScript dan API JavaScript GalenPages untuk mengimplementasikan model objek halaman. Berikut adalah contoh sederhana dari tes Galen JavaScript:

 test("Home page", function() { var driver = createDriver("https://galenframework.com", "1024x768"); checkLayout(driver, "homePage.gspec", ["desktop"]); });

Dan berikut adalah implementasi dari model objek halaman untuk halaman login, yang diambil dari proyek nyata.

 WelcomePage = $page("Welcome page", { loginButton: "#welcome-page .button-login" }); LoginPage = $page("Login page", { username: "input[name='login.username']", password: "input[name='login.password']", loginButton: "button.button-login" loginAs: loggedFunction ("Log in as ${_1.username} with password ${_1.password}", function(user) { this.username.typeText(user.username); this.password.typeText(user.password); this.loginButton.click(); }) }); test("Login page", function() { var driver = createDriver("https://testapp.galenframework.com", "1024x768"); var welcomePage = new WelcomePage(driver).waitForIt(); welcomePage.loginButton.click(); new LoginPage(driver).waitForIt(); checkLayout(driver, "loginPage.gspec", ["desktop"]); });

Untuk penggunaan lanjutan, saya menyarankan Anda untuk melihat proyek Galen Bootstrap. Ini adalah ekstensi JavaScript yang dibuat khusus untuk Galen. Ini menyediakan beberapa fungsionalitas tambahan untuk pengujian UI dan cara yang lebih mudah untuk mengonfigurasi browser dan menjalankan rangkaian pengujian yang kompleks.

Tes Tata Letak Sederhana

Mari saya mulai dengan memperkenalkan tes tata letak sederhana di Galen Framework. Kemudian, saya akan beralih ke kasus penggunaan lanjutan dan mendemonstrasikan cara memperluas sintaks Galen Specs. Untuk ini, kita akan melihat header dengan ikon dan keterangan:

Ikon dan keterangan
Ikon dan keterangan (Lihat versi besar)

Dalam kode HTML, mungkin terlihat seperti ini:

 <body> <!-- … --> <div> <img class="header-logo" src="/imgs/header-logo.png"/> <h1>My Blog</h1> </div> <!-- … --> </body>

Bentuk paling sederhana dari tes tata letak Galen akan terlihat seperti berikut ini. Pertama, kita harus mendeklarasikan objek dengan pemilih CSS.

 @objects header #header icon #header img caption #header h1

Kemudian, kami mendeklarasikan bagian pengujian dengan nama yang bermakna dan meletakkan semua validasi kami di bawahnya.

 = Icon and Caption = icon: left-of caption 10 to 15px width 32px height 32px inside header 10px top caption: aligned horizontally all header inside header

Di sini kami telah menguji dua elemen header: ikon dan keterangan. Semua validasi yang tercantum di bawah ikon dan elemen keterangan sebenarnya adalah Spesifikasi Galen standar. Spesifikasi tersebut adalah blok bangunan dasar yang dengannya Anda dapat merakit solusi pengujian tata letak Anda sendiri. Setiap spesifikasi memverifikasi satu properti (seperti lebar, tinggi, teks), posisi relatif (seperti di dalam, kiri, di atas) atau piksel dalam tangkapan layar (seperti skema warna, gambar).

Menguji Beberapa Elemen Menggunakan forEach Loops

Contoh sebelumnya menunjukkan skenario sederhana. Mari kita lihat bagaimana kita bisa menghadapi situasi yang lebih rumit: menu horizontal. Pertama, mari kita coba teknik pengujian tata letak langsung.

Menu horisontal
Menu horizontal (Lihat versi besar)

Mulailah dengan mencocokkan beberapa elemen pada halaman. Dengan kode berikut, kami memberi tahu Galen untuk mencari elemen yang cocok dengan #menu ul li pemilih CSS.

 @objects menu #menu item-* ul li

Nanti, kita bisa merujuk ke item ini dengan nama seperti menu.item-1 dan menu.item-2 dan mengulangi semua item menu menggunakan @forEach loop.

 = Menu = menu.item-1: inside menu 0px top left bottom @forEach [menu.item-*] as menuItem, next as nextItem ${menuItem}: left-of ${nextItem} 0px aligned horizontally all ${nextItem}

Seperti yang Anda lihat, meskipun pemeriksaan sebenarnya tidak terlalu rumit, kodenya sudah menjadi kurang intuitif. Bayangkan jika kami memiliki lebih banyak kode serupa dalam pengujian kami. Pada titik tertentu, itu akan menjadi kekacauan yang tidak dapat dipertahankan. Harus ada cara untuk meningkatkannya.

Memikirkan Ulang Pengujian Tata Letak

Jika Anda memikirkan contoh sebelumnya, sepertinya kita bisa mengekspresikan tata letak hanya dalam satu atau dua kalimat. Misalnya, kita dapat mengatakan sesuatu seperti, “Semua item menu harus disejajarkan secara horizontal, tanpa margin di antaranya. Item menu pertama harus ditempatkan di sisi kiri menu, tanpa margin.” Karena kita telah merumuskan kalimat untuk menjelaskan tata letak yang kita inginkan, mengapa kita tidak menggunakannya saja dalam kode kita? Bayangkan jika kita bisa menulis kode seperti ini:

 = Menu = |first menu.item-* is in top left corner of menu |menu.item-* are aligned horizontally next to each other

Sebenarnya, itu adalah kode kerja nyata, disalin dari proyek saya. Dalam dua baris terakhir tersebut (dimulai dengan pipa, | ), kami menjalankan fungsi khusus yang mengumpulkan argumennya dengan menguraikan kedua pernyataan tersebut. Tentu saja, contoh di atas tidak akan berfungsi apa adanya. Agar dapat dikompilasi, kita perlu mengimplementasikan handler untuk kedua pernyataan tersebut. Kami akan kembali ke implementasi ini nanti.

Poin kunci dengan contoh di atas adalah bahwa pengujian tata letak telah bergeser dari pengujian berbasis objek ke pengujian berbasis ekspresi . Ini mungkin tidak jelas dari contoh kecil seperti itu, tetapi jelas terlihat pada skala yang lebih besar. Jadi, mengapa ini signifikan? Jawaban singkatnya adalah bahwa ini mengubah pola pikir kita dan memengaruhi cara kita mendesain perangkat lunak kita dan menulis tes untuknya.

Dengan menggunakan teknik ini, kami tidak memperlakukan halaman kami sebagai sekumpulan objek dengan hubungan khusus di antara mereka. Kami tidak menguji properti CSS dari elemen individual. Dan kami menghindari penulisan kode non-sepele yang rumit. Sebagai gantinya, kami mencoba memikirkan pola tata letak umum dan pernyataan yang bermakna. Daripada menguji item menu 1, item menu 2 dan seterusnya secara terpisah, kami menerapkan pernyataan umum yang:

  • dapat direproduksi pada elemen lain;
  • tidak mengandung nilai piksel hardcoded;
  • diterapkan pada abstraksi dan bukan pada objek konkret;
  • dan, last but not least, benar-benar masuk akal ketika kita membacanya.

Bagaimana itu bekerja

Izinkan saya menjelaskan mekanisme ekspresi tata letak khusus menggunakan contoh sederhana ini:

sketsa sederhana
Sketsa sederhana (Lihat versi besar)

Dalam contoh ini, kita seharusnya memeriksa bahwa tombol membentang ke panel, tanpa margin di sisi kiri atau kanan. Tanpa aturan khusus, kami dapat mendekatinya dengan cara yang berbeda, tetapi saya lebih suka solusi berikut:

 button: inside some_panel 0px left right

Kode di atas memberi kita fleksibilitas untuk mendeklarasikan margin kustom di samping, dan juga secara implisit menguji apakah tombol tersebut sepenuhnya berada di dalam panel. Kelemahannya adalah itu tidak terlalu mudah dibaca, itulah sebabnya saya akan meletakkan validasi ini di belakang button stretches to some_panel . Agar itu berfungsi, kita perlu menulis aturan khusus seperti ini:

 @rule %{elementName} stretches to %{parentName} ${elementName}: inside ${parentName} 0px left right

Itu dia. Sekarang kita dapat mengujinya hanya dalam satu baris:

 | button stretches to some_panel

Seperti yang Anda lihat, aturan ini membutuhkan dua argumen: elementName dan parentName . Ini memungkinkan kita untuk menerapkannya ke elemen lain juga. Ganti saja nama kedua objek itu.

 | login_panel stretches to main_container | header stretches to screen | footer stretches to screen # etc.

Menerapkan Bahasa Pengujian Anda Sendiri

Mari kembali ke contoh awal ekspresi layout untuk menu horizontal.

 = Menu = | first menu.item-* is in top left corner of menu | menu.item-* are aligned horizontally next to each other

Kita dapat menerapkan aturan pertama dengan cara berikut:

 @rule first %{itemPattern} is in %{cornerSides} corner of %{parentElement} @if ${count(itemPattern) > 0} ${first(itemPattern).name}: inside ${parentElement} 0px ${cornerSides}

Ketika digunakan dalam contoh kita, itu akan mengurai argumen sebagai berikut:

  • itemPattern = menu.item-*
  • cornerSides = top left
  • parentElement = menu

Karena kita sudah selesai dengan ekspresi pertama kita, kita bisa pindah ke yang berikutnya. Dalam ekspresi kedua, kita seharusnya menguji perataan horizontal semua item menu. Saya mengusulkan tiga langkah sederhana:

  1. Temukan semua item menu.
  2. Ulangi semuanya sampai elemen kedua dari belakang.
  3. Periksa apakah elemen n terletak di sebelah kiri elemen n+1 dan tepi atas dan bawahnya sejajar.

Untuk membuatnya berfungsi, kita perlu mengambil @forEach loop dan spesifikasi left-of dan aligned . Untungnya, di Galen Anda dapat merujuk ke item sebelumnya atau berikutnya dalam satu lingkaran. Jika Anda telah mendeklarasikan referensi ke elemen berikutnya, itu hanya akan diulang hingga elemen kedua dari belakang, yang persis seperti yang kita butuhkan.

 @rule %{itemPattern} are aligned horizontally next to each other @forEach [${itemPattern}] as item, next as nextItem ${item}: left-of ${nextItem} 0px aligned horizontally all ${nextItem}

Anda mungkin bertanya, Bagaimana jika kita harus menentukan margin dalam pengujian kita (seperti ~ 20px atau 10 to 20px )? Kemudian, saya sarankan untuk menerapkan aturan terpisah atau memperluas yang sudah ada untuk mendukung argumen %{margin} .

 @rule %{itemPattern} are aligned horizontally next to each other with %{margin} margin @forEach [${itemPattern}] as item, next as nextItem ${item}: left-of ${nextItem} ${margin} aligned horizontally all ${nextItem}

Itu dia! Kami telah membuat ekspresi umum yang membantu kami memvalidasi menu horizontal. Namun, karena fleksibilitasnya, kami dapat melakukan lebih dari itu. Kita dapat menggunakannya untuk menguji elemen lain di halaman. Kami bahkan dapat menggunakannya untuk menguji keselarasan dua tombol:

Tombol formulir
Tombol formulir (Lihat versi besar)
 | menu.item-* are aligned horizontally next to each other with 0px margin | submit_button, cancel_button are aligned horizontally next to each other with 20px margin

Anda mungkin memperhatikan dalam dua contoh ini bahwa kami telah mendeklarasikan argumen pertama dalam dua cara yang berbeda. Pada ekspresi pertama, argumen pertama adalah “menu.item-*” , dan pada ekspresi kedua dideklarasikan sebagai “submit_button, cancel_button” . Itu dimungkinkan karena @forEach loop memungkinkan kita untuk menggunakan daftar objek yang dipisahkan koma bersama dengan operator bintang. Tapi kita masih belum selesai dengan refactoring. Kami dapat meningkatkan kode lebih lanjut dan membuatnya lebih mudah dibaca. Jika kita membuat grup untuk item menu dan tombol formulir masuk, kita dapat melakukan sesuatu seperti ini:

 @groups menu_items menu_item-* login_form_buttons submit_button, cancel_button = Testing login page = | &menu_items are aligned horizontally next to each other with 0px margin | &login_form_buttons are aligned horizontally next to each other with 20px margin

Dalam hal ini, kita harus menggunakan simbol & , yang merupakan singkatan dari deklarasi grup. Itu sudah merupakan ujian yang bagus. Pertama, itu hanya berfungsi, dan kami dapat menguji apa yang kami butuhkan. Juga, kodenya jelas dan mudah dibaca. Jika orang lain bertanya kepada Anda seperti apa tampilan halaman masuk dan apa persyaratan desainnya, Anda dapat memberi tahu mereka untuk melihat pengujiannya.

Seperti yang Anda lihat, mengimplementasikan ekspresi kustom untuk pola tata letak yang kompleks bukanlah masalah besar. Ini mungkin menantang pada awalnya, tetapi masih menyerupai sesuatu dari aktivitas kreatif.

Margin Dinamis

Mari kita lihat pola tata letak langka lainnya yang mungkin kadang-kadang Anda temukan di berbagai situs web. Bagaimana jika kita ingin menguji bahwa elemen memiliki jarak yang sama antara satu sama lain? Mari kita coba menerapkan aturan lain untuk itu, tetapi kali ini menggunakan implementasi JavaScript. Saya mengusulkan pernyataan seperti itu: “box_item-* are aligned horizontally next to each other with equal distance” . Ini akan menjadi sedikit rumit karena kita tidak tahu margin antar elemen dan kita tidak bisa hanya meng-hardcode nilai piksel. Oleh karena itu, hal pertama yang harus kita lakukan adalah mengambil margin aktual antara elemen pertama dan terakhir.

Sama-sama jauh
Sama jauhnya (Lihat versi besar)

Setelah kita mendapatkan margin itu, kita dapat mendeklarasikannya dalam loop @forEach yang serupa dengan yang kita lakukan sebelumnya. Saya mengusulkan penerapan aturan ini menggunakan JavaScript API karena logika yang diperlukan sedikit lebih kompleks daripada di semua contoh kami sebelumnya. Mari kita buat file bernama my-rules.js dan ketik kode ini:

 rule("%{objectPattern} are aligned horizontally next to each other with equal margin", function (objectName, parameters) { var allItems = findAll(parameters.objectPattern), distance = Math.round(Math.abs(allItems[1].left() - allItems[0].right())), expectedMargin = (distance - 1) + " to " + (distance + 1) + "px"; if (allItems.length > 0) { for (var i = 0; i < allItems.length - 1; i += 1) { var nextElementName = allItems[i + 1].name; this.addObjectSpecs(allItems[i].name, [ "aligned horizontally all " + nextElementName, "left-of " + nextElementName + " " + expectedMargin ]); } } });

Dalam kode pengujian kami, kami akan menggunakannya seperti ini:

 @script my-rules.js # … = Boxes = | box_item-* are aligned horizontally next to each other with equal distance

Seperti yang Anda lihat, di Galen Framework kita dapat memilih antara dua bahasa saat menerapkan aturan: Galen Specs dan JavaScript. Untuk ekspresi sederhana, Galen Specs lebih mudah digunakan, tetapi untuk ekspresi kompleks saya selalu memilih JavaScript. Jika Anda ingin mempelajari lebih lanjut tentang aturan JavaScript, lihat dokumentasi.

Ekstra Galen

Setelah cukup bermain dengan berbagai pola tata letak, saya menyadari bahwa semua aturan Galen ini dapat dengan mudah diterapkan di proyek pengujian lainnya. Itu memberi saya ide untuk mengkompilasi ekspresi tata letak yang paling umum ke dalam perpustakaan mereka sendiri. Begitulah cara saya datang untuk membuat proyek Galen Extras. Berikut adalah beberapa contoh kemampuan perpustakaan ini:

 | header.icon should be squared | amount of &menu_items should be > 3 | &menu_items are aligned horizontally next to each other | &list_items are aligned vertically above each other with equal distance | every &menu_item is inside menu 0px top and has width > 50px | first &menu_item is inside menu 0px top left | &menu_items are rendered in 2 column table | &menu_items are rendered in 2 column table, with 0 to 1px vertical and 10px horizontal margin | &login_form_elements sides are vertically inside content_container with 20px margin login_panel: | located on the left side of panel and takes 70 % of its width # etc …

Pustaka Galen Extras berisi banyak pola tata letak yang biasa Anda temukan di situs web, dan saya terus memperbaruinya segera setelah saya menemukan pola yang berguna. Setelah perpustakaan ini disiapkan, saya memutuskan untuk mencobanya pada proyek uji nyata.

Menguji Aplikasi Pesan

Saat ini, saya bekerja sebagai insinyur perangkat lunak di Marktplaats. Pada titik tertentu, saya memutuskan untuk menerapkan semua pengalaman yang saya peroleh ke proyek nyata. Saya perlu menguji halaman perpesanan di situs web kami. Berikut tampilannya:

halaman pesan
Halaman pesan (Lihat versi besar)

Sejujurnya, menerapkan tes untuk halaman seperti itu selalu tampak agak menakutkan bagi saya, terutama tes tata letak. Tetapi dengan perpustakaan Galen Extras di tempat, itu sebenarnya berjalan cukup lancar, dan segera saya dapat menemukan kode ini:

 @import ../selected-conversation.gspec @groups (message, messages) messenger.message-* first_two_messages messenger.message-1,messenger.message-2 first_message messenger.message-1 second_message messenger.message-2 third_message messenger.message-3 (message_date_label, message_date_labels) messenger.date_label-* first_date_label messenger.date_label-1 second_date_label messenger.date_label-2 = Messages panel = = Messages and Date labels = |amount of visible &message_date_labels should be 1 |first &message_date_label has text is "17 november 2015" |amount of visible &messages should be 3 |&first_two_messages should be located at the left inside messenger with ~ 20px margin |&third_message should be located at the right inside messenger with ~ 20px margin |&messages are placed above each other with 10 to 15px margin |text of all &messages should be ["Hi there!", "I want to buy something", "Hello! Sure, it's gonna be 100 euros"] = Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message

Mengekstrak Rentang Piksel

Tes tampak OK: Itu kompak dan mudah dibaca tetapi masih jauh dari sempurna. Saya tidak terlalu menyukai semua definisi margin tersebut ( ~ 20px , 10 to 15px ). Beberapa dari mereka diulang, dan sulit untuk memahami apa arti masing-masing dari mereka. Itulah mengapa saya memutuskan untuk menyembunyikan setiap margin di balik variabel yang berarti.

 # ... @set messages_side_margin ~ 20px messages_vertical_margin 10 to 15px = Messages panel = = Messages and Date labels = |amount of visible &message_date_labels should be 1 |first &message_date_label has text is "17 november 2015" |amount of visible &messages should be 3 |&first_two_messages should be located at the left inside messenger with ${messages_side_margin} margin |&third_message should be located at the right inside messenger with ${messages_side_margin} margin |&messages are placed above each other with ${messages_vertical_margin} margin # ...

Seperti yang Anda lihat, saya telah memindahkan margin ke messages_vertical_margin dan messages_side_margin . Saya juga telah mendeklarasikan margin minimal , yaitu kisaran antara 0 dan 1 piksel.

 # ... @set minimal 0 to 1px = Conversations Panel = | &conversations are aligned above each other with ${minimal} margin # ...

Validasi Berbasis Gambar dan Ekspresi Kustom

Setelah membahas posisi semua elemen utama pada halaman, saya memutuskan juga untuk menguji gaya. Saya ingin memvalidasi bahwa setiap pesan memiliki warna latar belakang khusus untuk peran pengguna. Saat pengguna masuk, pesan akan memiliki latar belakang biru muda. Pesan untuk pengguna lain akan memiliki latar belakang putih. Jika pesan belum terkirim, peringatan kesalahan akan memiliki latar belakang merah muda. Berikut adalah aturan yang membantu saya memvalidasi gaya ini:

 @set OWN_MESSAGE_COLOR #E1E8F5 OTHERS_MESSAGE_COLOR white ERROR_MESSAGE_COLOR #FFE6E6 @rule %{item} should be styled as %{style} message ${item}: @if ${style === "own"} color-scheme > 60% ${OWN_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR} @elseif ${style === "error"} color-scheme > 60% ${ERROR_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR} @else color-scheme > 60% ${OTHERS_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR}

Spesifikasi color-scheme memverifikasi distribusi proporsional warna dalam suatu elemen. Ini memotong tangkapan layar halaman dan menganalisis distribusi warna. Jadi, untuk memeriksa warna latar belakang suatu elemen, kami hanya memeriksa bahwa distribusinya lebih besar dari 60% dari total rentang warna. Dalam pengujian, aturan ini dipanggil seperti ini:

 = Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message

Mengonfigurasi Test Suite

Aplikasi perpesanan adalah aplikasi dinamis yang bekerja sama dengan RESTful Messaging API. Oleh karena itu, untuk menguji tata letaknya di semua status yang berbeda, kita harus menyiapkan data uji. Saya memutuskan untuk meniru Messaging API sehingga saya dapat mengonfigurasi semua pesan pengujian saya di suite pengujian. Berikut adalah bagian dari rangkaian pengujian saya yang menunjukkan bagaimana pengujian kami terstruktur.

 // ... testOnAllDevices("Unselected 2 conversations", "/", function (driver, device) { mock.onGetMyConversationsReturn(sampleConversations); refresh(driver); new MessageAppPage(driver).waitForIt(); checkLayout(driver, "specs/tests/unselected-conversations.gspec", device.tags); }); testOnAllDevices("When clicking a conversation it should reveal messages", "/", function (driver, device) { mock.onGetMyConversationsReturn(sampleConversations); mock.onGetSingleConversationReturn(sampleMessages); refresh(driver); var page = new MessageAppPage(driver).waitForIt(); page.clickFirstConversation(); checkLayout({ driver: driver, spec: "specs/tests/three-simple-messages-test.gspec", tags: device.tags, vars: { expectedTextProvider: textProvider({ "messenger.message-1": "Hi there!\n11:02", "messenger.message-2": "I want to buy something\n12:02", "messenger.message-3": "Hello! Sure, it's gonna be 100 euros\n13:02" }) } }); }); // ...

Menangkap Bug

Menerapkan ekspresi sederhana itu terbayar cukup cepat. Mari kita bahas jenis bug apa yang dapat kita tangkap dengan rangkaian pengujian kita.

Masalah Gaya

Berikut adalah contoh ketika ada yang salah dalam basis kode CSS kami dan, sebagai hasilnya, semua pesan dirender dengan latar belakang yang sama.

Warna latar belakang pesan salah
Warna latar belakang pesan salah (Lihat versi besar)

Jika Anda membandingkan tangkapan layar ini dengan aslinya, Anda akan melihat bahwa pesan terakhir memiliki latar belakang putih, padahal seharusnya berwarna biru muda. Mari kita lihat bagaimana Galen melaporkan masalah ini:

Tangkapan layar dengan pesan kesalahan
Tangkapan layar dengan pesan kesalahan (Lihat versi besar)

Untuk objek yang disorot, ini menampilkan color #e1e8f5 on “messenger.message-3” is 0% but it should be greater than 60% . Sejujurnya, pesan kesalahan ini tidak terlihat begitu jelas, tetapi karena pemeriksaan ini dibuat dari aturan khusus, kami selalu dapat mencari nama aslinya di cabang laporan:

Melaporkan kegagalan pengujian
Melaporkan kegagalan pengujian (Lihat versi besar)

Jika Anda menggulir ke atas, Anda akan melihat bahwa pernyataan asli &third_message should be styled as own message . Itu adalah manfaat lain dari menggunakan ekspresi kustom: Mereka membantu Anda memahami kegagalan dan menjelaskan dengan baik semua validasi yang dihasilkan.

Masalah Pemosisian

Berikut adalah contoh lain ketika tata letak menjadi salah karena penyelarasan elemen yang salah. Pada tangkapan layar berikut, Anda dapat melihat bahwa pesan terakhir diposisikan di sisi kiri area pandang perpesanan, bukan di kanan.

Posisi pesan yang salah
Posisi pesan yang salah (Lihat versi besar)

Mari kita lihat lagi tangkapan layar dengan pesan kesalahan:

Posisi pesan yang salah
Posisi pesan yang salah (Lihat versi besar)

Tangkapan layar menyoroti wadah pesan dan elemen pesan terakhir. Bersamaan dengan itu, itu menunjukkan pesan kesalahan berikut: “messenger.message-3” is 285px right which is not in range of 22 to 28px . Mungkin tidak jelas bagi pengembang web mengapa margin 22 hingga 28 piksel diharapkan di sisi kanan. Sekali lagi, Anda harus mencari pernyataan validasi di cabang laporan:

Posisi pesan yang salah
Posisi pesan yang salah (Lihat versi besar)

Pernyataan asli untuk pemeriksaan itu adalah &third_message should be located at the right inside messenger with ~ 25px margin . Itu jauh lebih masuk akal. Selain itu, teknisi front-end lainnya akan memahami laporan pengujian ini, meskipun mereka belum menulis pengujiannya.

Pedoman Pengujian Tata Letak

Dengan mempertimbangkan semua eksperimen yang berbeda ini, saya memutuskan untuk memformalkan semua pembelajaran ke dalam pedoman pengujian tata letak umum. Berikut adalah daftar cepat langkah-langkah yang harus diikuti untuk memudahkan rutinitas pengujian Anda.

  • Mengidentifikasi pola tata letak dalam desain.
  • Generalisasi pernyataan validasi. Cobalah untuk menyingkat sebagian besar validasi menjadi kalimat tunggal.
  • Komponen! Itu selalu lebih baik untuk memindahkan pengujian elemen berulang ke dalam komponen khusus.
  • Gunakan nama yang bermakna untuk bagian, aturan, dan objek.
  • Hindari piksel. Cobalah untuk mengganti nilai piksel (apakah nilai eksak atau rentang) dengan variabel yang bermakna.
  • Sesuaikan kode situs web Anda untuk memudahkan pengujian. Ini akan membantu Anda menyusun dan memelihara kode produksi dan pengujian Anda.

Kriteria Penerimaan Untuk Penyelamatan

Seringkali saya mendapatkan pertanyaan seperti, “Jadi, seberapa detail seharusnya tes tata letak? Dan apa yang harus kita uji secara khusus?” Jawaban umum sulit diberikan. Masalahnya adalah ketika cakupan tes kecil, Anda melewatkan bug. Di sisi lain, jika Anda memiliki tes yang terlalu rinci, Anda mungkin mendapatkan banyak positif palsu, dan di masa depan Anda mungkin tersesat dalam pemeliharaan tes. Jadi, ada trade-off. Tapi saya menemukan pedoman umum untuk diri saya sendiri. Jika Anda membagi pekerjaan menjadi cerita pengguna yang lebih kecil, maka akan lebih mudah untuk menyusun desain halaman dalam bentuk kriteria penerimaan. Pada akhirnya, Anda mungkin menempatkan kriteria penerimaan ini tepat di kode pengujian Anda. Misalnya, beberapa pernyataan ini dapat didefinisikan dalam bentuk aturan khusus, seperti yang ditunjukkan pada semua contoh kode sebelumnya. Contoh kriteria penerimaan yang baik adalah seperti ini:

  • Popup harus dipusatkan secara vertikal dan horizontal di layar.
  • Lebarnya harus 400 piksel.
  • Tombol harus disejajarkan secara horizontal.
  • Dan seterusnya

Setelah Anda menjelaskan desain dalam kalimat sederhana, akan lebih mudah untuk mengubahnya menjadi pernyataan yang dapat digunakan kembali dan untuk mengatur kode pengujian Anda.

Kesimpulan

Seperti yang Anda lihat, latihan semacam itu membantu Anda menyusun desain dan menemukan pola tata letak umum yang dapat dibagikan di beberapa komponen halaman. Meskipun halamannya kompleks dan terdiri dari banyak elemen, Anda selalu dapat menemukan cara untuk mengelompokkannya dalam ekspresi tata letak Anda. Dengan pendekatan ini, pengujian tata letak menjadi lebih dari alat untuk pengembangan yang didorong oleh pengujian, membantu Anda merancang, mengimplementasikan, dan mengirimkan perangkat lunak secara bertahap, yang sangat berguna dalam lingkungan yang tangkas.

Sumber daya

  • Kerangka Galen (situs web resmi)
  • Kerangka Galen, GitHub
  • Galen Extras (perpustakaan), GitHub
  • Galen Bootstrap, GitHub
  • “Tutorial Kerangka Galen,” YouTube