1 of 37

2 of 37

Как меня слышно && видно? Вкл запись!!!

Если нет – напишите, если слышите – смайлик в чат.

3

3 of 37

Test quality tools

4 of 37

Какие инструменты помогают писать код

  • Typescript проверяет ваш код на соответствие типов
  • Eslint помогает исправить проблемы в форматировании кода
  • Jest библиотека для тестирования
  • Storybook позволяет развивать библиотеку компонентов
  • Loki или Chromatic для visual тестов
  • Redux-saga-test-plan позволяет писать качественные тесты для redux+saga

5 of 37

Общие рекомендации

  • Придерживайтесь бережливого тестирования
  • Тестовый код отличается от того, что идёт в эксплуатацию. Делайте его максимально простым, коротким, свободным от абстракций, единым, замечательным в работе и бережливым.
  • Другой человек должен посмотреть на тест и сразу понять, что он делает.

6 of 37

Правила написания тестов

  • Что именно тестируется?
  • При каких условиях и сценарии?
  • Какой ожидается результат?

7 of 37

Правила написания тестов

describe("Login Saga", () => {

describe("Login success", () => {

it("checkUserSession with not-empty username success", () => {

8 of 37

Программируйте тесты в декларативном стиле

it("When asking for an admin, ensure only ordered admins in results", () => {

//assuming we've added here two admins "admin1", "admin2" and "user1"

const allAdmins = getUsers({ adminOnly: true });

const admin1Found, adming2Found = false;

allAdmins.forEach((aSingleUser) => {

if (aSingleUser === "user1") {

assert.notEqual(aSingleUser, "user1", "A user was found and not admin");

}

if (aSingleUser === "admin1") {

admin1Found = true;

}

if (aSingleUser === "admin2") {

admin2Found = true;

}

});

if (!admin1Found || !admin2Found) {

throw new Error("Not all admins were returned");

}

});

9 of 37

Программируйте тесты в декларативном стиле

it("When asking for an admin, ensure only ordered admins in results", () => {

//assuming we've added here two admins

const allAdmins = getUsers({ adminOnly: true });

expect(allAdmins)

.to.include.ordered.members(["admin1", "admin2"])

.but.not.include.ordered.members(["user1"]);

});

10 of 37

Не стоит генерировать и поддерживать данные с бека

11 of 37

Генерируйте реалистичные данные

  • https://github.com/faker-js/faker
  • faker.js - generate massive amounts of fake data in the browser and node.js

12 of 37

Не стоит проверять только удобные свойства

13 of 37

Группируйте тесты

14 of 37

Не ловите ошибки, а ожидайте их

it("When no product name, it throws error 400", async () => {

let errorWeExceptFor = null;

try {

const result = await addNewProduct({ name: 'nest' });

}

catch (error) {

expect(error.code).to.equal('InvalidInput');

errorWeExceptFor = error;

}

expect(errorWeExceptFor).not.to.be.null;

//if this assertion fails, the tests results/reports will only show

//that some value is null, there won't be a word about a missing Exception

});

15 of 37

Не ловите ошибки, а ожидайте их

it.only("When no product name, it throws error 400", async () => {

expect(addNewProduct)).to.eventually.throw(AppError).with.property('code', "InvalidInput");

});

16 of 37

Test coverage

17 of 37

Jest

  • Очень простая оценка с помощью флага --coverage

18 of 37

Минимальный порог покрытия

  • Если верить мнению многих авторитетных людей мин порог 80-90 %
  • 10-30 % слишком мало для получения корректности сборки
  • 100 % слишком дорого (долго)

19 of 37

Минимальный порог покрытия

  • https://martinfowler.com/bliki/TestCoverage.html
  • Если верить мнению многих авторитетных людей мин порог 80-90 %

20 of 37

Jest + CI

  • coverageThreshold поможет очень точно настроить минимальные пороги
  • Уверенность и числа идут рука об руку. Если вы не уверены, что протестировали большую часть системы, то у вас останутся опасения

21 of 37

Анализируйте отчеты о покрытии

  • Аналитика отчетов может помочь выявить недосягаемые участки кода
  • Необычное поведение приложения
  • Если вы не знаете, какие части кода остались не протестированными, то вы не знаете, где могут возникнуть проблемы
  • Запустим отчет!

22 of 37

Вопросы?

23 of 37

eslint-plugin-jest

24 of 37

Предотвращение проблем тестирования с помощью тест-линтеров

  • 90-процентное покрытие и все зелёные тесты это хорошо, пока не поймёте, что многие тесты ничего не подтверждают или вообще были пропущены
  • Всегда лучше руководствоваться помощью линтеров

25 of 37

Stryker mutator

26 of 37

Какие недостатки у традиционных метрик?

  • Метрики покрытия не показывают качества написанных тестов
  • Метрика покрытия измеряет количество строк кода, посещённых тестом, но не проверяет, действительно ли они протестированы

27 of 37

Stryker

  • Мутационное тестирование помогает оценить количество действительно ПРОТЕСТИРОВАННОГО кода

28 of 37

Как использовать?

npm install --save-dev @stryker-mutator/core

npx stryker init

29 of 37

На выходе получаем оценки качества

  • Stryker пошагово мутирует строчки кода
  • Если в этот момент не происходит падения теста, выходит что тест бесполезен
  • Изучим отчет!

30 of 37

Вопросы?

31 of 37

E2E test config

32 of 37

О преимуществах E2E тестов

  • Позволяет проверить user test cases
  • Полная проверка приложения на работоспособность
  • Довольно легко настроить

33 of 37

Jest-puppeteer

34 of 37

GitHub Actions

35 of 37

Actions

36 of 37

Вопросы?

37 of 37

Спасибо

за внимание!