Dasturchining hayotida eng ko'p uchraydigan vaziyatlardan biri shuki, bitta kichik o'zgartirish kiritasiz va kutilmaganda saytning butunlay boshqa qismi ishlamay qoladi. Bunday holatlarning oldini olishning eng ishonchli usuli unit testdir. Unit test — bu kodning eng kichik mantiqiy bo'lagini, odatda alohida funksiya yoki metodni, qolgan tizimdan ajratgan holda avtomatik ravishda tekshiruvchi kichik dasturdir. Siz funksiyaga ma'lum bir kirish qiymatini berasiz va u qanday natija qaytarishi kerakligini oldindan aytib qo'yasiz; agar haqiqiy natija kutilgan natijaga mos kelmasa, test muvaffaqiyatsiz tugaydi va sizni darhol ogohlantiradi.
Nega unit test yozish kerak
Unit testning birinchi va eng muhim foydasi xatoni iloji boricha erta tutib olishdir. Qo'lda sinab ko'rilganda topilmaydigan mantiqiy xatolar avtomatik testlar yordamida kod ishlab chiqarishga chiqishidan ancha oldin aniqlanadi, bu esa muammoni tuzatish narxini bir necha barobar kamaytiradi. Ikkinchidan, testlar kodga ishonch beradi: yuzlab testlar yashil bo'lib turganida, siz tizimning asosiy qismlari ishlayotganiga amin bo'lasiz. Uchinchi va ko'pincha eng qadrli foyda refaktoringdir — kodni qayta tuzish jarayonida testlar himoya to'ri vazifasini bajaradi, chunki agar siz biror narsani buzib qo'ysangiz, ular darhol qizil rangga aylanadi va sizga aniq nima ishlamay qolganini ko'rsatadi.
Asosiy tushunchalar: assert va AAA naqshi
Har qanday unit testning yuragida assertion, ya'ni tasdiqlash yotadi. Assertion — bu "men bu qiymat aynan shunday bo'lishini kutyapman" degan da'vodir; masalan, ikki sonni qo'shuvchi funksiya 2 va 3 ni qabul qilib 5 qaytarishini tasdiqlaysiz. Agar tasdiqlash bajarilmasa, test yiqiladi. Yaxshi tuzilgan testlar odatda AAA naqshiga amal qiladi: Arrange (tayyorlash) bosqichida kerakli ma'lumotlar va obyektlar tayyorlanadi, Act (harakat) bosqichida tekshirilayotgan funksiya chaqiriladi, va Assert (tasdiqlash) bosqichida natija kutilgan qiymat bilan solishtiriladi. Bu uch bosqichni aniq ajratish testni o'qishni va keyinchalik uni tushunishni ancha osonlashtiradi.
PHPUnit bilan PHP kodini tekshirish
PHP olamida eng keng tarqalgan test vositasi PHPUnit hisoblanadi. U Composer orqali o'rnatiladi va testlar odatda alohida tests papkasida saqlanadi. Quyidagi misolda biz oddiy Calculator klassini va uning add metodi uchun testni ko'rib chiqamiz, bunda AAA naqshi aniq ko'rinib turibdi.
<?php
use PHPUnit\Framework\TestCase;
class Calculator {
public function add(int $a, int $b): int {
return $a + $b;
}
}
class CalculatorTest extends TestCase {
public function testAddReturnsSum(): void {
// Arrange
$calc = new Calculator();
// Act
$result = $calc->add(2, 3);
// Assert
$this->assertSame(5, $result);
}
}
Bu testni ishga tushirish uchun terminalda vendor/bin/phpunit tests/ buyrug'ini yozasiz. Agar hamma narsa to'g'ri bo'lsa, PHPUnit yashil natija va o'tgan testlar sonini ko'rsatadi; metodda xato bo'lsa, u qaysi qatorda qaysi qiymat kutilgani va aslida nima qaytganini batafsil ko'rsatadi.
Jest bilan JavaScript funksiyalarini sinash
Frontend va Node.js loyihalarida eng mashhur test vositasi Jest hisoblanadi. U sodda sintaksisi va tezligi bilan ajralib turadi, hech qanday murakkab sozlashni talab qilmaydi. Quyidagi misolda biz JavaScript funksiyasini va uning Jest testini ko'ramiz; bu yerda describe bloki testlarni guruhlaydi, test funksiyasi esa alohida holatni ifodalaydi.
// math.js
function add(a, b) {
return a + b;
}
module.exports = { add };
// math.test.js
const { add } = require('./math');
describe('add funksiyasi', () => {
test('ikki musbat sonni qo\u2018shadi', () => {
// Arrange & Act
const result = add(2, 3);
// Assert
expect(result).toBe(5);
});
});
Testlarni npx jest buyrug'i bilan ishga tushirasiz. Jest barcha .test.js fayllarini avtomatik topadi va ularni bajaradi, natijalarni esa rang bilan ajratib ko'rsatadi. expect va toBe juftligi bu yerda aynan PHPUnit'dagi assertion vazifasini bajaradi.
Mock: tashqi bog'liqliklarni almashtirish
Real loyihalarda funksiyalar ko'pincha ma'lumotlar bazasiga, tashqi API'ga yoki to'lov tizimiga murojaat qiladi. Bunday bog'liqliklarni har bir testda haqiqatdan ishga tushirish sekin va ishonchsiz bo'ladi, shu sababli ularning o'rniga mock, ya'ni soxta nusxa qo'yiladi. Mock — bu haqiqiy obyektga o'xshab ko'rinadigan, lekin oldindan belgilangan natijalarni qaytaradigan nazorat ostidagi obyektdir. Masalan, foydalanuvchini bazadan oluvchi metodni mock qilib, har doim bir xil test foydalanuvchisini qaytarishini ta'minlaysiz; shunda test faqat o'z mantiqini tekshiradi, tashqi tizimning holatiga bog'liq bo'lmaydi. Jest'da bu jest.fn() orqali, PHPUnit'da esa createMock() orqali amalga oshiriladi.
Coverage va TDD haqida qisqacha
Code coverage, ya'ni qamrov, testlaringiz kodning necha foizini bajarib o'tganini ko'rsatuvchi o'lchovdir. PHPUnit --coverage-html bayrog'i bilan, Jest esa --coverage bilan ushbu hisobotni yaratadi va qaysi qatorlar umuman sinalmaganini aniq ko'rsatadi. Shuni ta'kidlash kerakki, yuqori qamrov foizi o'z-o'zidan sifatni kafolatlamaydi, lekin past qamrov aniq xavfli zonalarni ochib beradi. Test-Driven Development (TDD) esa yondashuv bo'lib, unda siz avval testni yozasiz, u tabiiy ravishda yiqiladi, so'ng uni o'tkazadigan minimal kodni yozasiz va keyin kodni tozalaysiz. Bu sikl kodni dastlabdan tekshiriladigan va sodda qilib loyihalashga majbur qiladi.
Qachon va qanday test yozish kerak
Hamma narsani yuz foiz testlash shart emas va ko'pincha foydasizdir. Birinchi navbatda biznes mantiqi murakkab bo'lgan, ko'plab shartlar va hisob-kitoblarni o'z ichiga olgan funksiyalarni testlash kerak, chunki aynan shu yerda xatolar eng ko'p uchraydi. Agar siz biror xatoni topib tuzatgan bo'lsangiz, o'sha xatoni qайтa keltirib chiqaradigan test yozish juda foydali, chunki bu xato kelajakda yana paydo bo'lmasligiga kafolat beradi. Eng muhimi, testlarni odat tusiga aylantirishdir: yangi funksiya yozganingizda u uchun test ham yozsangiz, vaqt o'tishi bilan loyihangizda ishonchli himoya to'ri shakllanadi va har bir o'zgartirish ancha xotirjam amalga oshiriladi.