Bileşenimiz sonunda neye benzeyebileceğini görelim. Uygulamamızın https://reactjs.org/ adresine ve /heroes yoluna iki bağlantıya ihtiyacımız var. React simgesinin görüntülenmesi ve metin için biraz css'e ihtiyacımız var.
feat/headerBarBrand adında bir dal oluşturun. src/components/ klasörü altında 2 dosya oluşturun; HeaderBarBrand.cy.tsx, HeaderBarBrand.tsx. Her zamanki gibi, bileşen işlemesiyle minimal başlangıç yapın; aşağıdakileri dosyalara kopyalayın ve yarn cy:open-ct ile çalıştırıcıyı açtıktan sonra testi çalıştırın.
Bağlantıya tıklayalım ve herhangi bir yönlendirme olup olmadığını görelim. Cypress çalıştırıcısı, öğenin görünür olmadığından şikayet edecek (Kırmızı 2).
Tıklama işlemine bir güç ekleyebiliriz .click({force: true}), ama daha iyisini yapalım. İlk bölümde react-icons'u yükledik, bu nedenle FaReact'i içe aktarabiliriz (Yeşil 2).
Şimdilik testten .click()'i çıkarın ve sadece görünürlük için kontrol edin.
Linkin https://reactjs.org adresinde yeni bir sekmede açılmasını istiyoruz. Bunun için link'e target='_blank' ve rel="noopener noreferrer"> özelliklerini ekleyebiliriz. Yeni işlevsellik için hatalı bir test yazalım (Kırmızı 3).
Şimdilik yalnızca bağlantıyı kontrol ediyoruz. Bileşenin içinde bir svg olup olmadığını da doğrulayabiliriz. Bir css seçicisiyle değil bileşen için bir data-cy özelliği olmasını istiyoruz. Bu için başarısız bir test yazalım (Kırmızı 4).
Uygulamamızda yönlendirme çözümü olarak react-router kullanacağız. React Router'ın Link bileşeni, uygulamadaki farklı rotalara geçmek için kullanılır ve NavLink, kullanıcının hangi rotada olduğuna dair görsel bir işaret eklemek için kullanılır. Biz NavLinki tercih edeceğiz. İşte NavLinknin bağlantı vurgu özelliğini gösteren bir örnek görüntü:
React-router'ı yarn add react-router-dom ile uygulamamıza ekleyin. divin altına NavLink ekleyin ve nasıl göründüklerine bakalım.
İki hata alıyoruz. Biri eksik bir özniteliğe dair bir derleyici uyarısı, diğeri react-routerın bileşeni Router bileşeni içinde sarmalanmadan kullanılmasıdır (Red 5). Bu da başka bir bileşen testi hatasıdır ve bu hata ile de tanışmak istiyoruz.
NavLink'e data-cy özniteliğini ekleyerek, bileşenin bağlantı kısmıyla ilgili işlemi tamamlamış oluruz.
Bileşen testindeki hata mesajını ise, bileşeni BrowserRouter içinde sarmalayarak giderebiliriz. Bu, gelecekteki yönlendirmeyle ilgili bileşen testlerinde sık sık göreceğimiz bir durumdur.
Testimiz tekrar başarılı oldu, ancak görsel olarak herhangi bir fark yok. Gereksinimler özelliklerini belirlemek için Angular sürümünü kullandık. Orada metnin üç farklı stildeki span ile gösterildiğini görebiliyoruz. NavLink'e css sınıflarını da ekleyebiliriz.
Bu içeriği kontrol eden yeni bir hatalı test yazabiliriz. NavLink'in oluşturulup oluşturulmadığını kontrol etmek istiyoruz ve span altındaki dizeleri doğrulamak istiyoruz. Bu linke tıklandığında, anasayfada olduğumuzu doğrulayabiliriz (Red 6). Cypress bileşen testinde url kavramı yoktur, ancak bağlantılara tıklama işlemi gerçekten bir url değerini değiştirir, bunu doğrulayabiliriz.
Bu noktada bir test yeniden yapılandırması mümkündür, iki farklı bölüme ayırmamız gerekiyor mu yoksa tek bir it bloğu altında mı olmalıdır?
Bir Cypress bileşen testi, küçük ölçekli bir e2e testidir; bir hatanın yarattığı zararın küçültülmesi için testleri kısa tutmaya gerek yoktur, çünkü çalıştırıcı teşhis etmeyi kolaylaştırır. Bir test perspektifinden önemli olan, testin başlangıç durumudur; bu duruma ulaşmak yaygınsa, genellikle bir test geliştirme fırsatıdır, kısmi test çoğaltması yerine.
Bizim durumumuzda, basit bir bileşen olduğu için, testi uzun tutabilir veya ortak durum için bir before hook kullanabiliriz (bileşenin montajı), böylece 2 ayrı test olur. İşte iki farklı sürüm (Düzenleme 6):
İpucu: Uzun bir testte cy.log(), sınır belirlemede kullanılabilir.
// src/components/HeaderBarBrand.cy.tsx// 2 it blocks with a beforeEach hook for mountimport HeaderBarBrand from"./HeaderBarBrand";import { BrowserRouter } from"react-router-dom";import"../styles.scss";describe("HeaderBarBrand", () => { r;beforeEach(() => {cy.mount( <BrowserRouter> <HeaderBarBrand /> </BrowserRouter> ); });it("should verify external link attributes", () => {cy.get("a").should("have.attr","href","https://reactjs.org/").and("have.attr","target","_blank").and("have.attr","rel","noopener noreferrer");cy.getByCy("header-bar-brand").within(() =>cy.get("svg")); });it("should verify internal link spans and navigation", () => {cy.getByCy("navLink").within(() => ["TOUR","OF","HEROES"].forEach((part:string) =>cy.contains("span", part) ) );cy.getByCy("navLink").click();cy.url().should("contain","/"); });});
Bileşen testinin RTL sürümü
// src/components/HeaderBarBrand.test.tsximport HeaderBarBrand from"./HeaderBarBrand";import { render, screen, within } from"@testing-library/react";import { BrowserRouter } from"react-router-dom";import userEvent from"@testing-library/user-event";import"@testing-library/jest-dom";describe("HeaderBarBrand", () => {beforeEach(() => {render( <BrowserRouter> <HeaderBarBrand /> </BrowserRouter> ); });it("should verify external link attributes",async () => {constlink=awaitscreen.findByTestId("header-bar-brand-link");expect(link).toHaveAttribute("href","https://reactjs.org/");expect(link).toHaveAttribute("target","_blank");expect(link).toHaveAttribute("rel","noopener noreferrer");// not easy to get a tag with RTL, needed to use a test idwithin(awaitscreen.findByTestId("header-bar-brand")).getByTestId("react-icon-svg" ); });it("should verify internal link spans and navigation",async () => {constnavLink=awaitscreen.findByTestId("navLink");constwithinNavLink=within(navLink); ["TOUR","OF","HEROES"].map((part) =>withinNavLink.getByText(part));awaituserEvent.click(navLink);expect(window.location.pathname).toBe("/"); });});
Özet
Bir href'ye giden bir bağlantı için başarısız bir test ekledik (Kırmızı 1).
Bağlantıyı bileşene ekledik (Yeşil 1).
Simgenin / bağlantının görünmediği tespit edildi (Kırmızı 2).
react-icon ekledik ve bağlantının görünürlüğünü doğruladık (Yeşil 2).
Dış bağlantıya tıklandığında yeni bir sekme açmak için yeni bir özellik için başarısız bir test ekledik (Kırmızı 3).
target=_blank ve rel özniteliklerini bileşene ekledik (Yeşil 3).
Bileşenin görünümünü iyileştirmek için CSS ekledik (Düzenleme 3).
Daha kapsamlı bir kontrol yapmak ve data-cy seçicisini kullanmak için testi iyileştirdik (Kırmızı 4).
Ardından bileşeni teste geçmek için iyileştirdik (Yeşil 4).
Dahili bağlantı için react-router ekledik ve yönlendirme için NavLink kullandık. NavLink'in bir to özniteliği olmadığı için iki hata aldık, diğeri de testin Router bileşeni tarafından sarılmamış olmasıydı (Kırmızı 5).
NavLink'e to özniteliğini ekledik ve bileşeni BrowserRouter ile sararak sorunu çözdük (Yeşil 5).
Angular uygulamasının görsel yapısal özelliklerini inceleyerek bileşene yeni testler ekledik (Kırmızı 6).
Bileşeni testi geçmesi için iyileştirdik (Yeşil 6).
Testi yeniden düzenledik (Düzenleme 6).
Çıkarılacak Dersler
Cypress'te ikinci sekme ile ilgili 3 yöntem vardır. Çoğu zaman href özniteliği için kontrol yeterlidir.
React uygulamalarında yönlendirmede react-router de facto bir çözümdür. Navigasyon için NavLink ile bir to özniteliği kullanırız.
react-router ile ilgili bileşen testleri için bileşeni BrowserRouter ile sarmak gerekir.
Cypress bileşen testinde URL kavramı yoktur, ancak bağlantılara tıklamak gerçekten bir URL özniteliğini değiştirir, bunu doğrulayabiliriz.
Bir Cypress bileşen testi küçük ölçekli bir end-to-end testidir. Bir hata durumunda tanı koymayı kolaylaştırmak için testleri kısa tutmak gerekli değildir. Test açısından önemli olan, bir testin başlangıç durumudur; eğer bu duruma ulaşmak yaygınsa, genellikle bir test geliştirme fırsatıdır, kısmi test kopyalaması değil.
Uzun bir testte, delimitasyon için cy.log() kullanılabilir.