Açıölçer - Hızlı Kılavuz
Bu bölüm size, bu test çerçevesinin kökenini ve neden bunu seçmeniz gerektiğini, bu aracın çalışması ve sınırlamaları hakkında bilgi edinebileceğiniz Açıölçer'e bir giriş sunar.
Açıölçer nedir?
İletki, Angular ve AngularJS uygulamaları için açık kaynaklı bir uçtan uca test çerçevesidir. Google tarafından WebDriver'ın üstüne oluşturulmuştur. Ayrıca, "Angular Scenario Runner" adı verilen mevcut AngularJS E2E test çerçevesinin yerine geçer.
Aynı zamanda NodeJS, Selenium, Jasmine, WebDriver, Cucumber, Mocha gibi güçlü teknolojileri birleştiren bir çözüm entegratörü olarak çalışır. AngularJS uygulamasının test edilmesinin yanı sıra normal web uygulamaları için otomatik regresyon testleri de yazar. Uygulamamızı gerçek bir kullanıcı gibi test etmemize olanak tanır çünkü testi gerçek bir tarayıcı kullanarak çalıştırır.
Aşağıdaki şema Açıölçerin kısa bir özetini verecektir -
Yukarıdaki diyagramda elimizde -
Protractor - Daha önce tartışıldığı gibi, özellikle açısal uygulamalar için tasarlanmış WebDriver JS üzerinde bir sarmalayıcıdır.
Jasmine- Temelde JavaScript kodunu test etmek için davranışa dayalı bir geliştirme çerçevesidir. Jasmine ile testleri rahatlıkla yazabiliyoruz.
WebDriver JS - Selenium 2.0 / WebDriver için bir Node JS bağlama uygulamasıdır.
Selenium - Tarayıcıyı otomatikleştirir.
Menşei
Daha önce de belirtildiği gibi, Açıölçer, "Açısal Senaryo Çalıştırıcısı" adı verilen mevcut AngularJS E2E test çerçevesinin yerini almıştır. Temel olarak, Açıölçer'in kökeni, Senaryo Koşucusu'nun sonuyla başlar. Burada ortaya çıkan bir soru, neden Açıölçer inşa etmemiz gerektiğidir? Bunu anlamak için önce selefi olan Scenario Runner'ı kontrol etmemiz gerekiyor.
Açıölçerin Başlangıç
Protractor'ın geliştirilmesine en büyük katkıda bulunan Julie Ralph, Google'daki başka bir projede Angular Scenario Runner ile aşağıdaki deneyime sahipti. Bu, özellikle boşlukları doldurmak için Açıölçer inşa etmenin motivasyonu oldu -
"Scenario Runner'ı kullanmayı denedik ve gerçekten test etmemiz gereken şeyleri yapamadığını gördük. Giriş yapmak gibi şeyleri test etmemiz gerekiyordu. Giriş sayfanız Açısal bir sayfa değil ve Senaryo Çalıştırıcısı bununla başa çıkamadı. Ve pop-up'lar ve birden çok pencere gibi şeylerle, tarayıcı geçmişinde gezinirken, bunun gibi şeylerle başa çıkamadı. "
Açıölçer için en büyük avantajı Selenium projesinin olgunlaşması ve Angular projelerinde rahatlıkla kullanılabilecek şekilde yöntemlerini tamamlamasıdır. Protractor'ın tasarımı, bir uygulamanın web kullanıcı arayüzü, arka uç hizmetleri, kalıcılık katmanı vb. Gibi tüm katmanları test edecek şekilde oluşturulmuştur.
Neden Açıölçer?
Neredeyse tüm uygulamaların geliştirme için JavaScript kullandığını biliyoruz. JavaScript'in boyutu büyüdüğünde test uzmanlarının görevi zorlaşır ve uygulamaların sayısının artması nedeniyle uygulamalar için karmaşık hale gelir. Çoğu zaman, JUnit veya Selenium WebDriver kullanarak AngularJS uygulamalarında web öğelerini yakalamak çok zor hale gelir, web uygulama bileşenlerini ifade etmek için genişletilmiş HTML sözdizimi kullanır.
Buradaki soru, Selenium Web Driver'ın AngularJS web öğelerini neden bulamamasıdır? Bunun nedeni, AngularJS uygulamalarının Selenium yer belirleyicilerinde bulunmayan ng-tekrarlayıcı, ng-denetleyici ve ng-modeli gibi bazı genişletilmiş HTML özniteliklerine sahip olmasıdır.
Burada, Açıölçerin önemi ortaya çıkıyor çünkü Selenium'un tepesindeki İletki, AngularJS web uygulamalarındaki bu genişletilmiş HTML öğelerini işleyebilir ve kontrol edebilir. Bu nedenle çerçevelerin çoğunun AngularJS uygulamaları için birim testleri yapmaya odaklandığını söyleyebiliriz, Protractor bir uygulamanın gerçek işlevselliğini test ederdi.
Açıölçerin Çalışması
Test çerçevesi olan Protractor, bir kullanıcının tarayıcıda veya mobil cihazda çalışan bir AngularJS uygulamasıyla etkileşimini simüle etmek için otomatik bir test altyapısı sağlamak üzere Selenium ile birlikte çalışır.
Açıölçerin çalışması aşağıdaki adımların yardımıyla anlaşılabilir -
Step 1- İlk adımda testleri yazmamız gerekiyor. Yasemin, Mocha veya Salatalık yardımı ile yapılabilir.
Step 2- Şimdi Protractor yardımıyla yapılabilecek testi çalıştırmamız gerekiyor. Aynı zamanda test koşucusu olarak da adlandırılır.
Step 3 - Bu adımda Selenium sunucusu tarayıcıları yönetmeye yardımcı olacaktır.
Step 4 - Sonunda, tarayıcı API'leri Selenium WebDriver yardımıyla çalıştırılır.
Avantajlar
Bu açık kaynaklı uçtan uca test çerçevesi aşağıdaki avantajları sunar:
Açık kaynaklı bir araç olan Protractor'ın kurulumu ve kurulumu çok kolaydır.
Testi oluşturmak için Jasmine çerçevesiyle iyi çalışır.
Test odaklı geliştirmeyi (TDD) destekler.
Otomatik beklemeler içerir, bu da testimize açıkça beklemeler ve uykular eklememiz gerekmediği anlamına gelir.
Selenium WebDriver'ın tüm avantajlarını sunar.
Birden çok tarayıcı üzerinden paralel testi destekler.
Otomatik senkronizasyonun faydasını sağlar.
Mükemmel test hızına sahiptir.
Sınırlamalar
Bu açık kaynaklı uçtan uca test çerçevesi aşağıdaki sınırlamalara sahiptir:
WebDriver JS için bir sarmalayıcı olduğu için tarayıcı otomasyonunda herhangi bir dikey ortaya çıkarmaz.
JavaScript bilgisi kullanıcı için önemlidir, çünkü sadece JavaScript için mevcuttur.
Kullanıcı arayüzü odaklı bir test aracı olduğu için yalnızca ön uç testi sağlar.
Protractor ile çalışmak için JavaScript bilgisi gerekli olduğundan, bu bölümde JavaScript testi kavramlarını ayrıntılı olarak anlayalım.
JavaScript Testi ve Otomasyon
JavaScript, dinamik olarak yazılmış ve yorumlanan en popüler betik dilidir, ancak en zorlu görev kodu test etmektir. Bunun nedeni, JAVA ve C ++ gibi diğer derlenmiş dillerin aksine, JavaScript'te test edenin hataları anlamasına yardımcı olabilecek hiçbir derleme adımı olmamasıdır. Ayrıca, tarayıcı tabanlı testler çok zaman alır; dolayısıyla, JavaScript için otomatik testi destekleyen araçlara ihtiyaç vardır.
Otomatik Test Kavramları
Kodu daha iyi hale getirdiği için testi yazmak her zaman iyi bir uygulamadır; manuel test ile ilgili sorun, biraz zaman alıcı ve hataya açık olmasıdır. Manuel test süreci programcılar için de oldukça sıkıcıdır çünkü süreci tekrarlamaları, test özelliklerini yazmaları, kodu değiştirmeleri ve tarayıcıyı birkaç kez yenilemeleri gerekir. Ayrıca manuel test, geliştirme sürecini de yavaşlatır.
Yukarıdaki nedenlerden dolayı, bu testleri otomatikleştirebilecek ve programcıların bu tekrarlayan ve sıkıcı adımlardan kurtulmasına yardımcı olabilecek bazı araçlara sahip olmak her zaman yararlıdır. Test sürecini otomatik hale getirmek için geliştirici ne yapmalıdır?
Temel olarak, bir geliştirici araç setini CLI (Komut Satırı Yorumlayıcı) veya geliştirme IDE (Entegre geliştirme ortamı) içinde uygulayabilir. Daha sonra bu testler, geliştiricinin girdisi olmasa bile ayrı bir işlemde sürekli olarak çalışacaktır. JavaScript'in otomatik olarak test edilmesi de yeni değildir ve Karma, Açıölçer, CasperJS vb. Gibi birçok araç geliştirilmiştir.
JavaScript için Test Türleri
Farklı amaçlar için farklı testler olabilir. Örneğin, bazı testler bir programdaki işlevlerin davranışını kontrol etmek için yazılırken, bazıları bir modül veya özelliğin akışını test etmek için yazılır. Bu nedenle, aşağıdaki iki tür testimiz var -
Birim Testi
Test, birim adı verilen programın test edilebilir en küçük bölümünde yapılır. Ünite, temelde, o ünitenin diğer parçalara herhangi bir bağımlılığı olmaksızın, izole olarak test edilir. JavaScript söz konusu olduğunda, belirli bir davranışa sahip bireysel yöntem veya işlev bir kod birimi olabilir ve bu kod birimleri yalıtılmış bir şekilde test edilmelidir.
Birim testinin avantajlarından biri, birimlerin birbirinden bağımsız olması nedeniyle birimlerin testinin herhangi bir sırada yapılabilmesidir. Gerçekten önemli olan birim testinin bir diğer avantajı, testi herhangi bir zamanda aşağıdaki şekilde çalıştırabilmesidir -
- Geliştirme sürecinin en başından itibaren.
- Herhangi bir modülün / özelliğin geliştirilmesini tamamladıktan sonra.
- Herhangi bir modülü / özelliği değiştirdikten sonra.
- Mevcut uygulamaya herhangi bir yeni özellik ekledikten sonra.
JavaScript uygulamalarının otomatik birim testi için Mocha, Jasmine ve QUnit gibi birçok test aracı ve çerçevesinden seçim yapabiliriz.
Uçtan Uca Test
Uygulama akışının baştan sona (bir uçtan diğer uca) tasarıma göre iyi çalışıp çalışmadığını test etmek için kullanılan test metodolojisi olarak tanımlanabilir.
Uçtan uca test, işlev / akış testi olarak da adlandırılır. Birim testinden farklı olarak, uçtan-uca test, tek tek bileşenlerin bir uygulama olarak birlikte nasıl çalıştığını test eder. Bu, birim testi ile uçtan uca test arasındaki temel farktır.
Örneğin, kullanıcının kaydı tamamlamak için bazı geçerli bilgiler sağlaması gereken bir kayıt modülümüz varsa, o zaman o modül için E2E testi testi tamamlamak için aşağıdaki adımları izleyecektir -
- İlk olarak, formu veya modülü yükleyecek / derleyecektir.
- Şimdi, form öğelerinin DOM'sunu (Belge nesne modeli) alacak.
- Ardından, çalışıp çalışmadığını kontrol etmek için gönder düğmesinin tıklama olayını tetikleyin.
- Şimdi, doğrulama amacıyla giriş alanlarından değeri toplayın.
- Daha sonra, giriş alanları doğrulanmalıdır.
- Test amacıyla, verileri depolamak için sahte bir API çağırın.
Her adım, beklenen sonuç kümesiyle karşılaştırılacak kendi sonuçlarını verir.
Şimdi, ortaya çıkan soru şu ki, bu tür E2E veya fonksiyonel testler manuel olarak da yapılabilirken, bunun için neden otomasyona ihtiyacımız var? Bunun ana nedeni, otomasyonun bu test sürecini kolaylaştıracak olmasıdır. Herhangi bir uygulama ile kolayca entegre edilebilen mevcut araçlardan bazıları, bu amaçla Selenium, PhantomJS ve Protractor'dur.
Test Araçları ve Çerçeveleri
Açısal test için çeşitli test araçlarımız ve çerçevelerimiz var. Aşağıdakiler, iyi bilinen araçlardan ve çerçevelerden bazılarıdır -
Karma
Vojta Jina tarafından yaratılan Karma, bir test koşucusu. Başlangıçta bu proje Testacular olarak adlandırıldı. Bu bir test çerçevesi değildir, yani bize gerçek tarayıcılarda JavaScript birim testlerini kolayca ve otomatik olarak çalıştırma yeteneği verir. Karma, AngularJS için oluşturuldu çünkü Karma'dan önce web tabanlı JavaScript geliştiricileri için otomatik test aracı yoktu. Öte yandan, Karma tarafından sağlanan otomasyonla, geliştiriciler basit tek bir komut çalıştırabilir ve tüm bir test paketinin başarılı olup olmadığını belirleyebilir.
Karma kullanmanın artıları
Aşağıdakiler, manuel işleme kıyasla Karma kullanmanın bazı avantajlarıdır -
- Birden çok tarayıcıda ve cihazda testleri otomatikleştirir.
- Dosyaları hatalara karşı izler ve düzeltir.
- Çevrimiçi destek ve dokümantasyon sağlar.
- Sürekli bir bütünleştirme sunucusuyla entegrasyonu kolaylaştırır.
Karma Kullanmanın Eksileri
Aşağıdakiler Karma kullanmanın bazı dezavantajlarıdır -
Karma kullanmanın temel dezavantajı, yapılandırma ve bakım için ek bir araç gerektirmesidir.
Jasmine ile Karma test çalıştırıcısı kullanıyorsanız, bir öğe için birden çok kimliğiniz olması durumunda CSS'nizi kurma hakkında bilgi bulmak için daha az belge mevcuttur.
Yasemin
JavaScript kodunu test etmek için davranış odaklı bir geliştirme çerçevesi olan Jasmine, Pivotal Labs'ta geliştirildi. Jasmine çerçevesinin aktif olarak geliştirilmesinden önce, dahili bir test çalıştırıcısı olan Pivotal Labs tarafından JsUnit adlı benzer bir birim test çerçevesi de geliştirildi. Tarayıcı testleri, SpecRunner.html dosyası dahil edilerek veya bir komut satırı test çalıştırıcısı olarak kullanılarak Jasmine testleri aracılığıyla çalıştırılabilir. Karma ile veya Karma olmadan da kullanılabilir.
Yasemin Kullanmanın Artıları
Aşağıdakiler Jasmine'i kullanmanın bazı artılarıdır -
Tarayıcı, platform ve dilden bağımsız bir çerçeve.
Davranış odaklı geliştirmeyle birlikte test odaklı geliştirmeyi (TDD) destekler.
Karma ile varsayılan entegrasyona sahiptir.
Sözdizimini anlamak kolay.
Ek işlevler olarak test etmeye yardımcı olan test casusları, sahteler ve geçiş işlevleri sağlar.
Yasemin Kullanmanın Eksileri
Aşağıdaki, Jasmine'i kullanmanın bir aleyhidir -
Jasmine'de test çalıştırılırken dosya izleme özelliği bulunmadığından testler değiştikçe kullanıcı tarafından iade edilmelidir.
Mocha
Node.js uygulamaları için yazılan Mocha, bir test çerçevesidir ancak tarayıcı testini de destekler. Oldukça Jasmine'e benziyor ancak aralarındaki en büyük fark, Mocha'nın bazı eklentilere ve kitaplığa ihtiyaç duyması çünkü tek başına bir test çerçevesi olarak çalışamıyor. Öte yandan, Jasmine bağımsızdır. Bununla birlikte, Mocha, Jasmine'den daha esnektir.
Mocha kullanmanın artıları
Aşağıdakiler Mocha kullanmanın bazı avantajlarıdır -
- Mocha'nın kurulumu ve yapılandırması çok kolaydır.
- Kullanıcı dostu ve basit dokümantasyon.
- Birkaç düğüm projesine sahip eklentiler içerir.
Mocha kullanmanın eksileri
Aşağıdakiler Mocha kullanmanın bazı dezavantajlarıdır -
- İddialar, casuslar vb. İçin ayrı modüllere ihtiyaç duyar.
- Ayrıca Karma ile kullanmak için ek yapılandırma gerektirir.
QUnit
İlk olarak 2008 yılında John Resig tarafından jQuery'nin bir parçası olarak geliştirilen QUint, güçlü ancak kullanımı kolay bir JavaScript birim test paketidir. Herhangi bir genel JavaScript kodunu test etmek için kullanılabilir. Tarayıcıda JavaScript'i test etmeye odaklanmasına rağmen, geliştirici tarafından kullanılması çok uygundur.
QUnit kullanmanın avantajları
Aşağıdakiler, QUnit kullanmanın bazı avantajlarıdır -
- Kurulumu ve yapılandırması kolaydır.
- Kullanıcı dostu ve basit dokümantasyon.
QUnit kullanmanın eksileri
Aşağıdaki, QUnit kullanmanın bir kuraldır -
- Esas olarak jQuery için geliştirilmiştir ve bu nedenle diğer çerçevelerle kullanım için o kadar iyi değildir.
Selenyum
İlk olarak 2004 yılında Jason Huggins tarafından ThoughtWorks'te dahili bir araç olarak geliştirilen Selenium, açık kaynaklı bir test otomasyon aracıdır. Selenium kendisini “Selenium tarayıcıları otomatikleştirir. Bu kadar!". Tarayıcıların otomasyonu, geliştiricilerin tarayıcılarla çok kolay etkileşim kurabileceği anlamına gelir.
Selenium kullanmanın artıları
Aşağıdakiler Selenium kullanmanın bazı artılarıdır -
- Büyük özellik seti içerir.
- Dağıtılmış testi destekler.
- Sauce Labs gibi hizmetler aracılığıyla SaaS desteğine sahiptir.
- Mevcut basit belgeler ve zengin kaynaklarla kullanımı kolaydır.
Selenyum kullanmanın eksileri
Aşağıdakiler Selenium kullanmanın bazı dezavantajlarıdır -
- Selenium kullanmanın temel bir dezavantajı, ayrı bir işlem olarak çalıştırılması gerektiğidir.
- Geliştiricinin birkaç adımı izlemesi gerektiğinden yapılandırma biraz zahmetlidir.
Önceki bölümlerde Açıölçer'in temellerini öğrendik. Bu bölümde, onu nasıl kurup yapılandıracağımızı öğrenelim.
Önkoşullar
Bilgisayarınıza İletki kurmadan önce aşağıdaki ön koşulları yerine getirmemiz gerekiyor -
Node.js
İletki bir Node.js modülüdür, dolayısıyla en önemli ön koşul, bilgisayarımızda Node.js'nin kurulu olması gerektiğidir. Node.js ile birlikte gelen npm (JavaScript paket yöneticisi) kullanarak Protractor paketini kuracağız.
Node.js yüklemek için lütfen resmi bağlantıyı izleyin - https://nodejs.org/en/download/. Node.js'yi kurduktan sonra, komutu yazarak Node.js ve npm sürümlerini kontrol edebilirsiniz.node --version ve npm --version aşağıda gösterildiği gibi komut isteminde -
Krom
Google tarafından oluşturulmuş bir web tarayıcısı olan Google Chrome, bir Selenium sunucusuna ihtiyaç duymadan Protractor'da uçtan uca testleri çalıştırmak için kullanılacaktır. Bağlantıya tıklayarak kromu indirebilirsiniz -https://www.google.com/chrome/.
Selenium WebDriver Chrome için
Bu araç, Protractor npm modülü ile sağlanır ve web uygulamalarıyla etkileşim kurmamızı sağlar.
Açıölçer Yükleme
Bilgisayarımıza Node.js'yi kurduktan sonra aşağıdaki komut yardımıyla İletki kurabiliriz -
npm install -g protractor
İletki başarıyla yüklendikten sonra, sürümünü yazarak kontrol edebiliriz protractor --version komut isteminde aşağıda gösterildiği gibi komut -
Chrome için WebDriver'ı Yükleme
Protractor'ı kurduktan sonra, Selenium WebDriver for Chrome'u kurmamız gerekiyor. Aşağıdaki komutun yardımıyla kurulabilir -
webdriver-manager update
Yukarıdaki komut, projede kullanılan gerekli Chrome sürücüsünü içeren bir Selenium dizini oluşturacaktır.
Kurulum ve Yapılandırmayı Onaylama
Protractor'ı kurduktan sonra örnekte verilen conf.js'yi biraz değiştirerek Protractor kurulumunu ve yapılandırmasını onaylayabiliriz. Bu conf.js dosyasını kök dizinde bulabilirsiniznode_modules/Protractor/example.
Bunun için önce aynı dizinde testconfig.js adlı yeni bir dosya oluşturun yani node_modules/Protractor/example.
Şimdi, conf.js dosyasında, kaynak dosya bildirim parametresi altında testconfig.js yazın.
Ardından, tüm dosyaları kaydedip kapatın ve komut istemini açın. Aşağıdaki ekran görüntüsünde gösterildiği gibi conf.js dosyasını çalıştırın.
Çıktıyı aşağıda gösterildiği gibi alırsanız, İletki yapılandırması ve kurulumu başarılıdır -
Yukarıdaki çıktı, conf.js dosyasında kaynak dosya bildirim parametresinde boş dosyayı sağladığımız için belirtim olmadığını gösterir. Ancak yukarıdaki çıktıdan, hem iletki hem de WebDriver'ın başarılı bir şekilde çalıştığını görebiliriz.
Kurulum ve yapılandırmadaki sorunlar
İletki ve WebDriver'ı kurarken ve yapılandırırken, aşağıdaki yaygın sorunlarla karşılaşabiliriz -
Selenium doğru yüklenmemiş
WebDriver'ı kurarken en sık karşılaşılan sorundur. Bu sorun, WebDriver'ı güncellemezseniz ortaya çıkar. WebDriver'ı güncellememiz gerektiğini unutmayın, aksi takdirde onu İletki kurulumuna atıfta bulunamayız.
Testleri bulamıyorum
Diğer bir yaygın sorun da Açıölçer çalıştırdıktan sonra testleri bulamadığını göstermesidir. Bunun için ilgili yolların, dosya adlarının veya uzantıların doğru olduğundan emin olmalıyız. Ayrıca conf.js dosyasını çok dikkatli bir şekilde yazmamız gerekiyor çünkü konfigürasyon dosyası ile başlıyor.
Daha önce tartışıldığı gibi, Protractor, Angular ve AngularJS uygulamaları için açık kaynaklı, uçtan uca bir test çerçevesidir. Node.js programıdır. Öte yandan Selenium, Selenium Sunucusunu, WebDriver API'lerini ve WebDriver tarayıcı sürücülerini içeren bir tarayıcı otomasyon çerçevesidir.
Selenyum ile açıölçer
Açıölçer ve Selenium'un birleşiminden bahsedersek, İletki otomatik bir test altyapısı sağlamak için Selenium sunucusu ile çalışabilir. Altyapı, kullanıcının bir tarayıcıda veya mobil cihazda çalışan açısal bir uygulama ile etkileşimini simüle edebilir. İletki ve Selenium birleşimi, aşağıdaki şemada gösterildiği gibi test, sunucu ve Tarayıcı olmak üzere üç bölüme ayrılabilir -
Selenium WebDriver İşlemleri
Yukarıdaki şemada gördüğümüz gibi, Selenium WebDriver kullanarak yapılan bir test aşağıdaki üç işlemi içerir -
- Test komut dosyaları
- Sunucu
- Tarayıcı
Bu bölümde, bu üç süreç arasındaki iletişimi tartışalım.
Test Komut Dosyaları ve Sunucu arasındaki iletişim
İlk iki süreç arasındaki iletişim - test komut dosyaları ve sunucu, Selenium Sunucusunun çalışmasına bağlıdır. Yani Selenium sunucunun çalışma şeklinin test betikleri ile sunucu arasındaki iletişim sürecine şekil vereceğini söyleyebiliriz.
Selenium server, makinemizde tek başına Selenium Server (selenium-server-standalone.jar) olarak lokal olarak çalışabilir veya bir servis (Sauce Labs) aracılığıyla uzaktan çalıştırılabilir. Bağımsız bir Selenium sunucusu olması durumunda, Node.js ile selenyum sunucusu arasında bir http iletişimi olacaktır.
Sunucu ve tarayıcı arasındaki iletişim
Sunucunun, komutları test komut dosyalarından yorumladıktan sonra tarayıcıya iletmekten sorumlu olduğunu biliyoruz. Bu nedenle sunucu ve tarayıcı da bir iletişim ortamına ihtiyaç duyar ve burada iletişim,JSON WebDriver Wire Protocol. Tarayıcı, komutları yorumlamak için kullanılan Tarayıcı Sürücüsü ile genişletildi.
Selenium WebDriver süreçleri ve bunların iletişimi ile ilgili yukarıdaki kavram, aşağıdaki şema yardımıyla anlaşılabilir -
Protractor ile çalışırken, ilk işlem olan test betiği Node.js kullanılarak çalıştırılır, ancak tarayıcıda herhangi bir işlem gerçekleştirmeden önce, test edilen uygulamanın stabilize olduğundan emin olmak için fazladan bir komut gönderir.
Selenium Sunucuyu Kurmak
Selenium Server, test komut dizimiz ile tarayıcı sürücüsü arasında bir proxy sunucusu gibi davranır. Temel olarak komutu test komut dosyamızdan WebDriver'a iletir ve WebDriver'dan gelen yanıtları test komut dosyamıza döndürür. Selenium sunucusunu kurmak için aşağıdaki seçenekler vardır.conf.js test komut dosyası dosyası -
Bağımsız Selenium Sunucu
Sunucuyu yerel makinemizde çalıştırmak istiyorsak, bağımsız selenyum sunucu kurmamız gerekiyor. Bağımsız selenyum sunucusunu kurmanın ön koşulu, JDK'dır (Java Geliştirme Kiti). Yerel makinemizde JDK'nın kurulu olması gerekir. Komut satırından aşağıdaki komutu çalıştırarak kontrol edebiliriz -
java -version
Artık Selenium Server'ı manuel olarak veya test komut dizisinden kurma ve başlatma seçeneğimiz var.
Selenium sunucusunu manuel olarak kurmak ve başlatmak
Selenium sunucusunu manuel olarak kurmak ve başlatmak için, Protractor ile birlikte gelen WebDriver-Manager komut satırı aracını kullanmamız gerekir. Selenium sunucusunu kurma ve başlatma adımları aşağıdaki gibidir -
Step 1- İlk adım, Selenium sunucusunu ve ChromeDriver'ı kurmaktır. Aşağıdaki komutu çalıştırarak yapılabilir -
webdriver-manager update
Step 2- Sonra, sunucuyu başlatmamız gerekiyor. Aşağıdaki komutu çalıştırarak yapılabilir -
webdriver-manager start
Step 3- Sonunda yapılandırma dosyasındaki seleniumAddress'i çalışan sunucunun adresine ayarlamamız gerekiyor. Varsayılan adreshttp://localhost:4444/wd/hub.
Selenium sunucusunu bir Test Komut Dosyasından başlatma
Selenium sunucusunu bir Test Komut Dosyasından başlatmak için, yapılandırma dosyamızda aşağıdaki seçenekleri ayarlamamız gerekir -
Location of jar file - seleniumServerJar'ı ayarlayarak yapılandırma dosyasında bağımsız Selenium sunucusu için jar dosyasının konumunu ayarlamamız gerekiyor.
Specifying the port- Bağımsız Selenium Sunucuyu başlatmak için kullanılacak bağlantı noktasını da belirlememiz gerekir. SeleniumPort ayarlanarak yapılandırma dosyasında belirtilebilir. Varsayılan bağlantı noktası 4444'tür.
Array of command line options- Sunucuya geçmek için komut satırı seçenekleri dizisini de ayarlamamız gerekiyor. SeleniumArgs ayarlanarak yapılandırma dosyasında belirtilebilir. Komut dizilerinin tam listesine ihtiyacınız varsa, sunucuyu-help bayrak.
Uzak Selenium Sunucusuyla Çalışma
Testimizi çalıştırmak için başka bir seçenek de Selenium sunucusunu uzaktan kullanmaktır. Sunucuyu uzaktan kullanmanın ön koşulu, sunucuyu barındıran bir hizmete sahip bir hesabımız olması gerektiğidir. Protractor ile çalışırken, sunucuyu barındıran aşağıdaki hizmetler için yerleşik desteğe sahibiz -
TestObject
TestObject'i uzak Selenium Sunucusu olarak kullanmak için, TestObject hesabımızın kullanıcı adı olan testobjectUser'ı ve TestObject hesabımızın API anahtarı olan testobjectKey'i ayarlamamız gerekir.
BrowserStack
BrowserStack'i uzak Selenium Sunucusu olarak kullanmak için, BrowserStack hesabımızın kullanıcı adı olan browserstackUser'ı ve BrowserStack hesabımızın API anahtarı olan browserstackKey'i ayarlamamız gerekir.
Sos Laboratuvarları
Sos Laboratuvarlarını uzak Selenium Sunucusu olarak kullanmak için, Sauce Labs hesabımızın kullanıcı adı olan SauceUser'ı ve Sauce Labs hesabımızın API anahtarı olan SauceKey'i ayarlamamız gerekir.
Kobiton
Kobiton'u uzak Selenium Sunucusu olarak kullanmak için kobitonUser'ı, Kobiton hesabımızın kullanıcı adını ve Kobiton hesabımızın API anahtarı olan kobitonKey'i ayarlamamız gerekir.
Selenium Sunucusu kullanmadan doğrudan Tarayıcı Sürücüsüne bağlanma
Testimizi çalıştırmak için bir başka seçenek de Selenium sunucusunu kullanmadan Tarayıcı Sürücüsüne doğrudan bağlanmaktır. İletki, yapılandırma dosyasında directConnect: true ayarını yaparak, Selenium Sunucusu kullanmadan, Chrome ve Firefox'a karşı doğrudan test yapabilir.
Tarayıcıyı Kurmak
Tarayıcıyı yapılandırmadan ve kurmadan önce, hangi tarayıcıların Protractor tarafından desteklendiğini bilmemiz gerekir. Aşağıda, Protractor tarafından desteklenen tarayıcıların listesi verilmiştir -
- ChromeDriver
- FirefoxDriver
- SafariDriver
- IEDriver
- Appium-iOS/Safari
- Appium-Android/Chrome
- Selendroid
- PhantomJS
Tarayıcıyı ayarlamak ve yapılandırmak için, Protractor yapılandırma dosyasına geçmemiz gerekir çünkü tarayıcı kurulumu yapılandırma dosyasının yetenekler nesnesi dahilinde yapılır.
Chrome'u Kurma
Chrome Tarayıcıyı kurmak için, yetenekler nesnesini aşağıdaki gibi ayarlamamız gerekir
capabilities: {
'browserName': 'chrome'
}
Ayrıca chromeOptions'a yerleştirilmiş Chrome'a özgü seçenekleri ekleyebiliriz ve tam listesi şu adreste görülebilir: https://sites.google.com/a/chromium.org/chromedriver/capabilities.
Örneğin, sağ üst tarafa FPS sayacı eklemek istiyorsanız, yapılandırma dosyasında aşağıdaki gibi yapılabilir -
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': ['show-fps-counter=true']
}
},
Firefox kurulumu
Firefox tarayıcısını kurmak için, yetenekler nesnesini aşağıdaki gibi ayarlamamız gerekir -
capabilities: {
'browserName': 'firefox'
}
Ayrıca moz: firefoxOptions nesnesine yerleştirilmiş Firefox'a özgü seçenekler de ekleyebiliriz ve tam listesi şu adreste görülebilir: https://github.com/mozilla/geckodriver#firefox-capabilities.
Örneğin, testinizi Firefox'ta güvenli modda çalıştırmak istiyorsanız, yapılandırma dosyasında aşağıdaki gibi yapılabilir -
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': ['—safe-mode']
}
},
Başka bir tarayıcı kurma
Chrome veya Firefox dışında herhangi bir tarayıcı kurmak için, şuradan ayrı bir ikili program yüklememiz gerekir: https://docs.seleniumhq.org/download/.
PhantonJS'yi kurma
Aslında PhantomJS, çökme sorunları nedeniyle artık desteklenmiyor. Bunun yerine başsız Chrome veya başsız Firefox kullanmanız önerilir. Aşağıdaki gibi kurulabilirler -
Başsız Chrome'u kurmak için, Chrome'u aşağıdaki gibi başsız işaretiyle başlatmamız gerekir -
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': [“--headless”, “--disable-gpu”, “--window-size=800,600”]
}
},
Başsız Firefox kurmak için Firefox'u şu şekilde başlatmalıyız: –headless aşağıdaki gibi bayrak -
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': [“--headless”]
}
},
Test için birden fazla tarayıcı kurma
Ayrıca birden fazla tarayıcıda test edebiliriz. Bunun için multiCapabilities yapılandırma seçeneğini aşağıdaki gibi kullanmamız gerekiyor -
multiCapabilities: [{
'browserName': 'chrome'
},{
'browserName': 'firefox'
}]
Hangi Çerçeve?
İki BDD (Davranış odaklı geliştirme) test çerçevesi, Jasmine ve Mocha, Protractor tarafından desteklenmektedir. Her iki çerçeve de JavaScript ve Node.js tabanlıdır. Testlerin yazılması ve yönetilmesi için gerekli olan sözdizimi, rapor ve yapı iskelesi bu çerçeveler tarafından sağlanır.
Sonra, çeşitli çerçeveleri nasıl kurabileceğimizi görüyoruz -
Yasemin çerçevesi
İletki için varsayılan test çerçevesidir. Protractor'ı kurduğunuzda, onunla birlikte Jasmine 2.x sürümünü de alacaksınız. Ayrı olarak kurmamıza gerek yok.
Mocha çerçevesi
Mocha, temelde Node.js üzerinde çalışan başka bir JavaScript test çerçevesidir. Mocha'yı test çerçevemiz olarak kullanmak için BDD (Davranış odaklı geliştirme) arayüzünü ve Chai As Promised ile Chai iddialarını kullanmamız gerekiyor. Kurulum aşağıdaki komutlar yardımıyla yapılabilir -
npm install -g mocha
npm install chai
npm install chai-as-promised
Gördüğünüz gibi mocha'yı kurarken -g seçeneği kullanılıyor, bunun nedeni Protractor'ı -g seçeneğini kullanarak global olarak kurmuş olmamızdır. Kurduktan sonra, test dosyalarımızın içinde Chai'yi zorunlu kılmamız ve kurmamız gerekiyor. Aşağıdaki gibi yapılabilir -
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
Bundan sonra, Chai As Promised'ı bu şekilde kullanabiliriz -
expect(myElement.getText()).to.eventually.equal('some text');
Şimdi, framework: 'mocha' ekleyerek çerçeve özelliğini config dosyasının mocha olarak ayarlamamız gerekiyor. Mocha için 'muhabir' ve 'yavaş' gibi seçenekler yapılandırma dosyasına aşağıdaki gibi eklenebilir -
mochaOpts: {
reporter: "spec", slow: 3000
}
Salatalık Çerçevesi
Salatalık'ı test çerçevemiz olarak kullanmak için, bunu çerçeve seçeneğiyle Açıölçer ile entegre etmemiz gerekir. custom. Kurulum aşağıdaki komutlar yardımı ile yapılabilir
npm install -g cucumber
npm install --save-dev protractor-cucumber-framework
Gördüğünüz gibi Cucumber kurulurken -g seçeneği kullanılıyor, bunun nedeni Protractor'ı global olarak yani -g seçeneğiyle kurmuş olmamızdır. Daha sonra, çerçeve özelliğini şu şekilde ayarlamamız gerekiyor:custom cucumberConf.js adlı yapılandırma dosyasına framework: 'custom' ve frameworkPath: 'Protractor-cucumber-framework' ekleyerek yapılandırma dosyası oluşturun.
Aşağıda gösterilen örnek kod, Salatalık özellik dosyalarını Protractor ile çalıştırmak için kullanılabilen basit bir cucumberConf.js dosyasıdır -
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl: 'https://angularjs.org/',
capabilities: {
browserName:'Firefox'
},
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
specs: [
'./cucumber/*.feature'
],
// cucumber command line options
cucumberOpts: {
require: ['./cucumber/*.js'],
tags: [],
strict: true,
format: ["pretty"],
'dry-run': false,
compiler: []
},
onPrepare: function () {
browser.manage().window().maximize();
}
};
Bu bölümde, Açıölçer'de ilk testi nasıl yazacağımızı anlayalım.
Açıölçer tarafından istenen dosyalar
İletki çalıştırmak için aşağıdaki iki dosyaya ihtiyaç duyar -
Spec veya test dosyası
Protractor'ı çalıştırmak için önemli dosyalardan biridir. Bu dosyaya gerçek test kodumuzu yazacağız. Test kodu, test çerçevemizin sözdizimi kullanılarak yazılmıştır.
Örneğin, kullanıyorsak Jasmine çerçeve, daha sonra test kodu sözdizimi kullanılarak yazılacaktır. Jasmine. Bu dosya, testin tüm işlevsel akışlarını ve iddialarını içerecektir.
Basit bir deyişle, bu dosyanın uygulama ile etkileşime girecek mantığı ve bulucuları içerdiğini söyleyebiliriz.
Misal
Aşağıda, bir URL'ye gitmek ve sayfa başlığını kontrol etmek için test senaryosuna sahip basit bir TestSpecification.js komut dosyası verilmiştir -
//TestSpecification.js
describe('Protractor Demo', function() {
it('to check the page title', function() {
browser.ignoreSynchronization = true;
browser.get('https://www.tutorialspoint.com/tutorialslibrary.htm');
browser.driver.getTitle().then(function(pageTitle) {
expect(pageTitle).toEqual('Free Online Tutorials and Courses');
});
});
});
Kod Açıklama
Yukarıdaki şartname dosyasının kodu şu şekilde açıklanabilir -
Tarayıcı
Protractor tarafından tüm tarayıcı seviyesindeki komutları işlemek için oluşturulan global değişkendir. Temelde bir WebDriver örneğinin etrafındaki bir sarmalayıcıdır. browser.get (), Açıölçer'e belirli bir sayfayı yüklemesini söyleyen basit bir Selenium yöntemidir.
describe ve it- Her ikisi de Jasmine test çerçevesinin sözdizimleridir. ’Describe’ test durumumuzun uçtan uca akışını tutmak için kullanılırken ‘it’bazı test senaryolarını içerir. Birden fazla olabiliriz‘it’ test durumu programımızdaki bloklar.
Expect - Web sayfası başlığını önceden tanımlanmış bazı verilerle karşılaştırdığımız bir iddiadır.
ignoreSynchronization- Açısal olmayan web sitelerini test etmeye çalışacağımız zaman kullanılan bir tarayıcı etiketidir. İletki yalnızca açısal web siteleriyle çalışmayı bekler, ancak açısal olmayan web siteleriyle çalışmak istiyorsak, bu etiket şu şekilde ayarlanmalıdır:“true”.
Yapılandırma Dosyası
Adından da anlaşılacağı gibi, bu dosya tüm Açıölçer yapılandırma seçenekleri için açıklamalar sağlar. Temel olarak Açıölçer'e şunları söyler -
- Test veya teknik özellik dosyaları nerede bulunur
- Hangi tarayıcıyı seçmeli
- Hangi test çerçevesinin kullanılacağı
- Selenium Sunucusuyla nerede konuşmalı
Misal
Aşağıdaki basit komut dosyası, config.js,
// config.js
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['TestSpecification.js'],
Kod Açıklama
Üç temel parametreye sahip yukarıdaki konfigürasyon dosyasının kodu aşağıdaki gibi açıklanabilir -
Yetenekler Parametresi
Bu parametre, tarayıcının adını belirtmek için kullanılır. Conf.js dosyasının aşağıdaki kod bloğunda görülebilir -
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
Yukarıda görüldüğü gibi, burada verilen tarayıcının adı, Protractor için varsayılan tarayıcı olan 'chrome'dur. Tarayıcının adını da değiştirebiliriz.
Çerçeve Parametresi
Bu parametre, test çerçevesinin adını belirtmek için kullanılır. Config.js dosyasının aşağıdaki kod bloğunda görülebilir -
exports.config = {
directConnect: true,
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
Burada 'yasemin' test çerçevesini kullanıyoruz.
Kaynak Dosya Beyanı Parametresi
Bu parametre, kaynak dosya bildiriminin adını belirtmek için kullanılır. Conf.js dosyasının aşağıdaki kod bloğunda görülebilir -
exports.config = {
directConnect: true,
// Spec patterns are relative to the current working
directory when protractor is called.
specs: ['TsetSpecification.js'],
Yukarıda görüldüğü gibi, burada verilen kaynak dosya bildiriminin adı ‘TestSpecification.js’. Bunun nedeni, bu örnek için şartname dosyasını adıyla oluşturmuş olmamızdır.TestSpecification.js.
Kodu yürütmek
Protractor'ı çalıştırmak için gerekli dosyalar ve kodlamaları hakkında temel anlayışa sahip olduğumuz için, örneği çalıştırmaya çalışalım. Bu örneği yürütmek için aşağıdaki adımları takip edebiliriz -
Step 1 - İlk olarak, komut istemini açın.
Step 2 - Ardından, dosyalarımızı kaydettiğimiz dizine, yani config.js ve TestSpecification.js.
Step 3 - Şimdi, Protrcator config.js komutunu çalıştırarak config.js dosyasını çalıştırın.
Aşağıda gösterilen ekran görüntüsü, örneği yürütmek için yukarıdaki adımları açıklayacaktır -
Ekran görüntüsünde testin geçtiği görülüyor.
Şimdi, açısal olmayan web sitelerini test ediyorsak ve ignoreSynchronization etiketini doğru yapmıyorsak, kodu çalıştırdıktan sonra "Sayfada Açısal bulunamadı" hatasını alacağımızı varsayalım.
Aşağıdaki ekran görüntüsünde görülebilir -
Rapor oluşturma
Şimdiye kadar, test senaryolarını çalıştırmak için gerekli dosyalar ve bunların kodlanması hakkında tartıştık. Açıölçer ayrıca test durumları için rapor oluşturabilir. Bu amaçla Yasemin'i destekler. JunitXMLReporter, test yürütme raporlarını otomatik olarak oluşturmak için kullanılabilir.
Ama ondan önce, aşağıdaki komutun yardımıyla Jasmine muhabirini kurmamız gerekiyor -
npm install -g jasmine-reporters
Gördüğünüz gibi Jasmine Reporters kurulurken -g seçeneği kullanılıyor, bunun nedeni Protractor'ı global olarak -g seçeneğiyle kurmuş olmamızdır.
Jasmine-habercileri başarıyla kurduktan sonra, aşağıdaki kodu daha önce kullandığımız config.js dosyamıza eklememiz gerekiyor -
onPrepare: function(){ //configure junit xml report
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'guitest-xmloutput',
savePath: 'test/reports'
}));
Şimdi, yeni config.js dosyamız aşağıdaki gibi olacaktır -
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['TestSpecification.js'],
//framework: "jasmine2", //must set it if you use JUnitXmlReporter
onPrepare: function(){ //configure junit xml report
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'guitest-xmloutput',
savePath: 'reports'
}));
},
};
Yukarıdaki yapılandırma dosyasını aynı şekilde çalıştırdıktan sonra, daha önce çalıştırmıştık, raporu kök dizininin altında içeren bir XML dosyası oluşturacaktır. reportsKlasör. Test başarılı olursa, rapor aşağıdaki gibi görünecektir -
Ancak, test başarısız olursa, rapor aşağıda gösterildiği gibi görünecektir -
İletki - Core APIS
Bu bölüm, iletki işleyişinin anahtarı olan çeşitli temel API'leri anlamanıza olanak tanır.
İletki API'lerinin Önemi
İletki, web sitesinin mevcut durumunu elde etmek için aşağıdaki eylemleri gerçekleştirmek için çok önemli olan geniş bir API yelpazesi sunar -
- Test edeceğimiz web sayfasının DOM öğelerini almak.
- DOM öğeleriyle etkileşim.
- Onlara eylemler atamak.
- Onlarla bilgi paylaşmak.
Yukarıdaki görevleri gerçekleştirmek için, Açıölçer API'lerini anlamak çok önemlidir.
Çeşitli Açıölçer API'leri
İletki'nin Node.js için WebDriver bağlamaları olan Selenium-WebDriver etrafında bir sarmalayıcı olduğunu bildiğimiz gibi. İletki aşağıdaki API'lere sahiptir -
Tarayıcı
Gezinme, sayfa çapında bilgiler vb. Gibi tarayıcı düzeyinde komutları işlemek için kullanılan bir WebDriver örneğinin etrafındaki bir sarmalayıcıdır. Örneğin, browser.get yöntemi bir sayfayı yükler.
Eleman
Test ettiğimiz sayfadaki DOM öğesini aramak ve onunla etkileşim kurmak için kullanılır. Bu amaçla, elemanı bulmak için bir parametreye ihtiyaç duyar.
Konumlayıcılar (tarafından)
Öğe bulma stratejilerinin bir koleksiyonudur. Öğeler, örneğin, CSS seçici tarafından, ID ile veya ng-model ile bağlı oldukları diğer herhangi bir öznitelik ile bulunabilir.
Daha sonra, bu API'ler ve işlevleri hakkında ayrıntılı olarak tartışacağız.
Tarayıcı API
Yukarıda tartışıldığı gibi, tarayıcı seviyesindeki komutları işlemek için bir WebDriver örneği etrafında bir sarmalayıcıdır. Aşağıdaki gibi çeşitli işlevleri yerine getirir -
Fonksiyonlar ve Açıklamaları
ProtractorBrowser API'nin işlevleri aşağıdaki gibidir−
browser.angularAppRoot
Tarayıcı API'sinin bu işlevi, üzerinde Angular'ı bulacağımız bir öğe için CSS seçiciyi ayarlar. Genellikle, bu işlev 'body'de bulunur, ancak bizim ng-uygulamamız olması durumunda, sayfanın bir alt bölümünde yer alır; aynı zamanda bir alt eleman da olabilir.
browser.waitForAngularEnabled
Tarayıcı API'sinin bu işlevi doğru veya yanlış olarak ayarlanabilir. Adından da anlaşılacağı gibi, bu işlev yanlış olarak ayarlanmışsa, İletki Açısal$http and $tarayıcıyla etkileşim kurmadan önce tamamlanması gereken zaman aşımı görevleri. Bir değer iletmeden waitForAngularEnabled () 'ı çağırarak mevcut durumu değiştirmeden de okuyabiliriz.
browser.getProcessedConfig
Bu tarayıcı API'leri işlevinin yardımıyla, şu anda çalıştırılmakta olan spesifikasyon ve yetenekler dahil, işlenmiş yapılandırma nesnesini elde edebiliriz.
browser.forkNewDriverInstance
Adından da anlaşılacağı gibi, bu işlev etkileşimli testlerde kullanılmak üzere başka bir tarayıcı örneğini çatallayacaktır. Kontrol akışı etkin ve devre dışı bırakılarak çalıştırılabilir. Her iki durum için örnek aşağıda verilmiştir -
Example 1
Koşu browser.forkNewDriverInstance() kontrol akışı etkinken -
var fork = browser.forkNewDriverInstance();
fork.get(‘page1’);
Example 2
Koşu browser.forkNewDriverInstance() kontrol akışı devre dışı bırakılmış -
var fork = await browser.forkNewDriverInstance().ready;
await forked.get(‘page1’);
browser.restart
Adından da anlaşılacağı gibi, tarayıcı örneğini kapatarak ve yenisini oluşturarak tarayıcıyı yeniden başlatacaktır. Kontrol akışı etkin ve devre dışı olarak da çalışabilir. Her iki durum için örnek aşağıda verilmiştir -
Example 1 - Koşu browser.restart() kontrol akışı etkinken -
browser.get(‘page1’);
browser.restart();
browser.get(‘page2’);
Example 2 - Koşu browser.forkNewDriverInstance() kontrol akışı devre dışı bırakılmış -
await browser.get(‘page1’);
await browser.restart();
await browser.get(‘page2’);
browser.restartSync
Browser.restart () işlevine benzer. Tek fark, yeni tarayıcı örneğine çözümleme sözü vermek yerine yeni tarayıcı örneğini doğrudan döndürmesidir. Yalnızca kontrol akışı etkinleştirildiğinde çalışabilir.
Example - Koşu browser.restartSync() kontrol akışı etkinken -
browser.get(‘page1’);
browser.restartSync();
browser.get(‘page2’);
browser.useAllAngular2AppRoots
Adından da anlaşılacağı gibi, yalnızca Angular2 ile uyumludur. Öğeleri bulurken veya kararlılığı beklerken sayfada bulunan tüm açısal uygulamaları arayacaktır.
browser.waitForAngular
Bu tarayıcı API işlevi, WebDriver'a Angular'ın oluşturmayı bitirmesini ve hiçbir $http or $Devam etmeden önce zaman aşımı çağrıları.
browser.findElement
Adından da anlaşılacağı gibi, bu tarayıcı API işlevi, öğe aramadan önce Angular'ın işlemeyi bitirmesini bekler.
browser.isElementPresent
Adından da anlaşılacağı gibi, bu tarayıcı API işlevi öğenin sayfada bulunup bulunmadığını test edecektir.
browser.addMockModule
Protractor.get yöntemi her çağrıldığında Angular'dan önce yüklenecek bir modül ekleyecektir.
Example
browser.addMockModule('modName', function() {
angular.module('modName', []).value('foo', 'bar');
});
browser.clearMockModules
browser.addMockModule'den farklı olarak, kayıtlı sahte modüllerin listesini temizleyecektir.
browser.removeMockModule
Adından da anlaşılacağı gibi, bir yazmaç sahte modülleri kaldıracaktır. Örnek: browser.removeMockModule ('modName');
browser.getRegisteredMockModules
Browser.clearMockModule'ün tersine, kayıtlı sahte modüllerin listesini alacaktır.
browser.get
Tarayıcıda belirli bir web adresine gitmek için browser.get () kullanabiliriz ve Angular yüklemeden önce o sayfa için sahte modülleri yükleyebiliriz.
Example
browser.get(url);
browser.get('http://localhost:3000');
// This will navigate to the localhost:3000 and will load mock module if needed
browser.refresh
Adından da anlaşılacağı gibi, bu mevcut sayfayı yeniden yükleyecek ve Angular'dan önce sahte modülleri yükleyecektir.
browser.navigate
Adından da anlaşılacağı gibi, gezinme yöntemlerini daha önce olduğu gibi çağrılmaları için gezinme nesnesine geri karıştırmak için kullanılır. Örnek: driver.navigate (). Renew ().
browser.setLocation
Sayfa içi navigasyonu kullanarak başka bir sayfaya göz atmak için kullanılır.
Example
browser.get('url/ABC');
browser.setLocation('DEF');
expect(browser.getCurrentUrl())
.toBe('url/DEF');
ABC'den DEF sayfasına gidecektir.
browser.debugger
Adından da anlaşılacağı gibi, bu, iletki hata ayıklama ile kullanılmalıdır. Bu işlev, temelde testi duraklatmak ve tarayıcıya yardımcı işlevleri enjekte etmek için kontrol akışına bir görev ekler, böylece hata ayıklama tarayıcı konsolunda yapılabilir.
browser.pause
WebDriver testlerinde hata ayıklamak için kullanılır. Kullanabilirizbrowser.pause() Testimizde, kontrol akışındaki bu noktadan iletki hata ayıklayıcısına girmek için.
Example
element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();
browser.controlFlowEnabled
Kontrol akışının etkinleştirilip etkinleştirilmediğini belirlemek için kullanılır.
İletki - Core APIS (CONTD…)
Bu bölümde, Protractor'ın bazı temel API'lerini öğrenelim.
Elements API
Öğe, iletki tarafından açığa çıkan global işlevlerden biridir. Bu işlev bir konum belirleyiciyi alır ve aşağıdakini döndürür -
- Konumlandırıcıya göre tek bir öğe bulan ElementFinder.
- Konumlandırıcıya göre bir dizi öğe bulan ElementArrayFinder.
Yukarıdaki her ikisi de aşağıda tartışıldığı gibi zincirleme yöntemlerini destekler.
ElementArrayFinder'ın zincirleme fonksiyonları ve açıklamaları
Aşağıdakiler, ElementArrayFinder'ın işlevleridir -
element.all(locator).clone
Adından da anlaşılacağı gibi, bu işlev elemanlar dizisinin yüzeysel bir kopyasını oluşturur, yani ElementArrayFinder.
element.all(locator).all(locator)
Bu işlev temelde boş olabilecek veya alt öğeleri içeren yeni bir ElementArrayFinder döndürür. Aşağıdaki gibi bir dizi olarak birden fazla eleman seçmek için kullanılabilir
Example
element.all(locator).all(locator)
elementArr.all(by.css(‘.childselector’));
// it will return another ElementFindArray as child element based on child locator.
element.all(locator).filter(filterFn)
Adından da anlaşılacağı gibi, ElementArrayFinder içindeki her bir öğeye filtre işlevi uyguladıktan sonra, filtre işlevini geçen tüm öğeleri içeren yeni bir ElementArrayFinder döndürür. Temelde iki argümana sahip, birincisi ElementFinder ve ikincisi indeks. Sayfa nesnelerinde de kullanılabilir.
Example
View
<ul class = "items">
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
Code
element.all(by.css('.items li')).filter(function(elem, index) {
return elem.getText().then(function(text) {
return text === 'Third';
});
}).first().click();
element.all(locator).get(index)
Bunun yardımıyla ElementArrayFinder içinde indeks ile bir eleman elde edebiliriz. Endeksin 0'dan başladığını ve negatif endekslerin sarıldığını unutmayın.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');
element.all(locator).first()
Adından da anlaşılacağı gibi, bu ElementArrayFinder için ilk öğeyi alacaktır. Altta yatan öğeyi almayacaktır.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');
element.all(locator).last()
Adından da anlaşılacağı gibi, bu ElementArrayFinder için son öğeyi alacaktır. Altta yatan öğeyi almayacaktır.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let first = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');
element.all(locator).all(selector)
$$ çağrıları zincirlendiğinde bir ebeveyn içindeki bir dizi öğeyi bulmak için kullanılır.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).$$('li');
element.all(locator).count()
Adından da anlaşılacağı gibi, bu ElementArrayFinder tarafından temsil edilen elemanların sayısını sayacaktır. Altta yatan öğeyi almayacaktır.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let list = element.all(by.css('.items li'));
expect(list.count()).toBe(3);
element.all(locator).isPresent()
Öğeleri bulucu ile eşleştirecektir. Doğru veya yanlış olarak dönebilir. Doğru, bulucu ile eşleşen herhangi bir öğe varsa, aksi takdirde Yanlış.
Example
expect($('.item').isPresent()).toBeTruthy();
element.all(locator).locator
Adından da anlaşılacağı gibi, en alakalı konum belirleyiciyi döndürecektir.
Example
$('#ID1').locator();
// returns by.css('#ID1')
$('#ID1').$('#ID2').locator();
// returns by.css('#ID2')
$$('#ID1').filter(filterFn).get(0).click().locator();
// returns by.css('#ID1')
element.all(locator).then(thenFunction)
ElementArrayFinder tarafından temsil edilen öğeleri alır.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).then(function(arr) {
expect(arr.length).toEqual(3);
});
element.all(locator).each(eachFunction)
Adından da anlaşılacağı gibi, ElementArrayFinder tarafından temsil edilen her ElementFinder'da input fonksiyonunu çağıracaktır.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).each(function(element, index) {
// It will print First 0, Second 1 and Third 2.
element.getText().then(function (text) {
console.log(index, text);
});
});
element.all(locator).map(mapFunction)
Adından da anlaşılacağı gibi, ElementArrayFinder içindeki her elemana bir eşleme işlevi uygulayacaktır. İki argümanı var. Birincisi ElementFinder ve ikincisi indeks olacaktır.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let items = element.all(by.css('.items li')).map(function(elm, index) {
return {
index: index,
text: elm.getText(),
class: elm.getAttribute('class')
};
});
expect(items).toEqual([
{index: 0, text: 'First', class: 'one'},
{index: 1, text: 'Second', class: 'two'},
{index: 2, text: 'Third', class: 'three'}
]);
element.all(locator).reduce(reduceFn)
Adından da anlaşılacağı gibi, bir akümülatöre ve konumlandırıcı kullanılarak bulunan her öğeye karşı bir azaltma işlevi uygulayacaktır. Bu işlev, her öğeyi tek bir değere indirgeyecektir.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
return elem.getText().then(function(text) {
return acc + text + ' ';
});
}, '');
expect(value).toEqual('First Second Third ');
element.all(locator).evaluate
Adından da anlaşılacağı gibi, girdiyi mevcut temel unsurların kapsamında olup olmadığını değerlendirecektir.
Example
View
<span class = "foo">{{letiableInScope}}</span>
Code
let value =
element.all(by.css('.foo')).evaluate('letiableInScope');
element.all(locator).allowAnimations
Adından da anlaşılacağı gibi, animasyona mevcut temel öğelerde izin verilip verilmediğini belirleyecektir.
Example
element(by.css('body')).allowAnimations(false);
ElementFinder'ın zincirleme fonksiyonları ve açıklamaları
ElementFinder'ın zincirleme fonksiyonları ve açıklamaları -
element(locator).clone
Adından da anlaşılacağı gibi, bu işlev ElementFinder'ın sığ bir kopyasını oluşturacaktır.
element(locator).getWebElement()
Bu ElementFinder tarafından temsil edilen WebElement'i döndürür ve öğe yoksa bir WebDriver hatası atılır.
Example
View
<div class="parent">
some text
</div>
Code
// All the four following expressions are equivalent.
$('.parent').getWebElement();
element(by.css('.parent')).getWebElement();
browser.driver.findElement(by.css('.parent'));
browser.findElement(by.css('.parent'));
element(locator).all(locator)
Bir ebeveyn içinde bir dizi öğe bulacaktır.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).all(by.tagName('li'));
element(locator).element(locator)
Bir ebeveynin içindeki öğeleri bulacaktır.
Example
View
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
// Calls Chain 2 element.
let child = element(by.css('.parent')).
element(by.css('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');
// Calls Chain 3 element.
let triple = element(by.css('.parent')).
element(by.css('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).all(selector)
$$ çağrıları zincirlendiğinde ebeveyn içinde bir dizi öğe bulacaktır.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).$$('li'));
element(locator).$(locator)
$ 'A yapılan çağrılar zincirlendiğinde ebeveyn içindeki öğeleri bulur.
Example
View
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
// Calls Chain 2 element.
let child = element(by.css('.parent')).
$('.child')); expect(child.getText()).toBe('Child text\n981-000-568'); // Calls Chain 3 element. let triple = element(by.css('.parent')). $('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).isPresent()
Öğenin sayfada gösterilip gösterilmeyeceğini belirleyecektir.
Example
View
<span>{{person.name}}</span>
Code
expect(element(by.binding('person.name')).isPresent()).toBe(true);
// will check for the existence of element
expect(element(by.binding('notPresent')).isPresent()).toBe(false);
// will check for the non-existence of element
element(locator).isElementPresent()
Öğe (yer belirleyici) .isPresent () ile aynıdır. Tek fark, alt konumlandırıcı tarafından tanımlanan elemanın mevcut eleman bulucu yerine mevcut olup olmadığını kontrol edecek olmasıdır.
element.all(locator).evaluate
Adından da anlaşılacağı gibi, girdiyi mevcut temel unsurların kapsamında olup olmadığını değerlendirecektir.
Example
View
<span id = "foo">{{letiableInScope}}</span>
Code
let value = element(by.id('.foo')).evaluate('letiableInScope');
element(locator).allowAnimations
Adından da anlaşılacağı gibi, animasyona mevcut temel öğelerde izin verilip verilmediğini belirleyecektir.
Example
element(by.css('body')).allowAnimations(false);
element(locator).equals
Adından da anlaşılacağı gibi, eşitlik için bir unsuru karşılaştıracaktır.
Konumlayıcılar (API'ye göre)
Temel olarak, Angular uygulamalarda öğeleri bağlama, model vb. Yoluyla bulmanın yollarını sağlayan öğe konum belirleme stratejilerinin bir koleksiyonudur.
Functions and their descriptions
ProtractorLocators API'nin işlevleri aşağıdaki gibidir -
by.addLocator(locatorName,fuctionOrScript)
Bu ProtrcatorBy örneğine, öğeyle (by.locatorName (args)) kullanılabilecek bir yer belirleyici ekleyecektir.
Example
View
<button ng-click = "doAddition()">Go!</button>
Code
// Adding the custom locator.
by.addLocator('buttonTextSimple',
function(buttonText, opt_parentElement, opt_rootSelector) {
var using = opt_parentElement || document,
buttons = using.querySelectorAll('button');
return Array.prototype.filter.call(buttons, function(button) {
return button.textContent === buttonText;
});
});
element(by.buttonTextSimple('Go!')).click();// Using the custom locator.
by.binding
Adından da anlaşılacağı gibi, metin bağlama yoluyla bir öğe bulacaktır. Girdi dizesini içeren değişkenlere bağlı tüm elemanların döndürülmesi için kısmi bir eşleşme yapılacaktır.
Example
View
<span>{{person.name}}</span>
<span ng-bind = "person.email"></span>
Code
var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Foo');
var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('[email protected]');
by.exactbinding
Adından da anlaşılacağı gibi, tam bağlama ile bir öğe bulacaktır.
Example
View
<spangt;{{ person.name }}</spangt;
<span ng-bind = "person-email"gt;</spangt;
<spangt;{{person_phone|uppercase}}</span>
Code
expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
by.model(modelName)
Adından da anlaşılacağı gibi, ng modeli ifadesine göre bir öğe bulacaktır.
Example
View
<input type = "text" ng-model = "person.name">
Code
var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Foo123');
by.buttonText
Adından da anlaşılacağı gibi, metinle bir düğme bulacaktır.
Example
View
<button>Save</button>
Code
element(by.buttonText('Save'));
by.partialButtonText
Adından da anlaşılacağı gibi, kısmi metinle bir düğme bulacaktır.
Example
View
<button>Save my file</button>
Code
element(by.partialButtonText('Save'));
by.repeater
Adından da anlaşılacağı gibi, bir ng-tekrarının içinde bir öğe bulacaktır.
Example
View
<div ng-repeat = "cat in pets">
<span>{{cat.name}}</span>
<span>{{cat.age}}</span>
<</div>
<div class = "book-img" ng-repeat-start="book in library">
<span>{{$index}}</span>
</div>
<div class = "book-info" ng-repeat-end>
<h4>{{book.name}}</h4>
<p>{{book.blurb}}</p>
</div>
Code
var secondCat = element(by.repeater('cat in
pets').row(1)); // It will return the DIV for the second cat.
var firstCatName = element(by.repeater('cat in pets').
row(0).column('cat.name')); // It will return the SPAN for the first cat's name.
by.exactRepeater
Adından da anlaşılacağı gibi, tam tekrarlayıcıyla bir eleman bulacaktır.
Example
View
<li ng-repeat = "person in peopleWithRedHair"></li>
<li ng-repeat = "car in cars | orderBy:year"></li>
Code
expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
.toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
by.cssContainingText
Adından da anlaşılacağı gibi, tam dizeyi içeren öğeleri CSS ile bulacaktır.
Example
View
<ul>
<li class = "pet">Dog</li>
<li class = "pet">Cat</li>
</ul>
Code
var dog = element(by.cssContainingText('.pet', 'Dog'));
// It will return the li for the dog, but not for the cat.
by.options(optionsDescriptor)
Adından da anlaşılacağı gibi ng-options ifadesine göre bir eleman bulacaktır.
Example
View
<select ng-model = "color" ng-options = "c for c in colors">
<option value = "0" selected = "selected">red</option>
<option value = "1">green</option>
</select>
Code
var allOptions = element.all(by.options('c for c in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('red');
by.deepCSS(selector)
Adından da anlaşılacağı gibi, gölge DOM içinde CSS seçici ile bir öğe bulacaktır.
Example
View
<div>
<span id = "outerspan">
<"shadow tree">
<span id = "span1"></span>
<"shadow tree">
<span id = "span2"></span>
</>
</>
</div>
Code
var spans = element.all(by.deepCss('span'));
expect(spans.count()).toEqual(3);
Açıölçer - Nesneler
Bu bölüm, Açıölçer'deki nesneler hakkında ayrıntılı olarak tartışır.
Sayfa Nesneleri nedir?
Sayfa nesnesi, test bakımını geliştirmek ve kod tekrarını azaltmak için e2e testleri yazmak için popüler hale gelen bir tasarım modelidir. AUT'nizin (test edilen uygulama) bir sayfasına arayüz görevi gören nesne yönelimli bir sınıf olarak tanımlanabilir. Ancak, sayfa nesnelerine derinlemesine dalmadan önce, otomatik kullanıcı arayüzü testindeki zorlukları ve bunlarla başa çıkmanın yollarını anlamamız gerekir.
Otomatik kullanıcı arayüzü testiyle ilgili zorluklar
Otomatikleştirilmiş kullanıcı arayüzü testiyle ilgili bazı yaygın zorluklar aşağıdadır -
UI Değişiklikleri
UI testiyle çalışırken en yaygın sorunlar, kullanıcı arayüzünde gerçekleşen değişikliklerdir. Örneğin, çoğu zaman düğmeler veya metin kutuları vb. Genellikle değişir ve UI testi için sorunlar yaratır.
DSL (Etki Alanına Özgü Dil) desteği eksikliği
UI testiyle ilgili bir diğer sorun da DSL desteğinin olmamasıdır. Bu sorunla birlikte neyin test edildiğini anlamak çok zorlaşıyor.
Çok sayıda tekrar / Kod çoğaltma
UI testinde bir sonraki yaygın sorun, çok sayıda tekrar veya kod tekrarının olmasıdır. Aşağıdaki kod satırlarının yardımı ile anlaşılabilir -
element(by.model(‘event.name’)).sendKeys(‘An Event’);
element(by.model(‘event.name’)).sendKeys(‘Module 3’);
element(by.model(‘event.name’));
Zor bakım
Yukarıdaki zorluklar nedeniyle, bakım için baş ağrısına dönüşür. Bunun nedeni, tüm örnekleri bulmamız, yeni ad, seçici ve diğer kodla değiştirmemiz gerektiğidir. Ayrıca testleri yeniden düzenleme ile uyumlu tutmak için çok zaman harcamamız gerekiyor.
Kırık testler
UI testindeki bir diğer zorluk, testlerde çok sayıda başarısızlık olmasıdır.
Zorluklarla Başa Çıkmanın Yolları
UI testinin bazı yaygın zorluklarını gördük. Bu tür zorluklarla baş etmenin yollarından bazıları aşağıdaki gibidir:
Referansları Manuel Olarak Güncelleme
Yukarıdaki zorlukların üstesinden gelmek için ilk seçenek, referansları manuel olarak güncellemektir. Bu seçenekteki sorun, testlerimizin yanı sıra kodda da manuel değişikliği yapmamız gerektiğidir. Bu, bir veya iki test dosyanız olduğunda yapılabilir, ancak ya bir projede yüzlerce test dosyanız varsa?
Sayfa Nesnelerini Kullanma
Yukarıdaki zorlukların üstesinden gelmek için başka bir seçenek, sayfa nesnelerini kullanmaktır. Bir sayfa nesnesi, temelde bir Angular şablonun özelliklerini kapsayan düz bir JavaScript'tir. Örneğin, aşağıdaki özellik dosyası, farkı anlamak için sayfa nesneleri olmadan ve sayfa nesneleriyle birlikte yazılmıştır -
Without Page Objects
describe('angularjs homepage', function() {
it('should greet the named user', function() {
browser.get('http://www.angularjs.org');
element(by.model('yourName')).sendKeys('Julie');
var greeting = element(by.binding('yourName'));
expect(greeting.getText()).toEqual('Hello Julie!');
});
});
With Page Objects
Kodu Sayfa Nesneleri ile yazmak için yapmamız gereken ilk şey bir Sayfa Nesnesi oluşturmaktır. Dolayısıyla, yukarıdaki örnek için bir Sayfa Nesnesi şöyle görünebilir -
var AngularHomepage = function() {
var nameInput = element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get = function() {
browser.get('http://www.angularjs.org');
};
this.setName = function(name) {
nameInput.sendKeys(name);
};
this.getGreetingText = function() {
return greeting.getText();
};
};
module.exports = new AngularHomepage();
Testleri Organize Etmek İçin Sayfa Nesnelerini Kullanma
UI testinin zorluklarının üstesinden gelmek için yukarıdaki örnekte sayfa nesnelerinin kullanıldığını gördük. Daha sonra, testleri düzenlemek için bunları nasıl kullanabileceğimizi tartışacağız. Bunun için test komut dosyasının işlevselliğini değiştirmeden test komut dosyasını değiştirmemiz gerekir.
Misal
Bu kavramı anlamak için yukarıdaki konfigürasyon dosyasını sayfa nesneleriyle alıyoruz. Test komut dosyasını aşağıdaki gibi değiştirmemiz gerekiyor -
var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
it('should greet the named user', function() {
angularHomepage.get();
angularHomepage.setName('Julie');
expect(angularHomepage.getGreetingText()).toEqual
('Hello Julie!');
});
});
Burada, sayfa nesnesine giden yolun belirtiminize göre olacağını unutmayın.
Aynı notta, test paketimizi çeşitli test gruplarına ayırabiliriz. Konfigürasyon dosyası daha sonra aşağıdaki gibi değiştirilebilir
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Spec patterns are relative to the location of the spec file. They may
// include glob patterns.
suites: {
homepage: 'tests/e2e/homepage/**/*Spec.js',
search: ['tests/e2e/contact_search/**/*Spec.js',
'tests/e2e/venue_search/**/*Spec.js']
},
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
}
};
Şimdi, bir veya diğer test paketini çalıştırmak arasında kolayca geçiş yapabiliriz. Aşağıdaki komut, testin yalnızca ana sayfa bölümünü çalıştıracaktır -
protractor protractor.conf.js --suite homepage
Benzer şekilde, aşağıdaki komutla belirli test paketlerini çalıştırabiliriz -
protractor protractor.conf.js --suite homepage,search
İletki - Hata Ayıklama
Artık, İletki'nin tüm kavramlarını önceki bölümlerde gördüğümüze göre, bu bölümde hata ayıklama kavramlarını ayrıntılı olarak anlayalım.
Giriş
Uçtan uca (e2e) testlerinde hata ayıklamak çok zordur çünkü bunlar, o uygulamanın tüm ekosistemine bağlıdırlar. Çeşitli eylemlere bağlı olduklarını gördük veya özellikle oturum açma gibi önceki eylemlere ve bazen de izne bağlı olduklarını söyleyebiliriz. E2e testlerinde hata ayıklamadaki bir diğer zorluk, farklı işletim sistemleri ve tarayıcılarla farklı şekilde hareket ettiği için WebDriver'a bağımlı olmasıdır. Son olarak, e2e testlerinde hata ayıklama ayrıca uzun hata mesajları üretir ve tarayıcıyla ilgili sorunları ayırmayı ve işlem hatalarını test etmeyi zorlaştırır.
Arıza Türleri
Test paketlerinin başarısız olmasının çeşitli nedenleri olabilir ve aşağıdakiler iyi bilinen bazı hata türleridir -
WebDriver hatası
Bir komut tamamlanamadığında, WebDriver tarafından bir hata atılır. Örneğin, bir tarayıcı tanımlanan adresi alamaz veya beklendiği gibi bir öğe bulunamaz.
WebDriver beklenmeyen hatası
Web sürücü yöneticisini güncelleyemediğinde, beklenmedik bir tarayıcı ve işletim sistemi ile ilgili bir arıza meydana gelir.
Angular için açıölçer hatası
Açıölçer için Açıölçer'in başarısızlığı, Açıölçer kütüphanede beklendiği gibi Açısal bulamadığında gerçekleşir.
Açıölçer Angular2 hatası
Bu tür bir hatada, İletki, yapılandırmada useAllAngular2AppRoots parametresi bulunamadığında başarısız olur. Bunun nedeni, bu olmadan, test sürecinin süreçte birden fazla öğe beklerken tek bir kök öğeye bakmasıdır.
Zaman aşımı için açıölçer hatası
Bu tür bir başarısızlık, test özelliği bir döngüye veya uzun bir havuza çarptığında ve verileri zamanında döndüremediğinde meydana gelir.
Beklenti hatası
Normal bir beklenti başarısızlığının neye benzediğini gösteren en yaygın test başarısızlıklarından biri.
Protractor'da hata ayıklama neden önemlidir?
Diyelim ki, test senaryoları yazdıysanız ve başarısız oldularsa, bu test senaryolarında nasıl hata ayıklanacağını bilmek çok önemlidir çünkü hatanın meydana geldiği yeri tam olarak bulmak çok zor olacaktır. Protractor ile çalışırken, komut satırında kırmızı renkli yazı tipinde bazı uzun hatalar alacaksınız.
Testi Duraklatma ve Hata Ayıklama
Protractor'da hata ayıklamanın yolları burada açıklanmıştır & miuns;
Duraklatma Yöntemi
Protractor'daki test senaryolarında hata ayıklamak için duraklatma yöntemini kullanmak en kolay yollardan biridir. Test kodumuzu duraklatmak istediğimiz yere aşağıdaki komutu yazabiliriz & miuns;
browser.pause();
Çalışan kodlar yukarıdaki komuta ulaştığında, o noktada çalışan programı duraklatacaktır. Bundan sonra tercihimize göre aşağıdaki komutları verebiliriz -
İleriye Gitmek için C Tipi
Bir komut ne zaman biterse, ilerlemek için C yazmalıyız. C yazmazsanız, test tam kodu çalıştırmaz ve Jasmine zaman aşımı hatası nedeniyle başarısız olur.
Etkileşimli moda girmek için repl yazın
Etkileşimli modun yararı, WebDriver komutlarını tarayıcımıza gönderebilmemizdir. Etkileşimli moda girmek istiyorsak, yazınrepl.
Testlerden çıkmak ve devam etmek için Ctrl-C yazın
Testten duraklatma durumundan çıkmak ve teste kaldığı yerden devam etmek için Ctrl-C yazmamız gerekir.
Misal
Bu örnekte, aşağıdaki spesifikasyon dosyasına sahibiz example_debug.js, iletki bulucu ile bir öğeyi tanımlamaya çalışır by.binding('mmmm') ancak URL (https://angularjs.org/ Sayfanın belirtilen konumlandırıcıya sahip öğesi yok.
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText =
element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
Şimdi, yukarıdaki testi yürütmek için yukarıdaki spesifikasyon dosyasında testi duraklatmak istediğiniz tarayıcı.pause () kodunu eklememiz gerekiyor. Aşağıdaki gibi görünecek -
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
browser.pause();
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText =
element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
Ancak çalıştırmadan önce, yapılandırma dosyasında da bazı değişiklikler yapmamız gerekiyor. Daha önce kullanılan yapılandırma dosyasında aşağıdaki değişiklikleri yapıyoruz.example_configuration.js önceki bölümde -
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['example_debug.js'],
allScriptsTimeout: 999999,
jasmineNodeOpts: {
defaultTimeoutInterval: 999999
},
onPrepare: function () {
browser.manage().window().maximize();
browser.manage().timeouts().implicitlyWait(5000);
}
};
Now, run the following command −
protractor example_configuration.js
The debugger will start after the above command.
Debugger Method
Using the pause method to debug the test cases in Protractor is a bit advanced way. We can type the following command at the place we want to break our test code −
browser.debugger();
It uses the node debugger to debug the test code. For running the above command, we must type the following command in a separate command prompt which has opened from the test project location −
protractor debug protractor.conf.js
In this method, we also need to type C in the terminal for continuing the test code. But opposite to pause method, in this method it is to be typed for only one time.
Example
In this example, we are using the same specification file named bexample_debug.js, used above. The only difference is that instead of browser.pause(), we need to use browser.debugger() where we want to break the test code. It will look as follows −
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
browser.debugger();
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText = element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
We are using the same configuration file, example_configuration.js, used in above example.
Now, run the protractor test with following debug command line option
protractor debug example_configuration.js
The debugger will start after the above command.
Protractor - Style Guide For Protractor
In this chapter, let us learn in detail about style guide for protractor.
Introduction
The style guide was created by two software engineers named, Carmen Popoviciu, front-end engineer at ING and Andres Dominguez, software engineer at Google. Hence, this style guide is also called Carmen Popoviciu and Google’s style guide for protractor.
This style guide can be divided into the following five keypoints −
- Generic rules
- Project Structure
- Locator strategies
- Page Objects
- Test suites
Generic Rules
The following are some generic rules that must be taken care while using protractor for testing −
Do not end-to-end test what has been already unit tested
This is the very first generic rule given by Carmen and Andres. They suggested that we must not perform e2e test on the code that already been unit tested. The main reason behind it is that the unit tests are much faster than e2e tests. Another reason is that we must have to avoid duplicate tests (don’t perform both unit and e2e testing) for saving our time.
Use only one configuration file
Another important point recommended is that we must have to use only one configuration file. Do not create configuration file for each environment you are testing. You can use grunt-protractor-coverage in order to set up different environments.
Avoid using logic to your test
We must have to avoid using IF statements or FOR loops in our test cases because if we do so then the test may pass without testing anything or it may run very slow.
Make the test independent at file level
Protractor can run the test parallelly when sharing is enabled. These files are then executed across different browsers as and when they become available. Carmen and Andres recommended to make the test independent at least at file level because the order in which they will be run by protractor is uncertain and moreover it is quite easy to run a test in isolation.
Project Structure
Another important key point regarding the style guide of Protractor is the structure of your project. The following is the recommendation about project structure −
Groping e2e test in a sensible structure
Carmen and Andres recommended that we must group our e2e tests in a structure that makes sense to the structure of your project. The reason behind this recommendation is that the finding of files would become easy and the folder structure would be more readable. This step will also separate e2e tests from unit tests. They recommended that the following kind of structure should be avoided −
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
home-page.js
home-spec.js
profile-page.js
profile-spec.js
contacts-page.js
contacts-spec.js
On the other hand, they recommended the following kind of structure −
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
|-- page-objects
home-page.js
profile-page.js
contacts-page.js
home-spec.js
profile-spec.js
contacts-spec.js
Locator Strategies
The following are some locator strategies that must be taken care while using protractor for testing −
Never use XPATH
This is the first locator strategies that is recommended in protractor style guide. The reasons behind the same is that XPath is requires lots of maintenance because markup is very easily subject to change. Moreover, XPath expressions are the slowest and very hard to debug.
Always prefer protractor-specific locators such as by.model and by.binding
Protractor-specific locators such as by.model and by.binding are short, specific and easy to read. With the help of them it is very easy to write our locator also.
Example
View
<ul class = "red">
<li>{{color.name}}</li>
<li>{{color.shade}}</li>
<li>{{color.code}}</li>
</ul>
<div class = "details">
<div class = "personal">
<input ng-model = "person.name">
</div>
</div>
For the above code, it is recommended to avoid the following −
var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
On the other hand, the following is recommended to use −
var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name'));
var personName = element(by.model('person.name'));
When no Protractor locators are available, then it is recommended to prefer by.id and by.css.
Always avoid text locators for frequently changing text
We must have to avoid text-based locators such as by.linkText, by.buttonText and by.cssContaningText because text for buttons, links and labels frequently change over time.
Page Objects
As discussed earlier, page objects encapsulate information about the elements on our application page and due to this help us write cleaner test cases. A very useful advantage of page objects is that they can be reused across multiple tests and in case if the template of our application has been changed, we only need to update the page object. Followings are some recommendations for page objects that must be taken care while using protractor for testing −
To interact with page under test, use page objects
It is recommended to use page objects to interact with the page under test because they can encapsulate information about the element on the page under test and they can be reused also.
Always declare one-page object per file
We should define each page object in its own file because it keeps the code clean and finding of things becomes easy.
At the end of page object file always uses a single module.exports
It is recommended that each page object should declare a single class so that we only need to export one class. For example, the following use of object file should be avoided −
var UserProfilePage = function() {};
var UserSettingsPage = function() {};
module.exports = UserPropertiesPage;
module.exports = UserSettingsPage;
But on the other hand, following is recommended to use −
/** @constructor */
var UserPropertiesPage = function() {};
module.exports = UserPropertiesPage;
Declare all the required modules at the top
We should declare all the required modules at the top of the page object because it makes module dependencies clear and easy to find.
Instantiate all page objects at the beginning of the test suite
It is recommended to instantiate all the page objects at the beginning of the test suite because this will separate dependencies from the test code as well as makes the dependencies available to all the specifications of the suite.
Do not use expect() in page objects
We should not use expect() in page objects i.e. we should not make any assertions in our page objects because all the assertions must be done in test cases.
Another reason is that the reader of the test should be able to understand the behavior of the application by reading the test cases only.