React Testing Library

React Testing Library Entegrasyon ve Birim testlerini kolayca hazırlayabileceğiniz bir test aracı. @testing-library altında yer alıyor. Bu paket herhangi bir framework’e bağlı değil. Bu paketin bir çok kütüphane için (React, Vue, Angular vb.) wrapper’ları bulunuyor. React Testing Library ile kullanıcı merkezli UI testleri oluşturabiliriz.

@testing-library’in birçok kütüphane için (React, Vue, Angular vb.) wrapper’ları bulunuyor.

“Testleriniz yazılımınızın kullanış şekline ne kadar benzerse size o kadar güven verir.”

@testing-library’i test dosyalarını bir kullanıcı gözüyle hazırlamanızı bekliyor. Ekranda görünen ifadeleri selector’ler yardımla seçin ve kullanıcıdan beklediğiniz eylemleri bu araç ile otomatize edin.

Kısa bir not: React Testing Library “test-runner” olarak Jest’i kullanıyor. React Testing Libray’nin alternatifi Ezynm adlı araç, Jest değil. (Diğer test araçlarını yakından tanımak için bu yazıya göz atabilirsiniz.)

Sorgu Yöntemleri

  • getByLabelText: <label for="search" />
  • getByPlaceholderText: <input placeholder="Search" />
  • getByAltText: <img alt="profile" />
  • getByDisplayValue: <input value="JavaScript" />

Üç ana sorgu tipi var bunlar getBy/getAllBy*, queryBy/queryAllBy* ve findBy/findAllBy*
get ile başlayan sorgularda sonuç ilk node’u döner eğer sorgu bir eleman bulamazsa hata fırlatır.
query ile başlayan sorgularda sonuç ilk node’u döner eğer sorgu bir eleman bulamazsa null döner.
find ile başlayan sorgularda sonuç bulunduğunda sonuçlanan(resolve) bir Promise döner.
getAll, queryAll ve findAll ilk node yerine node dizisi döner.

Birden fazla sorgu tek bir elemanı seçmek için çoğu durumda kullanılabilir. Testlerinizde tutarlılık sağlamak için önerilen şu sıralamayı önceliklendirin. Sırayla ByLabelText, ByPlaceholderText, ByText, ByAltText, ByTitle, ByDisplayValue, ByRole ve son olarak ByTestId kullanabilirsiniz.

Nasıl Kullanılır

Bir arama motoru için SearchBox adlı bir component’imizin olduğunu düşünelim. Bu component şu özelliklere sahip olsun:
1. “X” ikonuna tıklandığında sorgu silinsin.
2. Sorgu alanına tıklandığında bulunan sonuçların listelendiği alan görünmeli.
3. Kullanıcı bir ifade sorguladığında ekranda X ikonu belirsin. (Sorgu alanı boşken “X” ikonu olmasın)

Örnek bir SearchBox component’i

1 - “X” ikonuna tıklandığında sorgu silinsin.

İlk işlemin senaryosunu şu şekilde düşünelim. Kullanıcı arama motoruna “test” yazıyor ve daha sonra sorguyu temizlemek için “X” ikonuna tıklıyor. Kullanıcın beklediği sonuç “X” ikonuna tıklandığında sorgunun temizlenmesi.

“test” içerisine otomatize edeceğimiz işlemi tanımlıyoruz.

import React from 'react'
import { SearchBox } from './SearchBox'
import { render, screen, fireEvent} from '@testing-library/react'
describe('SearchBox', () => {
test('when clear button clicked the query should be empty', async () => {
render(<SearchBox />)
const clearButton = screen.getByLabelText('clear-input')
const searchBox = screen.getByPlaceholderText('Search...') as HTMLInputElement
fireEvent.change(searchBox, { target: { value: 'test' } })
fireEvent.click(clearButton)
expect(searchBox.value).toBe('')
})
...
})
  • screen.getByLabelText ile ekranda yer alan elemanı seçiyoruz. “X” ikonun “clear-input” adında label text’i bulunuyor.
  • screen.getByPlaceHolderText ile ekranda bulunan input alanını seçiyoruz. (Input alanımız placeholder yazısı olarak ‘Search…’ ifadesini kullanıyor)
  • fireEvent ile input, select, checkbox gibi component’lerin eylemlerini tetikleyebiliriz. fireEvent.change ile kullanıcın input alanına ‘test’ yazmasını simüle ediyoruz. fireEvent.click(clearButton) ile kullanıcının “X” ikonuna tıklamasını simüle ediyoruz.
  • Son olarak “expect” ile belirtiğimiz koşulunun sağlanıp sağlanmadığını kontrol ediyoruz. Burada
expect(searchBox.value).toBe(‘’)

ifadesi Input alanını boş beklediğimizi ifade ediyor. Bu koşul sağlanırsa testimiz başarıyla geçecek aksi takdirde hata verecek.

2 - Sorgu alanına tıklandığında bulunan sonuçların listelendiği alan görünmeli.

...
test('it should show suggestion box when user focus searchbox', () => {
render(<SearchBox />)
const searchBox = screen.getByPlaceholderText('Search...') as HTMLInputElement
searchBox.focus()
const suggestionBox = screen.getByLabelText('suggestion-box') as HTMLUListElement
expect(suggestionBox).toBeVisible()
})

Bu işlemlerin sonunda input alanındaki değerin boş olmasını bekliyoruz. Benzer şekilde ekrandan elemanları seçtik.

  • searchBox.focus ifadesi ile kullanıcının sorgu alanına focus olmasını simüle ettik. (Sadece tıklayarak değil klavyeyi kullanarak da bu alana focus olabilir.)
  • expect(suggestionBox).toBeVisible() ifadesi ile öneri alanının ekranda gözükmesi gerektiğini testimize söylüyoruz.

3 - Kullanıcı bir ifade sorguladığında ekranda X ikonu belirsin.

...
test('when user type clear button should be visible', () => {
render(<SearchBox />)
const searchBox = screen.getByPlaceholderText('Search...') as HTMLInputElement
fireEvent.change(searchBox, { target: { value: 'asd' } })
expect(screen.queryByLabelText('clear-input')).toBeInTheDocument()
fireEvent.change(searchBox, { target: { value: '' } })
expect(screen.queryByLabelText('clear-input')).toBeNull()
})

queryBy* selector’leri bir ifadeyi bulamadığı zaman null döner.
Benzer şekilde input alanını seçtik ve kullanıcın arama motoruna “asd” yazmasını simüle ettik. Bu durumda ekran “X” ikonun belirmesini beklediğimizden

expect(screen.queryByLabelText(‘clear-input’)).toBeInTheDocument()
  • ifadesi ile ikonun ekranda var olup olmadığını test ettik.
    Kullanıcın ekrandaki yazıyı sildiğinde, “X” ikonun kaybolmasını beklediğimizden
expect(screen.queryByLabelText(‘clear-input’)).toBeNull()
  • ile ekranda böyle bir ikonun olmaması gerektiğini ifade ettik.

Yazıyı kısaltmak adına asenkron ifadelerin ve Mock Service Worker ile API çağrımlarının kullanımı bir başka yazıya bırakıyorum. :)

Kaynaklar:
1- https://testing-library.com/docs/intro
2- https://medium.com/@oguzkilic/react-componentlar%C4%B1-i%C3%A7in-nas%C4%B1l-test-yaz%C4%B1l%C4%B1r-8da7ffc5d1d5
3- https://www.robinwieruch.de/react-testing-library

--

--

--

Frontend developer and designer, science fiction enthusiast, practicing minimalism, and stoic in search of flow. Writing about design and code.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
A. Kürşat Uzun

A. Kürşat Uzun

Frontend developer and designer, science fiction enthusiast, practicing minimalism, and stoic in search of flow. Writing about design and code.

More from Medium

basic but we can still be cool.

Weekly Response 11 — Living Art

Hermitian Matrix