TypeScript Cypress Testlerinizdeki Her Şey #frontend@twiliosendgrid

Yayınlanan: 2020-11-14

Twilio SendGrid'de, daha iyi tip kontrolü, sürdürülebilirlik ve kod tabanımızın dokümantasyonu için bugün TypeScript ve React ile özellikle yeni sayfalar ve özellikler olmak üzere ön uç web uygulamalarımızın çoğunu yazıyoruz. İki yıldan uzun bir süre önce Cypress testleri yazmaya başladığımızda, sayfa nesnelerimizin, yardımcılarımızın ve spesifikasyon dosyalarımızın çoğu hala JavaScript'te uygulanıyordu ve çoğunlukla Cypress sürüm 3.xx'deydik Daha yeni testler TypeScript'te zaten yazılmıştı, ancak biz hala dönüştürülecek ve TypeScript'e geçirilecek çok sayıda dosya vardı.

Bileşenlerimizi, birim testlerimizi ve Cypress E2E testlerimizi tam olarak yazmanın faydalarından yararlanmak istedik . Süreci kolaylaştıran şey, Cypress 4.4.0'dan bu yana TypeScript desteğinden yararlanmak için Cypress'in daha yeni bir sürümüne geçiş yapmaktı.

Bir adım geri atmak ve daha genel olarak E2E testleri yazmayı nasıl düşüneceğinizi öğrenmek istiyorsanız, bu blog gönderisine göz atmaktan çekinmeyin. Farklı ortamlarda Cypress testleri yazarken daha önce kullandığımız veya yaptığımız en yaygın şeylere bin fitlik bir genel bakış da görmek isterseniz, Cypress testlerinize TypeScript eklemeye başlamadan önce bu blog gönderisine başvurabilirsiniz. Bu blog gönderisi, Cypress testlerine aşina olduğunuzu ve API'lerini daha önce kullandığınızı varsayar.

İşleri nasıl yazdığımızı görmeye hazırsanız, eski bir sürümden geliyorsanız Cypress'e TypeScript desteği eklemek gibi bazı ilk değişikliklere bakalım.

Cypress 3.x'ten >= 4.4.0'a geçiş

Cypress altyapılarını Cypress 3.xx ila 4.4.3 sürümlerinde TypeScript ile çalışacak şekilde yapılandırmış olanlar için, plugins/index.js uygun Webpack önişlemci yapılandırmasını kurarken büyük olasılıkla bazı deneme yanılmalarla karşılaşmışsınızdır. Twilio SendGrid ekibi için, plugins ve support klasörlerinde JavaScript dosyaları olması gereken belirli dosyalarla ilgili bazı sorunlar vardı ve hata ayıklaması zor Cypress hataları ortaya çıkıyordu. Çalışan bir şey aldığınızda, bunun gibi görünmelidir.


3.xx'in önceki bir sürümünden yükseltme yaptıktan sonra, Webpack önişlemci yapılandırmamızı kaldırabildik, plugins/index.js dosyamızı bir index.ts dosyasıyla değiştirebildik, Cypress klasörümüzün tsconfig.json dosyasıyla biraz kurcalayabildik ve son olarak, Cypress klasörümüzdeki TS dosyalarını kullanarak ( some_page.spec.ts , index.d.ts veya page_object.ts gibi) artık Webpack önişlemci yapılandırması yok ve işe yaradı! Kendi Webpack önişlemci yapılandırmanızı yönetmemenin ve aşağıda gösterildiği gibi dosyalarımız üzerinde daha iyi TypeScript kapsamına sahip olmanın ne kadar temiz ve güzel olmasından memnunuz.

TypeScript desteğini kapsayarak, daha iyi nasıl yazılacağı hakkında daha fazla bilgi edinmek için Cypress ekibinin örnek gerçek dünya uygulamasına, selvi-gerçek dünya-uygulama deposuna baktık. Dosyaları güncellerken daha iyi zincirleme için cy.task(“pluginName”, { … }) ve Cypress.env(“someEnvVar”) işlev çağrılarının nasıl yazılacağını ve intellisense desteği yazılacağını keşfettik. Ayrıca beraberindeki TypeScript belgelerini de inceledik. Bu bize cy.login() özel komutumuz gibi şeyleri nasıl yazacağımızı ve bir tsconfig.json yapılandırma dosyasını nasıl kuracağımızı öğretti. Örnek uygulamada ayrıca başvuruda bulunmanız için bir tsconfig.json vardır ve bu, tercihlerinize göre özelleştirmeniz için size harika bir temel TypeScript yapılandırması sağlayabilir. En son Cypress sürümleriyle güncel kalmanızı, resmi Cypress kaynaklarına dalmanızı ve tür tanımlama dosyalarınızı denemenizi öneririz.

Özel Komutları Yazma

API aracılığıyla oturum açmayı işlemek için cy.login() gibi bazı genel özel komutlar oluşturduk, böylece tüm özellik dosyalarımızda yeniden kullanılabilir. Burada, kullanıcı kimlik bilgileri verilen ve bir kimlik doğrulama belirteci döndüren kendi oturum açma özel komutunuzu nasıl yazabileceğinize dair bir örnek verilmiştir.

Ortam Değişkenlerini Yazma

Geliştirme ve evreleme gibi birden çok test ortamıyla uğraşmak için, şu anda hangi ortama karşı test ettiğimizi tutmak için "testEnv" gibi ortam değişkenlerini yapılandırmanın avantajını kullandık, örneğin evreleme gibi, "apiHost" arka uç API ana bilgisayarını tutmak için ve diğer değişkenler. Bu gibi ortam değişkeni değerlerini kullanmaya dayanan işlevleri ve diğer nesneleri daha iyi yazmak için Cypress.env() çağrılarınızı yazabilirsiniz.

Eklentileri Yazma

API çağrılarından gelen şeyleri işlemek, hizmetler için yoklama yapmak ve test e-posta gelen kutularında eşleşen e-postaları kontrol etmek için birçok cy.task() eklenti işlevi oluşturduk. Önceden, cy.task().then((data) => {}) gibi bu işlev çağrılarından herhangi birini zincirlerken, zincirlenen veri konusu, TypeScript dosyalarımız için pek iyi olmayan any veya unknown olarak yazılırdı. Cypress örneklerinde, eklenti adına ve işlev çağrılarında iletilen argümanlara göre eklentilerin nasıl daha iyi yazılacağını keşfettik. Bu, TypeScript dosyalarımızın zincirleme veri türünün ne olacağını algılamasına izin verdi.

Karşılaştığımız ince bir sorun, eklenti adının ve argümanlarının tam olarak onu nasıl yazdığınızla eşleşmesi gerektiğiydi. Editörünüzdeki zincirleme .then( .then() türünün ve cy.task() argüman nesnesinin iki katına çıkarılmasının önemli olduğunu gördük. tiplerin doğru şekilde eşleştiğini kontrol edin. Bazen, cy.getCookie(“auth_token”).its(“value”).then((token) => { }) veya cy.wrap(data).then((data) => {}) , bu zincirlenmiş veri argümanlarını bir cy.task(..., { token, data }) fonksiyon argümanı olarak iletmeden önce de yazmanız gerekir, yoksa yine de cy.task(...).then((data) => { }) göreceksiniz cy.task(...).then((data) => { }) any veya unknown olarak yazılan veri bölümü. .its(“value”).then((token: string) => {}) veya cy.wrap(data).then((data: DataType) => {}) ( gibi zincirleme Cypress fonksiyon türlerinin çoğunda daha açık olmanız sizin için daha iyi olur. cy.wrap(data).then((data: DataType) => {}) türlerin tekrar çalıştığından emin olmak için bunları cy.task() argümanlar nesnesinin bir parçası olarak iletmeden önce.

plugins/index.ts kullanılmak üzere işlevleri dışa aktaracak ayrı eklenti TypeScript dosyaları oluşturduk. Eklentilerin sayısı arttıkça, plugins/index.ts dosyanızı küçük tutmak için bu eklenti işlevi uygulamalarını sayfaya veya özelliğe göre düzenlemenizi öneririz. plugins/index.ts dosyanızda tüm cy.task(...) işlevlerinizi tanımladığınız yerde bir bakışta okumayı kolaylaştırmalısınız. Sonunda bu görev fonksiyonlarını index.d.ts aşağıdaki şekilde yazabilirsiniz:

Hepsini bir tür bildirim dosyasında bir araya getirmek

Özel komutlarımız, ortam değişkenlerimiz ve eklentilerimiz için tüm türlerimizi support klasöründeki bir index.d.ts dosyasına yerleştirdik. İşleri düzenli tutmak için tüm Cypress türlerinizi de ana TypeScript tanım dosyasına yerleştirmenizi öneririz. Cypress test kodunuzda kullanılan harici bağımlılıklardaki eksik türleri atlamak için, kitaplığın TypeScript uyarılarına geçici bir çözüm bulmak için declare module 'some-lib' içeren “some-lib.d.ts” gibi modül dosyaları da tanımlayabilirsiniz. Tip tanımlarınızı birden çok dosyada tekrarlamaktan kaçınmak için diğer eklentiler/utils dosyalarınızda tanımlanan türleri/arayüzleri getirmek için TypeScript'in içe aktarma türleri özelliğini bile kullanabilirsiniz. Bu türleri bir Cypress ad alanına ekleyebilir ve bunları aşağıdaki şekilde düzenleyebilirsiniz:

Test fikstürü nesnelerinin, sayfa nesnelerinin ve özellik dosyalarının yazılması

Bir test ortamı için farklı kullanıcıları ve meta verileri yüklemek istediğimizde, "test" veya "evreleme" değerlerini çıkarmak için "testEnv" gibi ortam değişkenlerini "test" veya "hazırlama" değerleriyle nasıl birleştirebileceğimizi daha önce göstermiştik. genel test fikstürleri nesnesinden "evreleme" nesneleri. Tüm özelliklerinizin paylaşabileceği tutarlı bir yapı için bu test fikstürü ortamı nesnelerini jeneriklerle yazabilirsiniz. Her test ortamı için, ihtiyaç duyduğu kadar çok özellik eklemek için bir test için genel bir tür kullanarak aynı kullanıcı kimlik bilgilerine ve meta alanlara sahip olabilirsiniz. Aşağıdaki örneğe bakın.

Sayfa nesnelerinin yazılması ve ilgili özellik dosyalarının yazılması, Cypress komutlarına, eklentilere ve kullandığınız diğer araçlara bağlıdır. Çoğunlukla, sayfa nesnelerini veya spesifikasyon dosyalarını yazmak, JavaScript karşılıklarından çok fazla değişiklik gerektirmez (eklentileri ve ortam değişkeni çağrılarını zaten yazdığınızı varsayarsak). Bazen, tanımladığınız bir sayfa nesnesi yardımcı işlevinin yazılması için bazı bağımsız değişkenlerin yazılması gerekebilir veya bir cy.request() çağrısından gelen response.body as SomeType as gerekebilir. Genel olarak, VSCode gibi düzenleyiciniz cy.task() veya cy.customCommand() çağrılarınızın zincirleme türlerini, TypeScript uyarılarını telafi etmek için spec dosyalarınıza daha fazla tür eklemenize gerek kalmadan otomatik olarak algılayabilir.

Burada, bazı yardımcı işlevlere sahip bir sayfa nesnesinin bölümlerine ve sayfa nesnesini, oturum açma özel komutunu ve eklenti görevlerini kullanan bir belirtim dosyasına bir örnek verilmiştir.

Çözüm

Cypress testlerimize TypeScript eklemek, hataları önlememize yardımcı oldu ve Cypress testleri yazarken geliştirici deneyimimizi geliştirdi. cy.task() , Cypress.env() ve cy.customCommand() fonksiyon çağrılarını kullanırken, fonksiyon argümanları ve çıktıları üzerinde daha iyi tip kontrolü elde edebilir ve ayrıca VSCode gibi IDE'mizde kod tamamlamadan faydalanabiliriz.

Anahtar, kullandığınız özel komutlara, ortam değişkenlerine ve görev eklentisi işlevlerine dayalı olarak "Cypress" ve "Chainable" arabirimlerini geçersiz kılabileceğiniz veya genişletebileceğiniz bir index.d.ts dosyası gibi kendi tür bildirim dosyanızı oluşturmaktır. kullanarak. Sayfa nesnenizde ve spesifik TypeScript dosyalarınızda, bu Cypress işlevlerini kullanabilir ve beklenen girdi ve çıktı türlerinin tanımının üzerine gelebilir veya bunları takip edebilirsiniz.

Ayrıca, daha yeni sürümlerinde TypeScript için kullanıma hazır desteğe sahip olduğundan, TypeScript'i Cypress ile kullanmayı deneyin. İşlevleri daha net bir şekilde belgelemenize ve hatalı API kullanımını önlemenize yardımcı olup olmadığını test edin. TypeScript testleriniz muhtemelen JavaScript Cypress testlerinize benzer görünecek, bu nedenle yaklaşımları karşılaştırmak ve karşılaştırmak için bazı testleri bir seferde istikrarlı bir şekilde dönüştürebilirsiniz.

Cypress testlerimizden öğrendiklerimizle ilgili daha fazla gönderiyle ilgileniyorsanız, göz atmanız gereken bazı makaleler şunlardır:

  • E2E Testleri Yazarken Nelere Dikkat Edilmelidir?
  • Selvi Testleri Yazmaya 1.000 Ayak Genel Bakış
  • Cypress Testlerinde E-posta Akışlarıyla Başa Çıkmak
  • Cypress Testlerinizi Yapılandırma, Düzenleme ve Birleştirme Fikirleri
  • Docker, Buildkite ve CICD ile Cypress Testlerini Entegre Etme