Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Основы тестирования

Тест — это код, который проверяет другой код: создаёт сервис или компонент, выполняет действие и сравнивает результат с ожидаемым. Тесты запускаются за секунды и сразу показывают, если изменение что-то сломало. Для каждого файла, созданного ng generate, CLI уже сделал заготовку теста с окончанием .spec.ts.

Запуск

ng test

Команда собирает тесты и запускает их, а после каждого сохранения — заново. В Angular 20 по умолчанию используются Karma и Jasmine, тесты выполняются в браузере. В Angular 21 и новее новые проекты используют Vitest. Функции describe, it, expect в простых тестах выглядят одинаково.

Тест сервиса

Откройте src/app/todo-store.spec.ts и опишите поведение хранилища задач:

// src/app/todo-store.spec.ts
import { TestBed } from '@angular/core/testing';
import { TodoStore } from './todo-store';
 
describe('TodoStore', () => {
  let store: TodoStore;
 
  beforeEach(() => {
    store = TestBed.inject(TodoStore);
  });
 
  it('добавляет задачу', () => {
    store.add('Купить хлеб');
    expect(store.todos().length).toBe(1);
    expect(store.todos()[0].title).toBe('Купить хлеб');
  });
 
  it('считает невыполненные задачи', () => {
    store.add('Первая');
    store.add('Вторая');
    store.toggle(store.todos()[0].id);
    expect(store.left()).toBe(1);
  });
});

describe объединяет тесты, it — один тест, expect(...).toBe(...) — проверка. TestBed — тестовое окружение Angular, его метод inject() выдаёт сервис так же, как inject() в компоненте. Для каждого теста создаётся новое окружение, поэтому задачи из первого теста не попадают во второй.

В терминале появится отчёт: зелёным отмечаются пройденные тесты, красным — упавшие, с ожидаемым и полученным значением.

Тест компонента

Компонент создают методом TestBed.createComponent() и проверяют получившийся HTML:

// src/app/todo-item/todo-item.spec.ts
import { TestBed } from '@angular/core/testing';
import { TodoItem } from './todo-item';
 
describe('TodoItem', () => {
  it('выводит название задачи', () => {
    TestBed.configureTestingModule({ imports: [TodoItem] });
    const fixture = TestBed.createComponent(TodoItem);
 
    fixture.componentRef.setInput('todo', { id: 1, title: 'Позвонить Олегу', done: false });
    fixture.detectChanges();
 
    const el: HTMLElement = fixture.nativeElement;
    expect(el.textContent).toContain('Позвонить Олегу');
  });
});

setInput() задаёт входное свойство, как это сделал бы родитель. detectChanges() просит Angular обновить шаблон, а nativeElement — корневой элемент компонента, в котором можно искать текст и теги.

Что проверять

ЧтоПример проверки
Логика сервисаПосле add() в списке на одну задачу больше
Вычисленияleft() считает только невыполненные
Вывод компонентаНазвание задачи есть в HTML
СобытияПосле щелчка по флажку сработал выход toggle

Начните с сервисов: в них больше всего логики, а тестировать их проще всего.

Частая ошибка

Забыть fixture.detectChanges() после setInput() или изменения данных. Шаблон останется в прежнем состоянии, и проверка текста упадёт, хотя компонент работает правильно. После каждого изменения данных в тесте компонента вызывайте detectChanges().

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.