В этой статье я буду использовать среду тестирования Jest. Есть много других фреймворков для тестирования, но сейчас мне больше всего нравится Jest, и я буду использовать его в этой статье.

Прежде всего, что такое тестирование? Тестирование (т. е. тестирование программного обеспечения) - это расследование, проводимое с целью предоставления заинтересованным сторонам информации о качестве тестируемого программного продукта или услуги.

Это могло показаться многообещающим, позвольте мне остановиться. Тестирование программного обеспечения включает в себя процесс проверки вашего кода вручную или автоматически (то есть полуавтоматически), чтобы убедиться, что код функционирует должным образом.

Тест, о котором мы будем говорить в этой статье, - это автоматический тест, тесты, которые вы хотите создать, чтобы помочь вам найти все (или как можно больше) крайних случаев в вашем коде. Вскоре я подробнее расскажу об автоматических тестах, но сначала давайте поговорим о том, почему мы тестируем коды.

Типы тестов

  • Модульное тестирование - это уровень тестирования, при котором отдельные модули (компоненты) нашего кода проверяются изолированно от других, цель которого - убедиться, что каждая единица кода функционирует должным образом.
  • Интеграционное тестирование - это уровень тестирования, при котором блоки объединяются в группу и проверяется их совместная работа. Цель состоит в том, чтобы выявить ошибки, которые могут существовать во взаимодействии отдельных блоков.
  • Сквозное тестирование - это уровень тестирования, при котором проверяется поток системы от начала до конца как отдельного приложения и проверяется ее поведение, как ожидалось, цель состоит в том, чтобы выявить системные ошибки и сильные стороны и для обеспечения безопасности данных в системе на всех уровнях системы.

Почему мы должны тестировать наш код

Основная причина тестирования вашего кода - это наличие очень стабильного кода, вы хотите, чтобы ваш код делал именно то, что вы хотите, и вы не хотите, чтобы этот тест выполнялся вручную, проверяя каждую часть. То, что вы делаете, называется автоматическим тестом, вы используете фреймворки для тестирования, такие как Jest. Вы пишете набор тестов, ожидая, что ваш код (функция) будет работать определенным образом или вернет определенное значение; если ваш код действительно проходит это, вы знаете, что вам нужно больше крайних случаев в вашем тесте, за исключением того, что у вас достаточно и покрыли все это, но когда ваш тест терпит неудачу, вы возвращаетесь к своему коду / функциям, вы реорганизуете код и снова тестируете - этот процесс называется регрессионным тестированием.

Популярная поговорка в тестировании заключается в том, что ваш тест не работает при первом запуске.

TDD - Разработка через тестирование

Это процесс разработки продукта (программного обеспечения), который основан на повторении цикла тестирования и разработки, автоматический тест должен быть первым и терпеть неудачу при первом запуске, затем вы пишете функцию для теста.

Обычно соблюдается следующая последовательность шагов:

  • Добавить тест
  • Запустите все тесты и посмотрите, не сработает ли новый (есть ли старые тесты)
  • Напишите код
  • Провести тесты
  • Код рефакторинга
  • Повторить

Фреймворк тестирования (в нашем случае - jest) знает файл, из которого он должен читать тесты, проверяя любой файл с расширением .test.js или .spec.js. Я должен вас предупредить, TDD требует гораздо больше внимания и времени, чем «обычное» программирование.

Давайте настроим

Чтобы иметь возможность выполнять все тесты ниже или даже писать свои собственные тесты, вам необходимо настроить среду для этого.

// In your terminal do the following
$ npm init

$ npm install --save-dev jest
// Then in your package.json file
// change the value of test in scripts to jest

{
  "scripts": {
    "test": "jest"
  }
}

Хватит разговоров, давайте запачкаем руки - не буквально. Мы напишем тест для мини-проекта, который я создал ранее, чтобы объяснить ООП, я уже проводил тестирование при создании мини-проекта, я просто расскажу вам, что такое тестирование и как вы можете выполнять различные тесты, а затем я покажу вам что я сделал при тестировании ранее созданного проекта.

Вы можете прочитать об этом ниже. ⬇️



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

Затем я написал свою функцию-конструктор и продолжаю ее рефакторинг, пока она не пройдет мой вышеупомянутый тест.

Позвольте нам сделать небольшой обходной путь, я сделаю здесь небольшой тест и функцию суммирования, чтобы вы могли увидеть весь процесс. Первое, что мы сделаем, это напишем тест, который, по нашему мнению, должен работать для функции суммы, которая должна быть примерно 2 + 3 = 5.

Поэтому лучше всего сначала написать тест;

const sum = require('./sum') // assuming name of file will be sum 
                            // and they are in the same directory
test(‘Add 1 and 2 to give 3’, () => {
    expect(sum(1,2)).toBe(3);
});

Это не удастся в первый раз, потому что мы еще не написали нашу функцию суммы, затем мы напишем функцию суммы, чтобы убедиться, что мы прошли этот тест.

function sum(a, b) { return a + b }
module.exports = sum; // so we can import it in the Jest file

Это просто, и, как мы видим, это сработает, если мы протестируем в нашей консоли или даже в терминале (возможно, с использованием узла). Теперь нам нужно рассмотреть крайние случаи, например, есть тот, который вы можете знать или не знать,

0.1 + 0.2 = 0.3 // wrong
0.1 + 0.2 = 0.30000000000000004 // correct and this is not only in JavaScript

Итак, как мы протестируем этот пограничный случай, мы можем продолжить, используя другие сопоставители, чтобы решить эту проблему, мы также можем проверить, чтобы убедиться, что он возвращает значение (кривый путь). Для этого мы проверим, возвращает ли он значение вида 0,300… 4.

test(‘Add 0.1 and 0.2 to be close to 0.3’, () => {
    expect(sum(0.1, 0.2)).toBeCloseTo(0.3);
}

Причина, по которой я решил использовать toBeCloseTo в качестве сопоставителя (метода) для этого, заключается в том, что при работе с десятичными значениями есть возможности для большего количества значений после десятичной точки, в зависимости от того, какое вычисление выполняется для значений, поэтому вместо того, чтобы искать точное, я проверяю, находится ли оно где-то в этом диапазоне.

Теперь вы можете увидеть, как мы вышли из теста, написали функцию для прохождения теста, расширили наш пограничный случай, написали для него тест, а затем мы все равно пройдем с нашей функцией. Теперь вы можете продолжить, чтобы убедиться, что параметры всегда являются числами, а также проверить отрицательные значения.

Найдите ниже набор тестов, функция суммы, которая у нас выше, не удастся выполнить некоторые тесты, вам нужно будет реорганизовать ее, чтобы пройти все тесты.

Прежде чем мы углубимся, позвольте мне познакомить вас с Jest expect Api.

Jest ожидает, что Api имеет ряд сопоставителей, которые вы можете использовать. Похоже, Jest уже учел все, что можно проверить, вы можете проверить истинность, числа, объекты, массивы, содержащие определенные значения, и многое другое. Когда вы пишете тесты, вам часто нужно проверить, соответствуют ли значения определенным условиям. expect дает вам доступ к ряду сопоставителей, которые позволяют проверять разные вещи. Очевидно, что мы не можем говорить обо всех возможных сопоставлениях или методах, однако мы будем говорить о .toBe(), .toMatch() и .toEqual(). Чтобы узнать больше о expect, посетите страницу документации Jest expect Api.

.быть()

.toBe() используется для сравнения примитивных значений. Он вызывает Object.is для сравнения значений, что, согласно документации Jest, лучше для тестирования, чем ===. Вы не должны использовать .toBe() со значениями с плавающей запятой, как и в случае с 0.1 + 0.2 выше, он не преобразуется в 0.3, что делает .toBe() неподходящим для теста, но .toBeCloseTo() является правильным методом для чисел с плавающей запятой.

test(‘Add 1 and 2 to give 3’, () => {
    expect(sum(1,2)).toBe(3); 
});

.toMatch ()

.toMatch() используется для сравнения строки с регулярным выражением (регулярным выражением) или с другой строкой. Например, вы можете не знать, что возвращает функция, но знаете, что в ней должен быть конкретный текст, вы можете создать регулярное выражение для проверки, чтобы убедиться, что она возвращает правильный результат; позвольте нам использовать returnString () в качестве нашей функции, она возвращает 'I am learning testing with you, yes you!', помните, что мы не знаем, что он возвращает указанное выше, мы собираемся затем написать тест для проверки с использованием регулярного выражения, а также еще один тест, когда мы уверены в том, что мы хотим для возврата мы также можем использовать только часть ожидаемой строки.

test(‘A statement on learning’, () => {
    expect(returnString()).toMatch(/testing/); // using regex
    expect(returnString()).toMatch('I am learning testing with you, yes you') // using the exact string you want returned
    expect(returnString()).toMatch('I am learning ') // using just a part of the string
});

.равному()

.toEqual() используется для сравнения двух одинаковых объектов в деталях (проверка всех свойств объекта). Он также вызывает Object.is для сравнения значений, что, согласно документации Jest, лучше для тестирования, чем === (строгое равенство).

const obj1 = {
    isArticle: true,
    title: 'Testing your JavaScript Code — TDD'
}
const obj2 = {
    isArticle: true,
    title: 'Testing your JavaScript'
}
const obj3 = {
    isArticle: true,
    title: 'Testing your JavaScript Code — TDD'
}
test(‘Checking two objects to make sure they are qual’, () => {
    expect(obj1).toEqual(obj2); // wrong
    expect(obj1).toEqual(obj3); // correct
});

Вы можете запустить вышеуказанное, чтобы убедиться. Вам также следует ознакомиться с Документацией Jest, чтобы узнать больше о Jest и тестировании в целом.

С нашим не таким уж маленьким обходным путем, я думаю, вам следовало ознакомиться с Jest, это ожидает Api и то, что происходит в нашем тестовом файле. Теперь вернемся к предмету: мы добавим еще несколько тестов для наших функций ООП, я объясню некоторые из тестов здесь и покажу вам, как должен выглядеть ваш результат, когда вы еще не прошли тесты и когда вы все пройдете. Если вы хотите увидеть полный набор тестов и функции, вам следует клонировать репозиторий.

Итак, давайте добавим тестовые примеры;

Первый тестовый пример, приведенный выше, предназначен для создания записи студента, мы сначала создаем экземпляр пользователя, которого хотим использовать для создания записи из пользовательского конструктора, затем мы вызываем метод .createRecord для пользователя - jon.createRecord('4.3', 'Very brilliant chap', ‘0032’), а затем используем .toBe() matcher, чтобы проверить, возвращает ли он точное возвращаемое значение. Обратите внимание, что я проверяю, когда студент (пользователь без разрешения) пытается выполнить ту же функцию и что она возвращает.

Второй тест проверяет, читает ли администратор запись студента по его идентификатору. Как видите, в этом тесте мы использовали методы .toEqual() и .toMatch(). Как и в других случаях, мы создаем пользователя для тестирования, затем выполняем метод .readById - cersei.readById(1), затем используем сопоставление .toEqual(), а затем вы можете видеть expect.objectContaining() - эта часть теперь ожидает возвращаемое значение, которое будет объектом и должно содержать то, что указано в скобках - уловка здесь заключается в том, чтобы добавить литерал объекта {} в скобку перед парой key: 'value', это поможет преобразовать его в объект. Затем в следующей строке мы проверяем, когда пользователь без разрешения пытается выполнить функцию, затем мы используем метод .toMatch(), а затем проверяем часть полной строки.

Покрытие

Это одна из частей шутки, которую я так люблю, она помогает вам узнать, сколько кода вы покрыли. Вы можете узнать части своего кода, которые вам еще предстоит протестировать, и вы знаете, что проделали хорошую работу, когда набрали полные 100 во всех частях вашего кода.

Как видите, я не набрал 100 по всем параметрам, и после нескольких проверенных крайних случаев я смог завершить это покрытие и набрать все 100. Вам следует стремиться к 100, но не убивать себя в процессе (т. Е. Не тратить зря драгоценное время). Есть еще кое-что, что нужно сделать, чем попытаться достичь 100, но до того, как вы прекратите попытки убить себя, убедитесь, что вы попали как минимум на 92%.

Чтобы охватить ваши тесты, добавьте --coverage к вашим скриптам в package.json.

{
  "scripts": {
    "test": "jest --coverage"
  }
}

Ниже представлен мой полный комплект - с 100% покрытием.

Запуск тестов

Выполнить набор тестов, или только один тест, или вообще любой тест действительно просто и понятно, все, что вам нужно, это npm run test. Когда вы вводите это в свой терминал и нажимаете кнопку ввода (пока вы находитесь в папке проекта), jest найдет тестовые файлы и запустит тест.

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

Если вам нужна полная кодовая база для фиктивного проекта, созданного в этом уроке, вам следует клонировать studentReport.

📝 Прочтите этот рассказ позже в Журнале.

👩‍💻 Просыпайтесь каждое воскресное утро и слушайте самые интересные истории из области технологий, ожидающие вас в вашем почтовом ящике. Прочтите информационный бюллетень« Примечательно в технологиях .