Galen Çerçevesi ile Mizanpaj Testi Sanatı
Yayınlanan: 2022-03-10Bir grafik kullanıcı arayüzü tasarlarken her zaman açık bir soru vardır: Bunun için testi nasıl otomatikleştiririz? Ve web sitesi düzeninin duyarlı kalmasını ve çeşitli çözünürlüklerde her tür cihazda doğru şekilde görüntülenmesini nasıl sağlarız? Buna dinamik içerikten, uluslararasılaştırma ve yerelleştirme gereksinimlerinden kaynaklanan karmaşıklıkları ekleyin ve bu gerçek bir meydan okuma haline gelir.
Bu makalede, size ilginç bir yeni yerleşim testi tekniği konusunda rehberlik edeceğim. Galen Çerçevesini kullanarak, herhangi bir tarayıcıda ve herhangi bir cihazda yürütülebilen ve aynı zamanda tasarım dokümantasyonunuzda tek bir gerçek kaynağı olarak kullanılabilen, anlamlı genelleştirilmiş düzen testleri yazmak için ayrıntılı bir eğitim sağlayacağım.
SmashingMag'de Daha Fazla Okuma :
- Duyarlı Arayüz Tasarımı İçin Görsel Test Odaklı Geliştirme
- Uygulamalar, Oyunlar ve Mobil Web İçin Test Otomasyonunun Temelleri
- React Native Uygulamaları için Çeşitli Test Otomasyon Çerçeveleri
Ayrıca, ilanlar web sitemiz Marktplaats'ta bir mesajlaşma sayfası için optimize edilmiş bir testi nasıl bulduğumu da göstereceğim. Galen'in sözdizimini kendi dilimiz ile nasıl genişleteceğimizi, test kodunu nasıl geliştireceğimizi ve bir düzen test rutinini nasıl sanata dönüştüreceğimizi öğreneceğiz.
Galen Çerçevesine Giriş
Galen Framework, bir yıl önce "Duyarlı Arayüz Tasarımı için Görsel Teste Dayalı Geliştirme" bölümünde ele alındı. O zamanlar, sözdizimi sınırlıydı. O zamandan beri çok gelişti ve burada bakacağımız birçok yeni özellik kazandı.
Galen Framework'e aşina değilseniz, Galen Specs adlı kendi test diliyle duyarlı ve tarayıcılar arası düzen testi ve işlevsel test için bir araçtır. Selenium WebDriver'ı temel alır ve ayrıca WebDriver ile doğrudan çalışmanıza izin veren zengin bir JavaScript API'sine sahiptir. WebDriver üzerinde kontrole sahip olduğunuz için, herhangi bir tarayıcıda, bulutta (SauceLabs, BrowserStack, PerfectoMobile, vb.) veya Appium kullanarak gerçek mobil cihazlarda testleri çalıştırabilirsiniz.
Yükleme ve Yürütme
Galen Framework'ü kurmak kolaydır. Npm ile yüklenmesini sağlamak için aşağıdaki komutu yürütmeniz yeterlidir:
npm install -g galenframework-cli
npm kullanmıyorsanız, en son Galen Framework arşivini indirin, paketi çıkarın ve kurulum talimatlarını izleyin.
Galen Framework kurulduktan sonra çeşitli şekillerde başlatılabilir. Örneğin, tek bir sayfanın hızlı testini başlatmak için check
komutunu kullanabilirsiniz. Bu komut için, düzen doğrulamalarınızla birlikte bir .gspec
dosyası sağlamanız gerekir ve ardından onu şu şekilde çağırabilirsiniz:
galen check loginPage.gspec --url https://example.com --size 1024x768 --include desktop --htmlreport reports
Bu komut bir tarayıcı başlatacak, belirtilen URL'yi açacak, tarayıcı penceresini 1024 × 768 piksel olarak yeniden boyutlandıracak ve loginPage.gspec
dosyasında belirtilen tüm doğrulamaları yürütecektir. Sonuç olarak, ayrıntılı bir HTML raporu alacaksınız.
Test Paketlerini Yönetme
Gerçek dünyada, gerçek bir web uygulaması yalnızca statik sayfalardan oluşmaz. Oldukça sık, kontrol etmek istediğiniz yere ulaşmak için bazı eylemler gerçekleştirmeniz gerekecektir. Bu durumda Galen, sayfa nesne modelini uygulamak için JavaScript test takımları ve GalenPages JavaScript API'sini sunar. JavaScript Galen testinin basit bir örneği:
test("Home page", function() { var driver = createDriver("https://galenframework.com", "1024x768"); checkLayout(driver, "homePage.gspec", ["desktop"]); });
Ve işte gerçek bir projeden alınan bir oturum açma sayfası için sayfa nesne modelinin bir uygulaması.
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"]); });
Gelişmiş kullanım için Galen Bootstrap projesine bakmanızı tavsiye ederim. Galen için özel olarak oluşturulmuş bir JavaScript uzantısıdır. UI testi için bazı ekstra işlevler ve tarayıcıları yapılandırmak ve karmaşık test takımlarını yürütmek için daha kolay bir yol sağlar.
Basit Düzen Testi
Galen Çerçevesinde basit bir düzen testi tanıtarak başlayayım. Ardından, gelişmiş kullanım örneklerine geçeceğim ve Galen Spesifikasyonları sözdiziminin nasıl genişletileceğini göstereceğim. Bunun için bir simge ve başlık içeren bir başlığa bakacağız:

HTML kodunda şöyle görünebilir:
<body> <!-- … --> <div> <img class="header-logo" src="/imgs/header-logo.png"/> <h1>My Blog</h1> </div> <!-- … --> </body>
Galen yerleşim testinin en basit şekli aşağıdaki gibi görünecektir. İlk olarak, nesneleri CSS seçicileri ile bildirmeliyiz.
@objects header #header icon #header img caption #header h1
Ardından, anlamlı bir adla bir test bölümü ilan ediyoruz ve tüm doğrulamalarımızı bunun altına koyuyoruz.
= 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
Burada iki başlık öğesini test ettik: simge ve başlık. Simge ve başlık öğelerinin altında listelenen tüm doğrulamalar aslında standart Galen Spesifikasyonlarıdır. Bu özellikler, kendi yerleşim test çözümünüzü oluşturabileceğiniz temel yapı taşlarıdır. Her özellik, tek bir özelliği (genişlik, yükseklik, metin gibi), göreli konumlandırmayı (içeride, solunda, üstünde gibi) veya ekran görüntüsündeki pikselleri (renk şeması, görüntü gibi) doğrular.
forEach Döngülerini Kullanarak Birden Çok Öğeyi Test Etme
Önceki örnek basit bir senaryoyu göstermektedir. Daha karmaşık bir durumla nasıl başa çıkabileceğimize bakalım: yatay bir menü. İlk olarak, basit bir düzen test tekniği deneyelim.

Sayfadaki birden çok öğeyi eşleştirerek başlayın. Aşağıdaki kodla, #menu ul li
CSS seçicisiyle eşleşen öğeleri aramasını söylüyoruz.
@objects menu #menu item-* ul li
Daha sonra bu öğelere menu.item-1
ve menu.item-2
gibi isimlerle başvurabilir ve bir @forEach
döngüsü kullanarak tüm menü öğelerini yineleyebiliriz.
= 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}
Gördüğünüz gibi, gerçek kontrol o kadar karmaşık olmasa da, kod zaten daha az sezgisel hale geldi. Testlerimizde daha fazla benzer kodumuz olup olmadığını hayal edin. Bir noktada, sürdürülemez bir karmaşa haline gelecekti. Bunu iyileştirmenin bir yolu olmalı.
Düzen Testini Yeniden Düşünmek
Önceki örneği düşünürseniz, düzeni sadece bir veya iki cümleyle ifade edebiliriz. Örneğin, "Tüm menü öğeleri arada boşluk bırakılmadan yatay olarak hizalanmalıdır. İlk menü öğesi, menünün sol tarafında kenar boşluğu olmadan yer almalıdır.” İstediğimiz düzeni açıklamak için cümleler formüle ettiğimiz için, neden onları kodumuzda kullanamıyoruz? Kodu şöyle yazabileceğimizi hayal edin:
= Menu = |first menu.item-* is in top left corner of menu |menu.item-* are aligned horizontally next to each other
Aslında, bu benim projemden kopyalanan gerçek çalışma kodudur. Bu son iki satırda (pipe ile başlayan |
), bu iki ifadeyi ayrıştırarak argümanlarını toplayan özel işlevleri çağırıyoruz. Tabii ki, yukarıdaki örnek olduğu gibi çalışmayacaktır. Derlenmesi için bu iki ifadenin işleyicilerini uygulamamız gerekiyor. Bu uygulamaya daha sonra döneceğiz.
Yukarıdaki örnekteki kilit nokta, düzen testinin nesne güdümlü testten ifade güdümlü teste geçmiş olmasıdır. Bu kadar küçük bir örnekten belli olmayabilir, ancak daha büyük ölçekte kesinlikle fark edilir. Peki, bu neden önemli? Kısa cevap, bunun zihniyetimizi değiştirmesi ve yazılımımızı tasarlama ve bunun için testler yazma şeklimizi etkilemesidir.
Bu tekniği kullanarak, sayfamıza aralarında belirli ilişkiler olan bir grup nesne gibi davranmıyoruz. Tek tek öğelerin CSS özelliklerini test etmiyoruz. Ve karmaşık, önemsiz olmayan kod yazmaktan kaçınıyoruz. Bunun yerine, ortak düzen kalıpları ve anlamlı ifadeler düşünmeye çalışıyoruz. Menü öğesi 1, menü öğesi 2 ve benzerlerini ayrı ayrı test etmek yerine, şu genel ifadeleri uygularız:
- diğer elementler üzerinde tekrarlanabilir;
- sabit kodlanmış piksel değerleri içermez;
- somut nesnelere değil, soyutlamalara uygulanır;
- ve son olarak, ama en az değil, onları okuduğumuz zaman gerçekten mantıklı geliyor.
Nasıl çalışır
Bu basit örneği kullanarak özel düzen ifadelerinin mekanizmasını açıklamama izin verin:

Bu örnekte, düğmenin sol veya sağ tarafta kenar boşluğu olmadan panele uzandığını kontrol etmemiz gerekiyor. Özel kurallar olmadan farklı şekillerde yaklaşabiliriz, ancak aşağıdaki çözümü tercih ederim:
button: inside some_panel 0px left right
Yukarıdaki kod bize kenarlarda özel kenar boşluğu bildirme esnekliği verir ve ayrıca düğmenin tamamen panel içinde yer aldığını dolaylı olarak test eder. Dezavantajı, çok okunaklı olmamasıdır, bu yüzden bu doğrulamayı, ifade button stretches to some_panel
ifadesinin arkasına koyacağım. Bunun çalışması için şöyle bir özel kural yazmamız gerekiyor:
@rule %{elementName} stretches to %{parentName} ${elementName}: inside ${parentName} 0px left right
Bu kadar. Şimdi bunu testimize sadece bir satırda koyabiliriz:
| button stretches to some_panel
Gördüğünüz gibi, bu kural iki argüman alır: elementName
ve parentName
. Bu, onu diğer öğelere de uygulamamızı sağlar. Sadece bu iki nesnenin adlarını değiştirin.
| login_panel stretches to main_container | header stretches to screen | footer stretches to screen # etc.
Kendi Test Dilinizi Uygulamak
Yatay menü için düzen ifadelerinin ilk örneklerine geri dönelim.
= Menu = | first menu.item-* is in top left corner of menu | menu.item-* are aligned horizontally next to each other
Birinci kuralı şu şekilde uygulayabiliriz:
@rule first %{itemPattern} is in %{cornerSides} corner of %{parentElement} @if ${count(itemPattern) > 0} ${first(itemPattern).name}: inside ${parentElement} 0px ${cornerSides}
Örneğimizde kullanıldığında, argümanları aşağıdaki gibi ayrıştırır:
-
itemPattern
=menu.item-*
-
cornerSides
=top left
-
parentElement
=menu
İlk ifademiz bittiği için bir sonrakine geçebiliriz. İkinci ifadede, tüm menü öğelerinin yatay hizalamasını test etmemiz gerekiyor. Üç basit adım öneriyorum:
- Tüm menü öğelerini bulun.
- Sondan bir önceki öğeye kadar hepsini yineleyin.
-
n
öğesinin,n+1
öğesinin solunda yer aldığını ve üst ve alt kenarlarının aynı hizada olduğunu kontrol edin.
Çalışmasını sağlamak için, bir @forEach
döngüsü ve left-of
ve aligned
özelliklerden almamız gerekiyor. Neyse ki, Galen'de bir döngüdeki önceki veya sonraki öğeye başvurabilirsiniz. Bir sonraki öğeye bir başvuru bildirmiş olmanız durumunda, yalnızca sondan bir önceki öğeye kadar yinelenecektir, ki bu tam olarak ihtiyacımız olan şeydir.
@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}
Testimizde bir marj belirlememiz gerekirse ( ~ 20px
veya 10 to 20px
gibi) sorabilirsiniz. Ardından, ya ayrı bir kural uygulamanızı ya da mevcut kuralı bir %{margin}
argümanını destekleyecek şekilde genişletmenizi öneririm.
@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}
Bu kadar! Yatay menüyü doğrulamamıza yardımcı olan genel bir ifade oluşturduk. Ancak, esnekliği nedeniyle bundan çok daha fazlasını yapabiliriz. Sayfadaki diğer öğeleri test etmek için kullanabiliriz. İki düğmenin hizalamasını test etmek için bile kullanabiliriz:

| 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
Bu iki örnekte ilk argümanı iki farklı şekilde açıkladığımızı fark edebilirsiniz. İlk ifadede, ilk argüman “menu.item-*”
, ikinci ifadede “submit_button, cancel_button”
olarak bildirildi. @forEach
döngüsü yıldız operatörüyle birlikte virgülle ayrılmış bir nesne listesi kullanmamıza izin verdiği için bu mümkündür. Ama hala yeniden düzenleme ile işimiz bitmedi. Kodu daha da geliştirebilir ve daha okunabilir hale getirebiliriz. Menü öğeleri ve giriş formu düğmeleri için gruplar oluşturursak, şöyle bir şey başarabiliriz:

@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
Bu durumda, grup bildirimi anlamına gelen &
sembolünü kullanmamız gerekir. Bu zaten iyi bir test. İlk olarak, sadece işe yarıyor ve ihtiyacımız olanı test edebiliyoruz. Ayrıca, kod açık ve okunabilir. Başka bir kişi size giriş sayfasının nasıl görünmesi gerektiğini ve tasarım gereksinimlerinin neler olduğunu sorarsa, onlara teste bakmalarını söyleyebilirsiniz.
Gördüğünüz gibi, karmaşık düzen kalıpları için özel ifadeler uygulamak çok da önemli değil. Başlangıçta zorlayıcı olabilir, ancak yine de yaratıcı bir aktiviteyi andırıyor.
Dinamik Marjlar
Bazen çeşitli web sitelerinde bulabileceğiniz başka bir nadir yerleşim düzenine bakalım. Peki ya öğelerin aralarında eşit mesafe olduğunu test etmek istersek? Bunun için başka bir kural uygulamaya çalışalım, ancak bu sefer bir JavaScript uygulaması kullanarak. Böyle bir ifade öneriyorum: “box_item-* are aligned horizontally next to each other with equal distance”
. Bu biraz zor olacak çünkü elemanlar arasındaki marjı bilmiyoruz ve sadece piksel değerlerini sabit kodlayamayız. Bu nedenle, yapmamız gereken ilk şey, ilk ve son öğeler arasındaki gerçek marjı almaktır.

Bu marjı elde ettiğimizde, daha önce yaptığımıza benzer bir @forEach
döngüsünde bildirebiliriz. Gereken mantık önceki tüm örneklerimizden biraz daha karmaşık olduğundan, bu kuralı JavaScript API'sini kullanarak uygulamayı öneriyorum. my-rules.js
adında bir dosya oluşturalım ve şu kodu yazalım:
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 ]); } } });
Test kodumuzda bunu şu şekilde kullanacağız:
@script my-rules.js # … = Boxes = | box_item-* are aligned horizontally next to each other with equal distance
Gördüğünüz gibi, Galen Framework'te kuralları uygularken iki dil arasında seçim yapabiliriz: Galen Spesifikasyonları ve JavaScript. Basit ifadeler için Galen Specs'in kullanımı daha kolaydır, ancak karmaşık ifadeler için her zaman JavaScript'i seçerim. JavaScript kuralları hakkında daha fazla bilgi edinmek istiyorsanız belgelere bakın.
Galen Ekstraları
Çeşitli yerleşim kalıplarıyla yeterince oynadıktan sonra, tüm bu Galen kurallarının başka herhangi bir test projesinde kolayca uygulanabileceğini anladım. Bu bana en yaygın mizanpaj ifadelerini kendi kitaplıklarında derlemek için bir fikir verdi. Galen Extras projesini böyle yaratmaya geldim. Aşağıda bu kitaplığın neler yapabileceğine dair bazı örnekler verilmiştir:
| 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 …
Galen Extras kitaplığı, web sitelerinde yaygın olarak bulacağınız düzen kalıplarının çoğunu içerir ve kullanışlı bir kalıp keşfeder bulmaz onu güncellemeye devam ediyorum. Bu kütüphane kurulduktan sonra, onu gerçek bir test projesinde denemeye karar verdim.
Mesajlaşma Uygulamasını Test Etme
Şu anda Marktplaats'ta yazılım mühendisi olarak çalışıyorum. Bir noktada, kazandığım tüm deneyimi gerçek bir projede uygulamaya karar verdim. Web sitemizdeki mesajlaşma sayfasını test etmem gerekiyordu. İşte böyle görünüyor:

Dürüst olmak gerekirse, bu tür sayfalar için testler uygulamak, özellikle mizanpaj testleri olmak üzere bana her zaman biraz korkutucu geldi. Ama Galen Extras kütüphanesi yerindeyken, aslında oldukça sorunsuz gitti ve kısa süre sonra şu kodu bulabildim:
@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
Piksel Aralıklarını Çıkarma
Test iyi görünüyordu: Kompakt ve okunabilirdi ama yine de mükemmel olmaktan uzaktı. Tüm bu kenar boşluğu tanımlarını gerçekten beğenmedim ( ~ 20px
, 10 to 15px
). Bazıları tekrar edildi ve her birinin neyi temsil ettiğini anlamak zordu. Bu yüzden her kenar boşluğunu anlamlı bir değişkenin arkasına saklamaya karar verdim.
# ... @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 # ...
Gördüğünüz gibi, kenar boşluklarını messages_vertical_margin
ve messages_side_margin
olarak değiştirdim. Ayrıca 0 ile 1 piksel arasında bir aralık olan minimal
bir marj beyan ettim.
# ... @set minimal 0 to 1px = Conversations Panel = | &conversations are aligned above each other with ${minimal} margin # ...
Görüntü Tabanlı Doğrulama ve Özel İfadeler
Sayfadaki tüm ana öğelerin yerleşimini ele aldıktan sonra, stili de test etmeye karar verdim. Her mesajın kullanıcının rolüne özel bir arka plan rengine sahip olduğunu doğrulamak istedim. Kullanıcılar oturum açtığında, mesajlar açık mavi bir arka plana sahip olacaktır. Diğer kullanıcılar için olan mesajların arka planı beyaz olacaktır. Bir mesajın gönderilmemesi durumunda, hata uyarısı pembe bir arka plana sahip olacaktır. İşte bu stilleri doğrulamama yardımcı olan kural:
@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}
color-scheme
belirtimi, bir öğe içindeki renklerin orantılı dağılımını doğrular. Sayfanın ekran görüntüsünü kırpar ve renk dağılımını analiz eder. Bu nedenle, bir öğenin arka plan rengini kontrol etmek için dağılımının toplam renk aralığının %60'ından büyük olduğunu kontrol ederiz. Testte, bu kural şu şekilde çağrılır:
= Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message
Test Paketlerini Yapılandırma
Mesajlaşma uygulaması, RESTful Mesajlaşma API'si ile birlikte çalışan dinamik bir uygulamadır. Bu nedenle, yerleşimlerini tüm farklı durumlarda test etmek için test verilerini hazırlamamız gerekir. Test paketindeki tüm test mesajlarımı yapılandırabilmek için Messaging API'sini taklit etmeye karar verdim. İşte testlerimizin nasıl yapılandırıldığını gösteren test takımımın bir parçası.
// ... 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" }) } }); }); // ...
Hataları Yakalamak
Bu basit ifadeleri uygulamak oldukça hızlı bir şekilde karşılığını veriyor. Test takımımızla ne tür böcekleri yakalayabileceğimize bakalım.
Stil Sorunu
İşte CSS kod tabanımızda bir şeyler ters gittiğinde ve bunun sonucunda tüm mesajlar aynı arka planda işlendiğinde bir örnek.

Bu ekran görüntüsünü orijinaliyle karşılaştırırsanız, son mesajın beyaz bir arka plana sahip olduğunu ve açık mavi olması gerektiğini fark edeceksiniz. Galen'in bu sorunu nasıl bildirdiğini görelim:

Vurgulanan nesne için, color #e1e8f5 on “messenger.message-3” is 0% but it should be greater than 60%
. Dürüst olmak gerekirse, bu hata mesajı o kadar net görünmüyor, ancak bu kontrol özel bir kuraldan oluşturulduğundan, orijinal adını her zaman bir rapor dalında arayabiliriz:

Yukarı kaydırırsanız, orijinal ifadenin &third_message should be styled as own message
. Bu, özel ifadeler kullanmanın bir başka avantajıdır: Hatayı anlamanıza ve oluşturulan tüm bu doğrulamaları güzel bir şekilde tanımlamanıza yardımcı olurlar.
Konumlandırma Sorunu
Bir öğenin yanlış hizalanması nedeniyle yerleşimin ne zaman yanlış gittiğine dair başka bir örnek. Aşağıdaki ekran görüntüsünde, son mesajın mesajlaşma görünümünün sağ yerine sol tarafına yerleştirildiğini görebilirsiniz.

Hata mesajını içeren ekran görüntüsüne tekrar bakalım:

Ekran görüntüsü, mesajlaşma kapsayıcısını ve son mesaj öğesini vurgular. Bununla birlikte, aşağıdaki hata mesajını gösterir: “messenger.message-3” is 285px right which is not in range of 22 to 28px
. Sağ tarafta neden 22 ila 28 piksellik bir marj beklendiği bir web geliştiricisi için net olmayabilir. Yine, rapor dalında bir doğrulama ifadesi aramanız gerekir:

Bu kontrol için orijinal ifade &third_message should be located at the right inside messenger with ~ 25px margin
. Bu çok daha mantıklı. Ayrıca, diğer ön uç mühendisleri, testleri yazmamış olsalar bile bu test raporunu anlayacaktır.
Düzen Testi Yönergeleri
Tüm bu farklı deneyleri göz önünde bulundurarak, tüm öğrenmeyi genel yerleşim testi yönergelerinde resmileştirmeye karar verdim. Test rutininizi kolaylaştırmak için izlemeniz gereken adımların hızlı bir kontrol listesi.
- Tasarımdaki düzen kalıplarını tanımlayın.
- Doğrulama ifadelerini genelleştirin. Çoğu doğrulamayı tek cümlelerde toplamaya çalışın.
- Bileşenleştir! Tekrarlanan öğelerin testlerini özel bileşenlere taşımak her zaman daha iyidir.
- Bölümler, kurallar ve nesneler için anlamlı adlar kullanın.
- Piksellerden kaçının. Piksel değerlerini (tam değerler veya aralıklar) anlamlı değişkenlerle değiştirmeye çalışın.
- Test etmeyi kolaylaştırmak için web sitenizin kodunu ayarlayın. Bu, hem üretim hem de test kodunuzu yapılandırmanıza ve korumanıza yardımcı olacaktır.
Kurtarmaya Kabul Kriterleri
Sıklıkla, "Bir düzen testi ne kadar ayrıntılı olmalı? Ve özellikle neyi test etmeliyiz?” Genel bir cevap vermek zor. Sorun, testin kapsamı küçük olduğunda, hataları gözden kaçırmanızdır. Öte yandan, çok ayrıntılı testleriniz varsa, çok sayıda yanlış pozitif alabilirsiniz ve gelecekte test bakımında kaybolabilirsiniz. Yani bir takas var. Ama kendim için genel bir kılavuz buldum. Çalışmayı daha küçük kullanıcı hikayelerine bölerseniz, bir sayfanın tasarımını kabul kriterleri şeklinde yapılandırmak daha kolay hale gelir. Sonunda, bu kabul kriterlerini doğrudan test kodunuza koyabilirsiniz. Örneğin, bu ifadelerden bazıları, önceki tüm kod örneklerinde gösterildiği gibi, özel kurallar biçiminde tanımlanabilir. Kabul kriterlerine iyi bir örnek şöyle olabilir:
- Pop-up'lar ekranda dikey ve yatay olarak ortalanmalıdır.
- 400 piksel genişliğinde olmalıdırlar.
- Düğmeler yatay olarak hizalanmalıdır.
- Ve bunun gibi
Tasarımı basit cümlelerle tanımladığınızda, bunları yeniden kullanılabilir ifadelere dönüştürmek ve test kodunuzu düzenlemek daha kolay hale gelir.
Çözüm
Gördüğünüz gibi, böyle bir alıştırma, bir tasarımı yapılandırmanıza ve birden çok sayfa bileşeni arasında paylaşılabilen genel düzen kalıplarını keşfetmenize yardımcı olur. Sayfa karmaşık olsa ve birçok öğeden oluşsa bile, bunları düzen ifadelerinizde gruplandırmanın bir yolunu her zaman bulabilirsiniz. Bu yaklaşımla, yerleşim testi daha çok test odaklı geliştirme için bir araç haline gelir ve özellikle çevik bir ortamda yararlı olan yazılımları aşamalı olarak tasarlamanıza, uygulamanıza ve teslim etmenize yardımcı olur.
Kaynaklar
- Galen Çerçevesi (resmi web sitesi)
- Galen Çerçevesi, GitHub
- Galen Ekstraları (kütüphane), GitHub
- Galen Önyükleme, GitHub
- “Galen Çerçeve Eğitimleri,” YouTube