7-bo‘lim

Testlarni avtomatlashtirish

CI qanday qilib yashil yoki qizil qaror qabul qiladi, chiqish kodi, testlarni bosqichlarga ajratish va beqaror testlar.

🕑 11 daqiqa o‘qish 📄 721 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Sinov uchun kichik loyiha
  2. Chiqish kodi - CI ning yagona mezoni
  3. Testlarni quvurga ulash
  4. Testlarni bosqichlarga ajratish
  5. Baza kerak bo'lgan testlar
  6. Beqaror testlar
  7. Qamrov (coverage)
  8. Natijani ko'rinadigan qilish
  9. Xulosa

CI ning butun mantiqi bitta raqamga tayanadi: buyruqning chiqish kodiga. Nol - hammasi joyida, boshqa har qanday son - xato. Testlar shu qoida ustiga quriladi.

Sinov uchun kichik loyiha #

Ikki funksiyadan iborat modul:

JavaScript
export function qosh(a, b) {
    return a + b;
}

export function bol(a, b) {
    if (b === 0) {
        throw new Error("nolga bo'lish mumkin emas");
    }
    return a / b;
}

Va uning testlari (Node ning o'z sinov vositasi, qo'shimcha paket kerak emas):

JavaScript
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { qosh, bol } from './hisob.js';

test('qosh ikkita sonni qo\'shadi', () => {
    assert.equal(qosh(2, 3), 5);
});

test('bol bo\'linmani qaytaradi', () => {
    assert.equal(bol(10, 2), 5);
});

test('nolga bo\'lishda xato tashlaydi', () => {
    assert.throws(() => bol(1, 0), /nolga/);
});

Mahalliy ishga tushirish:

Terminal
node --test
Natija
# Subtest: qosh ikkita sonni qo'shadi
ok 1 - qosh ikkita sonni qo'shadi
# Subtest: bol bo'linmani qaytaradi
ok 2 - bol bo'linmani qaytaradi
# Subtest: nolga bo'lishda xato tashlaydi
ok 3 - nolga bo'lishda xato tashlaydi
1..3
# tests 3
# pass 3
# fail 0

Chiqish kodi - CI ning yagona mezoni #

CI jurnaldagi matnni o'qimaydi. U faqat buyruq qanday tugaganiga qaraydi:

Terminal
node --test
echo $?
Natija
0

Endi qosh funksiyasida ataylab xato qilamiz (a + b + 1):

Natija
not ok 1 - qosh ikkita sonni qo'shadi
  ---
  error: |-
    Expected values to be strictly equal:

    6 !== 5

  code: 'ERR_ASSERTION'
  expected: 5
  actual: 6
  operator: 'strictEqual'
Terminal
echo $?
Natija
1
CI qanday qaror qabul qiladi npm test buyruq bajariladi exit code 0 yoki boshqa son 0 - qadam yashil keyingi qadam boshlanadi 0 emas - qadam qizil job to'xtaydi, keyingilari ishlamaydi Shuning uchun test vositasi xato bo'lganda 0 dan boshqa kod qaytarishi shart Jurnalda «FAILED» deb yozilsa-yu, kod 0 bo'lsa - CI buni muvaffaqiyat deb biladi
Yashil va qizil - jurnaldagi matndan emas, chiqish kodidan kelib chiqadi

Testlarni quvurga ulash #

YAML
name: Testlar

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Bog'liqliklarni o'rnatish
        run: npm ci

      - name: Testlar
        run: npm test

Shu paytdan boshlab har bir kommit va har bir PR avtomatik tekshiriladi.

Testlarni bosqichlarga ajratish #

Hamma testni bitta qadamda ishlatish shart emas. Ularni tezligi bo'yicha ajratish quvurni sezilarli tezlashtiradi:

BosqichNimani tekshiradiTezligiQachon ishlaydi
Birlik (unit)Bitta funksiya, tashqi bog'liqliksizSoniyalarHar kommitda
IntegratsiyaBaza, fayl tizimi, ichki xizmatlarBir necha daqiqaHar kommitda yoki PR da
Uchdan-uchga (e2e)Butun tizim brauzer orqaliO'n daqiqalarPR da yoki kechasi
YAML
jobs:
  birlik:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test:unit

  integratsiya:
    needs: birlik
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test:integration

Tez testlar avval ishlaydi: xato bo'lsa, sekin testlarni kutish shart emas.

Baza kerak bo'lgan testlar #

Integratsiya testlari uchun runner yonida baza ishga tushiriladi:

YAML
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      baza:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: sinov
          MYSQL_DATABASE: sinov_bazasi
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5
    steps:
      - uses: actions/checkout@v4
      - name: Testlar
        env:
          DB_HOST: 127.0.0.1
          DB_USER: root
          DB_PASSWORD: sinov
        run: npm run test:integration
services - bu kichik Docker konteyner

GitHub konteynerni job boshlanishidan oldin ko'taradi va oxirida o'chiradi. options dagi salomatlik tekshiruvi muhim: usiz testlar baza hali tayyor bo'lmaganda boshlanib, tushunarsiz xato beradi.

Parol bu yerda ochiq yozilgani xavfsiz - bu vaqtinchalik konteyner faqat shu job davomida yashaydi va tashqaridan ko'rinmaydi.

Beqaror testlar #

Goh o'tadigan, goh yiqiladigan testlar quvurning eng katta dushmani. Sabablari odatda uchta:

SababBelgisiYechim
Vaqtga bog'liqlikSekin mashinada yiqiladiKutishni aniq shartga bog'lang
Tartibga bog'liqlikYolg'iz o'tadi, birga yiqiladiHar test o'z ma'lumotini yaratsin
Tashqi xizmatInternet sekin bo'lsa yiqiladiTashqi chaqiruvni almashtiring (mock)
Beqaror testni qayta ishga tushirish bilan "tuzatmang"

Eng keng tarqalgan yomon odat - qizil quvurni ko'rib, Re-run jobs tugmasini bosish. Test ikkinchi marta o'tadi va hamma unutadi.

Oqibati og'ir: jamoa qizil rangga ishonmay qo'yadi. Haqiqiy xato chiqqanda ham "yana o'sha beqaror test" deb o'ylab, qayta ishga tushiriladi.

Beqaror test topilsa - yo darhol tuzating, yo vaqtincha o'chirib, uni tuzatish uchun vazifa qo'ying. O'rtasi yo'q.

Qamrov (coverage) #

YAML
      - name: Qamrov bilan testlar
        run: npm test -- --experimental-test-coverage

Qamrov - foydali ko'rsatkich, lekin maqsad emas:

To'g'ri munosabatNoto'g'ri munosabat
Qamrov pasayganini sezish100% ga intilish
Umuman testlanmagan modulni topishKo'rsatkich uchun ma'nosiz test yozish
Yangi kod testlanganini talab qilishEski kodni bir kechada qoplashga urinish

Sakson foiz qamrovli, ammo muhim yo'llarni tekshiradigan to'plam - to'qson foizli, lekin faqat getter'larni sinaydiganidan yaxshiroq.

Natijani ko'rinadigan qilish #

Test natijasini ishga tushirish sahifasiga chiqarish mumkin:

YAML
      - name: Testlar
        run: npm test | tee natija.txt

      - name: Hisobot
        if: always()
        run: |
          echo "## Test natijalari" >> "$GITHUB_STEP_SUMMARY"
          echo '```' >> "$GITHUB_STEP_SUMMARY"
          tail -12 natija.txt >> "$GITHUB_STEP_SUMMARY"
          echo '```' >> "$GITHUB_STEP_SUMMARY"

if: always() bu yerda muhim: testlar yiqilganda ham hisobot yozilishi kerak - aks holda eng kerakli paytda hisobot bo'lmaydi.

Amaliy topshiriq
  1. hisob.js va uning testlarini yaratib, mahalliy node --test bilan ishga tushiring.
  2. echo $? bilan chiqish kodini tekshiring.
  3. Funksiyada ataylab xato qilib, kod 1 ga o'zganini ko'ring.
  4. Testlarni quvurga ulab, PR ochganingizda ishlashini kuzating.
  5. PR ichida testni yiqitib, GitHub PR sahifasida qizil belgi paydo bo'lishini ko'ring.
  6. Testlarni ikkita jobga ajrating: tez va sekin.
  7. needs bilan sekin testlarni tezlaridan keyin ishlashga majburlang.
  8. services orqali MySQL ko'tarib, unga ulanadigan test yozing.
  9. Qamrov hisobotini yoqing va eng kam qamrovli modulni toping.
  10. $GITHUB_STEP_SUMMARY ga test natijasini chiqaring va if: always() ta'sirini tekshiring.

Xulosa #

  • CI jurnalni o'qimaydi - u faqat buyruqning chiqish kodiga qaraydi.
  • 0 - muvaffaqiyat, boshqa har qanday son - xato va job to'xtaydi.
  • Test vositasi xato bo'lganda 0 dan boshqa kod qaytarishi shart.
  • Odatiy quvur: checkout -> setup-node -> npm ci -> npm test.
  • Testlarni tezligi bo'yicha ajrating: tez testlar avval, sekinlari keyin.
  • Baza kerak bo'lsa, services bilan vaqtinchalik konteyner ko'tariladi.
  • services da salomatlik tekshiruvi bo'lmasa, testlar baza tayyor bo'lmasdan boshlanadi.
  • Beqaror testlar eng katta zarar keltiradi: jamoa qizil rangga ishonmay qo'yadi.
  • Beqaror testni qayta ishga tushirish bilan yashirmang - tuzating yoki o'chiring.
  • Qamrov - kuzatish uchun ko'rsatkich, maqsad emas.

Keyingi bo'limda kod uslubini tekshiradigan linter va formatlovchini quvurga qo'shamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.