Урок 15 · Слайд 1
🧪

Зачем нужны тесты?

Чтобы код не ломался при изменениях

Представь: ты добавляешь новую функцию, и вдруг ломается старая. Без тестов ты узнаешь об этом только когда пользователь напишет баг-репорт. С тестами — сразу!

Тесты дают:

  • ✅ Уверенность что код работает правильно
  • 🔄 Безопасный рефакторинг (изменение кода)
  • 📖 Документацию — тест показывает как функция должна работать
  • 🚀 Автоматическую проверку при каждом деплое
📖 Словарик
Тест
Программа, проверяющая правильность работы другой программы.
"Тест проверяет: сумма(2, 3) должна равняться 5"
Регрессия
Когда новый код ломает то, что раньше работало.
"Тесты помогают поймать регрессию быстро"
CI/CD
Автоматическое тестирование и деплой при каждом коммите.
"GitHub Actions запускает тесты автоматически"
Урок 15 · Слайд 2
🔺

Виды тестов: пирамида

Разные тесты для разных задач

🔬
Unit тесты
Тестируют одну функцию. Быстрые, много.
🔗
Integration
Тестируют несколько модулей вместе.
🌐
E2E тесты
Тестируют весь сайт как пользователь.

Правило: чем больше тест охватывает — тем медленнее и дороже он. Большинство тестов должны быть Unit, мало E2E.

📖 Словарик
Unit тест
Тестирует одну функцию или класс изолированно.
"unit тест функции сложить(a, b): ожидаем 5 при (2,3)"
E2E (End-to-End)
Автоматически кликает по сайту, как реальный пользователь.
"E2E: открыть сайт → войти → купить товар → проверить"
Урок 15 · Слайд 3

Unit-тест вручную

Пишем первый тест без библиотек

test.js — самодельный тест
// Функция которую тестируем
function сложить(a, b) { return a + b; }
function делить(a, b) {
  if (b === 0) throw new Error('Нельзя делить на 0!');
  return a / b;
}

// Простая функция проверки
function ожидать(результат, ожидание, имя) {
  if (результат === ожидание) {
    console.log(`✅ PASSED: ${имя}`);
  } else {
    console.log(`❌ FAILED: ${имя}`);
    console.log(` Ожидали: ${ожидание}`);
    console.log(` Получили: ${результат}`);
  }
}

// Запускаем тесты
ожидать(сложить(2, 3), 5, '2+3=5');
ожидать(сложить(0, 0), 0, '0+0=0');
ожидать(делить(10, 2), 5, '10/2=5');
✅ PASSED: 2+3=5
✅ PASSED: 0+0=0
✅ PASSED: 10/2=5
📖 Словарик
Assert (утверждение)
Проверка условия — тест упадёт если условие ложно.
"assert(сложить(2,3) === 5) — проверяем результат"
Edge case
Крайний случай: пустые данные, ноль, очень большие числа.
"Тест деления на 0 — важный edge case"
Урок 15 · Слайд 4
🃏

Jest: профессиональное тестирование

Самый популярный фреймворк для тестов

math.test.js
// Устанавливаем: npm install --save-dev jest
const { сложить, делить } = require('./math');

// describe группирует тесты
describe('Математика', () => {
  test('складывает числа', () => {
    expect(сложить(2, 3)).toBe(5);
    expect(сложить(-1, 1)).toBe(0);
  });

  test('делит числа', () => {
    expect(делить(10, 2)).toBe(5);
  });

  test('бросает ошибку при делении на 0', () => {
    expect(() => делить(5, 0)).toThrow('Нельзя делить на 0!');
  });
});

$ npx jest
✓ складывает числа (3ms)
✓ делит числа
✓ бросает ошибку при делении на 0
Tests: 3 passed ✅
📖 Словарик
Jest
Популярный фреймворк для тестирования JavaScript.
"Jest используют React, Node.js проекты"
expect().toBe()
Проверяет точное равенство значений.
"expect(2+2).toBe(4) — ожидаем что 2+2 равно 4"
describe()
Группирует связанные тесты в блок.
"describe('Математика', ...) — группа тестов для модуля"
Урок 15 · Слайд 5
🤖

Puppeteer: тест в браузере

Робот кликает по странице за тебя

browser.test.js
// npm install puppeteer
const puppeteer = require('puppeteer');

test('Главная страница загружается', async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  
  // Открываем страницу
  await page.goto('http://localhost:3000');
  
  // Проверяем заголовок
  const заголовок = await page.title();
  expect(заголовок).toBe('Мой сайт');
  
  // Кликаем кнопку
  await page.click('#loginBtn');
  
  // Проверяем результат
  const текст = await page.$eval('#result',
    el => el.textContent);
  expect(текст).toContain('Добро пожаловать');
  
  await browser.close();
});
📖 Словарик
Puppeteer
Библиотека для управления браузером Chrome через Node.js.
"Puppeteer открывает сайт и кликает как пользователь"
Headless browser
Браузер без интерфейса — работает в фоне.
"headless: true — Chrome работает без окна"
Урок 15 · Слайд 6
🌲

Cypress: E2E тесты

Красивый инструмент для полного тестирования

cypress/e2e/auth.cy.js
// npm install cypress
// npx cypress open

describe('Авторизация', () => {
  beforeEach(() => {
    cy.visit('http://localhost:3000/login');
  });

  it('успешный вход', () => {
    cy.get('#email').type('user@test.com');
    cy.get('#password').type('secret123');
    cy.get('#loginBtn').click();
    cy.url().should('include', '/dashboard');
  });

  it('ошибка при пустом email', () => {
    cy.get('#loginBtn').click();
    cy.get('.error').should('be.visible');
  });
});
📖 Словарик
Cypress
Инструмент для E2E тестирования с красивым UI.
"Cypress показывает в реальном времени что происходит"
beforeEach()
Выполняется перед каждым тестом в блоке describe.
"beforeEach открывает нужную страницу перед каждым тестом"
Урок 15 · Слайд 7
🔴

TDD: разработка через тесты

Сначала тест — потом код!

🔴
Red
Пишем тест
он падает
🟢
Green
Пишем код
тест проходит
🔵
Refactor
Улучшаем
тест остаётся
TDD пример
// 1. 🔴 Пишем тест (функции ещё нет!)
test('isPrime(7) = true', () => {
  expect(isPrime(7)).toBe(true);
});
// ❌ ReferenceError: isPrime is not defined

// 2. 🟢 Пишем минимальный код
function isPrime(n) {
  for (let i = 2; i < n; i++) {
    if (n % i === 0) return false;
  }
  return n > 1;
}
// ✅ PASSED

// 3. 🔵 Рефакторинг: оптимизируем
// i <= Math.sqrt(n) — быстрее!
📖 Словарик
TDD (Test Driven Development)
Подход: сначала пишем тест, потом код, потом улучшаем.
"TDD: Red → Green → Refactor"
Рефакторинг
Улучшение кода без изменения его поведения.
"Рефакторинг безопасен если есть тесты"
Урок 15 · Слайд 8
🏆

Мини-квест: напиши 3 теста!

Применяй TDD на практике

1
Установи Jest: npm init -y && npm install --save-dev jest
2
Создай math.js с функциями: сложить, вычесть, умножить, делить
3
Создай math.test.js — напиши по 2 теста на каждую функцию (8 тестов)
4
Добавь edge cases: делить на 0, пустые аргументы, отрицательные числа
5
★ Примени TDD: напиши тест для функции isPalindrome до написания функции
6
★★ Настрой Cypress и напиши E2E тест для своего проекта гостевой книги 🏆