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

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

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

Пирамиды тестирования

«Пирамида тестов» — абстракция, которая означает группировку тестов программного обеспечения по разным уровням детализации.

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

Из этой пирамиды главное запомнить два принципа:
 

  1. Писать тесты разной детализации.
  2. Чем выше уровень, тем меньше тестов.


Придерживайтесь формы пирамиды, чтобы придумать здоровый, быстрый и поддерживаемый набор тестов.

-Напишите много маленьких и быстрых юнит-тестов.

-Напишите несколько более общих тестов

- и совсем мало высокоуровневых сквозных тестов, которые проверяют приложение от начала до конца.

Базовая пирамида тестирования

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

Интеграционные тесты - тестирование группы взаимодействующих модулей. Должны занимать середину пирамиды.
Используйте этот уровень для проверки бизнес-логики без использования пользовательского интерфейса (UI);
Тестируя за пределами пользовательского интерфейса, вы можете тестировать входы и выходы API или сервисов без всех сложностей, которые вводит пользовательский интерфейс;
Эти тесты медленнее и сложнее, чем модульные тесты, потому что им может потребоваться доступ к базе данных или другим компонентам.

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

"Идеальная " пирамида тестирования

"Идеальная" пирамида тестирования

"Самая идеальная" пирамида тестирования 😃

Перевернутая пирамида тестирования или "Рожок мороженного" (Ice-cream cone)

Перевернутая пирамида считается не рекомендованной, хотя в практике такой подход встречается.

Основные тезисы:

1. Тесты пользовательского интерфейса должны автоматизироваться в большей мере.
2. Длинные тестовые прогоны. Время выполнения занимает намного больше времени, чем другие типы тестов, потому что оно основано на взаимодействии с визуальными элементами пользовательского интерфейса и не обязательно имеет хуки в исходном коде;
3. Сложно поддерживать, так как тесты пользовательского интерфейса сложно писать и они очень сильно зависят даже от малейших изменений;
4. Больше подходит для сценариев позитивного пути. Тестирование отрицательных путей в сквозных тестах очень затратно и долго выполняется по сравнению с тестами более низкого уровня;
5. Ожидание написания модульных тестов до тех пор, пока функции не будут завершены, может привести к тому, что каждому придется несколько раз выполнить большую работу для решения проблемы.

Инструменты

unit-тестирования

Mocha JS - эта библиотека содержит общие функции для тестирования, включая describe и it.

Установка:

npm install --save-dev mocha

Использование:

// test/my_cool_function.js
const assert = require('assert'); // NodeJS модуль
const myCoolFunction = require('./my_cool_function'); // ваша функция

describe('myCoolFunction', () => {
  describe('cool usage', () => {
    it('should return cool name', () => {
      const name = myCoolFunction('Alex')
      assert.equal(name, 'Alex is cool');
    });
  });
});

Запуск в терминале:

./node_modules/mocha/bin/mocha

// а лучше создать скрипт в файле package.json
// 
//  "scripts": {
//    "test": "mocha"
//  }
//  
//  и запускать команду

npm run test

THE TEST/ DIRECTORY

По дефолту, mocha при запуске тестов ищет файлы со следующим паттерном -  "./test/*.js", так что можно просто создавать папки с названием test и складывать туда тестовые файлы к своим модулям (обычно файлы тестов называют в честь самих модулей, т.е. если у вас есть модуль "./printUser.js", то тесты к нему будут лежать в "./test/printUser.js").

Если необходимо поменять название папки с тестами, можно передать свой паттерн при запуске в CLI:

 

 
$ mocha --recursive "./spec/*.js"

Chai – библиотека, предоставляющая множество функций проверки утверждений.

Установка:

npm install chai -D

Использование:

// Assertions
const assert = require('chai').assert
const foo = 'bar';
const beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };

assert.typeOf(foo, 'string');
assert.equal(foo, 'bar', 'foo equal `bar`'); // 3 параметр - опциональный - сообщение
assert.lengthOf(foo, 3, 'foo`s value has a length of 3');
assert.lengthOf(beverages.tea, 3, 'beverages has 3 types of tea');

// Expectations
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
expect(beverages).to.have.property('tea').with.lengthOf(3);

Полезные статьи для самостоятельного прочтения:

 

testing

By Daniel Suleiman

testing

Основы тестирования приложений

  • 652