Photo by Hans Reniers on Unsplash

SERIES FOR REACT ARCHITECTURE

Platform Components Nasıl Test Yazılır ? (Snapshot ve DOM Testing)

Platform Component iş mantığı içermeyen , styling ve layout için kullandığımız bileşenlerdir. Bu yazıda bu tür bileşenlere nasıl unit test yazabileceğimizi anlatacağım.

Frontend Development With JS
4 min readJul 22, 2023

--

Bundan önceki yazımızda Page ve Platform Component ne olduğundan ve farklarından bahsetmiştim

Sadece props alan, state tutmayan kendisine verilen değerler doğrultusunda belli styling, metin ve davranışlara sahip olan bileşen türlerine platform components diyoruz.

Örnek olması açısından bu 3rd Part kütüphanelerinin üzerinde bir tane Platform Component geliştirip bunun için test yazacağım.

Örneğin tüm uygulama içerisinde Cancel düğmesinin belli bir stil ve davranışta olmasını isteyelim.

import { Button } from "antd";

interface CancelButtonProps {
handlCancel: () => void;
}

export const CancelButton: React.FC<CancelButtonProps> = ({ handlCancel }) => {
return <Button onClick={handlCancel}>Cancel</Button>;
};

Burada göreceğiniz gibi Cancel butonuna bir Style ekleyerek bunu özelleştirebilirim. (Own Styling and Naming)

Bu bileşeni kendi şirketime ait bir isimlendirmenin arkasına koyabilirim (React Bileşen İsimlendirmesinde Tür ve Hiyerarşik Yapıyı Tanımlayabilme)

Şimdi gelelim bu bileşene test yazma işine. Artık CRA giderek yok olmaya terkedildiği için (Create React App Neden Sonlandırıldı) , yeni React proje oluşturma altyapısı olarak Vite ve test altyapısı olarak Vitest kullanıyorum.

Frontend Testing konusunda önceden yazdığım bu blog yazısını okuyabilirsiniz.

Şimdi gelelim test yazma aşamasına ..

Snaphot Testing Nedir ?

Snapshot testi açıklamasını Oğuz Kılıç’ın blog yazısından okuyalım, özet olarak

Biz bugüne kadar UI testlerini yaparken bir çok araç kullandık. Bazen bu component testlerini yazmak proje büyüdükçe sıkıcı olabiliyor. Çünkü yaptığımız temel şeyler beklenilen ve var olan durumlar eşit mi değil mi x class’ı olmalı gibi kontrollerden ibaret. Bunu yapmamızın amacıda UI’ın değişip değişmedini anlamak ve olası hataların önüne geçmek veya data gelmesi zorunlu alanlara gerçekten bir data geliyor mu görmek.

Jest SnapShot testlerinde birebir react component’larınızın ekran görüntüsünü alıyor bir anlamda. Ancak bu görüntü bir jpg, png gibi ekran görüntüsü değil elbette. Component’ı JSON formatına dönüştürüyor. Daha sonra bunu .snap adında dosyalara yazıyor ve dosya adına -test.snap ekliyor. Ardından toMatchSnapshot() ile sizin Component’ınızda yapılan her değişikliği match etmeye çalışıyor. Aradaki diff ile test’i fail ediyor eğer bir fark yoksa testiniz geçiyor. (Oguz Kılıç)

Bunu yapabilmek için react-test-renderer faydalanıyoruz. Snapshot alarak, verdiğimiz mock handleCancel bir kere çağrıldığına bakarak bileşeni test etmeye çalışıyoruz.

import React from "react";
import renderer from "react-test-renderer";
import { CancelButton } from "./CancelButton";
import { vi, describe, test, expect } from "vitest";

vi.mock("antd", () => ({
Button: ({
onClick,
children,
}: {
onClick: () => void;
children: React.ReactNode;
}) => <button onClick={onClick}>{children}</button>,
}));

describe("CancelButton", () => {
test("renders correctly", () => {
const handleCancel = vi.fn();

const tree = renderer
.create(<CancelButton handlCancel={handleCancel} />)
.toJSON();

expect(tree).toMatchSnapshot();
});

test("calls the handleCancel function on button click", () => {
const handleCancel = vi.fn();

const component = renderer.create(
<CancelButton handlCancel={handleCancel} />
);
const button = component.root.findByType("button");

button.props.onClick();

expect(handleCancel).toHaveBeenCalledTimes(1);
});
});

DOM Testing Nedir ?

DOM Testing Mahmut Yıldız’ın blog yazısından okuyalım.

React Testing Library, bir DOM test library’sidir; bu, React komponentlerinin render edilmiş haliyle uğraşmak yerine, doğrudan DOM node üzerinde çalışacak ve kullanıcıların gördüğü gerçek çıktıların nasıl davrandıklarını test etmeye çalışacağı anlamına gelir. (Mahmut Yıldız)

Yani biz JSDOM veya HappyDOM kütüphaneleri üzerinden Testin içeriğini render edilmesini sağlayarak bunun üzerinden React Testing Library yardımı ile kullanıcı aksiyonlarını ve bunun sonuçlarını karşılaştırarak gerçek tarayıcı ortamını testler için simüle etmiş oluruz.

import { render, screen, fireEvent } from "@testing-library/react";

import { CancelButton } from "./CancelButton";
import { vi, describe, test, expect, afterEach } from "vitest";
import { cleanup } from "@testing-library/react";
import matchers from "@testing-library/jest-dom/matchers";

// extends Vitest's expect method with methods from react-testing-library
expect.extend(matchers);

// runs a cleanup after each test case (e.g. clearing jsdom)
afterEach(() => {
cleanup();
});

// Mock the Ant Design Button component

describe("CancelButton", () => {
test("renders correctly", () => {
const handleCancel = vi.fn(); // Create a mock function

render(<CancelButton handlCancel={handleCancel} />);

const cancelButton = screen.getByText("Cancel");
expect(cancelButton).toBeInTheDocument();
});

test("calls the handleCancel function on button click", () => {
const handleCancel = vi.fn(); // Create a mock function

render(<CancelButton handlCancel={handleCancel} />);

const cancelButton = screen.getByText("Cancel");
fireEvent.click(cancelButton); // Simulate button click

expect(handleCancel).toHaveBeenCalledTimes(1); // Check if the handleCancel function was called once
});
});

Yanlız bu aşamda vitest.config.ts içerisine bir takım eklemeler yapmak gerekiyor. (Alias kısmı ve environment HappyDOM tanımlamanız lazım)

import { configDefaults, defineConfig } from "vitest/config";
import path from "path";

export default defineConfig({
test: {
exclude: [...configDefaults.exclude, "packages/template/*"],
environment: "happy-dom",
},
resolve: {
alias: {
...
},
},
});

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke (React Testing) tıklayabilirsiniz.

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke (React Architecture) tıklayabilirsiniz.

--

--