Progress-servis55.ru

Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Unit test javascript

QUnit. Тестирование javascript кода

Наткнулся вчера на этот инструмент и не смог пройти мимо, провел ночь за написанием тестов, а теперь хочу поделиться находкой. QUnit — это библиотека от разработчиков jQuery, позволяющая писать unit-тесты для кода на javascript. Удобна в использовании, ничего лишнего, осваивается за 20 минут, выгода от применения — колоссальная.

Самым нетерпеливым сразу ссылки:
Официальная документация на сайте jquery: docs.jquery.com/QUnit
Реальные примеры тестов (для модулей jquery): view.jquery.com/trunk/jquery/test/unit
Руководство для начинающих (англ): www.swift-lizard.com/2009/11/24/test-driven-development-with-jquery-qunit
Система распределенного тестирования (гениально и просто): testswarm.com

Под катом информация о преимуществах юнит-тестирования применительно к js и разбор возможностей библиотеки на примерах.

Зачем писать unit-тесты?

Представим себе обычный цикл разработки: получили задачу, решили её, протестировали, починили баги и выпустили версию. Затем получили баг-репорты и фиче-реквесты и приступили к новому циклу разработки. По завершению этого цикла нам снова надо будет проверить, что всё то, что было реализовано ранее, по прежнему работает — провести регрессионное тестирование. И проводить его надо будет для каждого нового цикла разработки. По мере разрастания проекта на это будет уходить всё больше и больше времени. А как происходит регрессионное тестирование в web-проектах? Кликаем мышкой по кнопкам и ссылкам. В каждом браузере, для каждой фичи, на каждом цикле разработки. Нашли баг, поправили, обновляем страницу и снова кликаем, кликаем, кликаем.

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

Касательно web-разработки есть ещё одно огромное преимущество — запуск тестов под разными платформами и браузерами. Больше нет нужды проверять дотошно, как этот кусок кода будет работать в msie, понравится ли он опере, а как к нему отнесется сафари. Достаточно написать тест, который проверит функциональность. Более того, эту работу можно распределить между обычными пользователями, хороший пример такой функциональности — testswarm.com.

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

DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01 Transitional//EN»
«http://www.w3.org/TR/html4/loose.dtd» >
html >
head >
link rel =»stylesheet» href =»qunit.css» type =»text/css» media =»screen» >
script type =»text/javascript» src =»qunit.js» > script >

script >
head >
body >
h1 id =»qunit-header» > QUnit test env h1 >
h2 id =»qunit-banner» > h2 >
h2 id =»qunit-userAgent» > h2 >
ol id =»qunit-tests» >
ol >
body >
html >

* This source code was highlighted with Source Code Highlighter .

Теперь подключаем свой код и можно писать тесты.

Как писать тесты

* This source code was highlighted with Source Code Highlighter .

А вот так её можно протестировать:

test( ‘trim()’ , function () <
equals(trim( » ), » , ‘Пустая строка’ );
ok(trim( ‘ ‘ ) === » , ‘Строка из пробельных символов’ );
same(trim(), » , ‘Без параметра’ );

equals(trim( ‘ x’ ), ‘x’ , ‘Начальные пробелы’ );
equals(trim( ‘x ‘ ), ‘x’ , ‘Концевые пробелы’ );
equals(trim( ‘ x ‘ ), ‘x’ , ‘Пробелы с обоих концов’ );
equals(trim( ‘ x ‘ ), ‘x’ , ‘Табы’ );
equals(trim( ‘ x y ‘ ), ‘x y’ , ‘Табы и пробелы внутри строки не трогаем’ );
>);

* This source code was highlighted with Source Code Highlighter .

Разберем пример построчно. В первой строке вызов функции test. Первым параметром обозначаем функционал который тестируем. Последним — тестирующую функцию. Внутри этой функции производятся различные проверки. В данном случае мы проверяем соответствие результата выполнения функции и ожидаемой строки. Для проверки на соответствие используются функции:

  • equals — проверяет равенство первых двух параметров (нестрогая проверка, только для скалярных величин)
  • ok — истинность первого параметра
  • same — строгая проверка на равенство первых двух параметров (проверяет также равенство двух массивов и объектов)

Последним параметром функции принимают описание тестового случая.
В результате этой проверки получаем следующую картину:

Все тесты пройдены.

Как протестировать ajax? Асинхронные проверки.

С синхронными функциями просто. А что с асинхронными? Очевидно, для асинхронности мы должны остановить нормальный поток управления и по окончанию теста возобновить его. Этому служат функции stop() и start(). Вот простой пример:

test( ‘async’ , function () <
// Останавливаем поток выполнения на этом тесте
stop();

setTimeout( function () <
ok( true );

// По завершению теста
// возобновляем работу тестировщика
start();
>, 500);
>);

* This source code was highlighted with Source Code Highlighter .

Чтобы не вызывать всякий раз stop(); предусмотрен следующий вариант функции:

asyncTest( ‘async’ , function () <
// поток остановлен автоматически

setTimeout( function () <
ok( true );

// Возобновляем конечно же вручную
start();
>, 500);
>);

* This source code was highlighted with Source Code Highlighter .

А что если надо вызвать несколько асинхронных проверок в одном тесте? Когда в этом случае «стартовать» поток? Решение предлагается такое:

asyncTest( ‘asynctest’ , function () <
// Pause the test
expect(3);

$.get( function () <
// асинхронные проверки
ok( true );
>);

$.get( function () <
// другие асинхронные проверки
ok( true );
ok( true );
>);

setTimeout( function () <
start();
>, 2000);
>);

* This source code was highlighted with Source Code Highlighter .

Поток стартуется через 2 секунды. За это время должны пройти три проверки (вызов expect сообщает об этом тестирующей программе). Кстати, вместо вызова expect можно передавать второй числовой параметр функции test (asyncTest). Поведение будет идентичным предыдущему примеру.

Группировка тестов по модулям

QUnit позволяет сгруппировать тесты по модулям. Для этого достаточно вызвать функцию module(‘Название модуля или группы тестов’) непосредственно перед вызовом тестов. Это удобно.

Читать еще:  Java thread interrupt

Unit-тестирование в JavaScript

Введение

Разработчики применяют браузерный javascript для:

  • обработки событий на странице;
  • формирования HTML-контента;
  • работы с AJAX.

Используя вместе QUnit и Sinon.JS, можно написать юнит-тесты для любого из этих применений.

QUnit — framework для юнит-тестирования javascript, созданный и используемый разработчиками jQuery, предоставляет базовый функционал для написания тестов, их группировки и проверки утверждений.

Sinon.JS — mock-библиотека для javascript, которую можно использовать с любым тестовым фреймворком. Их совместное использование будет продемонстрировано на небольшом примере текстового чата. Скачать пример можно из репозитория на GitHub.

Быстрый старт

Предполагается, что тестируемое API хранится в отдельном файле chat.js, код юнит-тестов будем писать в отдельном файле chat.tests.js, а для запуска тестов создадим страницу tests.html, в которой пропишем ссылки на тестируемое API, код тестов и необходимые библиотеки:

Для запуска тестов надо открыть страницу tests.html в браузере, здесь мы увидим такой результат:

Опция “Check for globals” проверяет наличие глобальных переменных в API и тестах, что очень полезно для предотвращения конфликтов.

Если включена опция “No try-catch”, то тесты будут выполняться до первого exception, что не позволит прогнать весь набор тестов, но даст доступ к низкоуровневой информации об исключительной ситуации, что удобно для отладки в старых браузерах.

Asserts

Для проверки утверждений в юнит-тестах QUnit предоставляет несколько функций. Обратите внимание, что в отличие от других xUnit-фреймворков актуальное значение указывается первым аргументом, а ожидаемое — вторым (кроме функции ok(), в которой проверяется первый аргумент). Последним аргументом может быть строка с пояснением, что именно проверяется утверждением.

  • ok() — ожидает истинность первого аргумента
  • equal() / notEqual() — для сравнения используется оператор ==
  • deepEqual() / notDeepEqual() — для сравнения используется оператор ===
  • strictEqual() / notStrictEqual() — для сравнения используется оператор (===
  • throws() — ожидает, что будет сгенерирована исключительная ситуация.

Простой пример

Для создания юнит-теста QUnit предоставляет функцию test(), первым аргументом которой является строка с названием теста, вторым — функция, содержащая код теста. В этом примере проверяется, что вызов метода из тестируемого API вернет объект ожидаемой структуры.

Пример посложнее с использованием верстки

Специальный div #qunit-fixture удобно использовать для тестирования генерируемой верстки, так как QUnit очищает его после каждого теста, что обеспечивает атомарность.

Модули, конфигурация

QUnit позволяет объединять тесты в модули, это удобно для группировки тестов сходного функционала. Модуль может иметь переменные, видимые в каждом тесте, а также функции setup() и teardown(), которые выполняются перед и после каждого теста соответственно, и в которых можно инициализировать и очищать общие данные. Модуль начинается с функции module(), после которой может идти n-ное количество функций test(), все n тестов будут принадлежать этому модулю. Модуль кончится тогда, когда начнется следующий модуль.

В тесте используем инициализированные в setup() переменные:

Что дает Sinon.JS

Библиотека Sinon.JS предоставляет функции для эмуляции и проверки требуемого поведения в javascript. Sinon создает обертку поверх функции или объекта. Обертки могут быть 3-х видов — spy, stub и mock — они предоставляют интерфейс для проверки правильности доступа к эмулируемому ресурсу.

Самая простая обертка, выполняет слежение за вызовом. Исходный объект не меняется, и в него предается управление. Удобна для проверки того, какая функция с какими параметрами была вызвана. Некоторые члены интерфейса:

  • calledOnce() — возвращает true, если функция была вызвана ровно один раз
  • callCount — счетчик вызовов функции
  • getCall(m).args[n] — возвращает n-ный аргумент m-ного вызова
  • getCall(m).calledWith(args) — проверяет, что m-ный вызов произошел с указанными аргументами.

Расширяет интерфейс spy, при этом оригинальный объект замещается и не вызывается. Можно настраивать требуемое поведение эмулируемого объекта при вызове, например возвращаемое значение.

Пример использования spy и stub:

Эмуляция сервера

Sinon.JS позволяет эмулировать ответ сервера при ajax-запросах:

Моки — дальнейшее развитие идеи заглушек, они дают возможность тонко настроить ожидаемое поведение объекта и затем проверить, что работа с эмулируемым объектом проходила должным образом.

Интеграция с ant

Запустить юнит-тесты во время автоматической сборки (и остановить сборку в случае падения теста) можно при помощи PhantomJS (это запускаемый в консоли WebKit) и специального раннера. После установки PhantomJS создайте переменную окружения PHANTOMJS_HOME, указывающую на папку PhantomJS.

Ниже приведен пример ant-проекта, который выполняет QUnit-тесты во время сборки:

Автоматические тесты при помощи chai и mocha

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/testing-mocha.

В этой главе мы разберём основы автоматического тестирования. Оно будет применяться далее в задачах, и вообще, входит в «образовательный минимум» программиста.

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

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

В процессе разработки мы время от времени проверяем, правильно ли работает функция. Самый простой способ проверить – это запустить её, например в консоли, и посмотреть результат.

Если что-то не так, поправить, опять запустить – посмотреть результат… И так «до победного конца».

Но такие ручные запуски – очень несовершенное средство проверки.

Когда проверяешь работу кода вручную – легко его «недотестировать».

Например, пишем функцию f . Написали, тестируем с разными аргументами. Вызов функции f(a) работает, а вот f(b) не работает. Поправили код – стало работать f(b) , вроде закончили. Но при этом забыли заново протестировать f(a) – упс, вот и возможная ошибка в коде.

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

Читать еще:  Ошибка передачи данных

BDD – поведенческие тесты кода

Мы рассмотрим методику тестирования, которая входит в BDD – Behavior Driven Development. Подход BDD давно и с успехом используется во многих проектах.

BDD – это не просто тесты. Это гораздо больше.

Тесты BDD – это три в одном: И тесты, И документация, И примеры использования.

Впрочем, хватит слов. Рассмотрим примеры.

Разработка pow: спецификация

Допустим, мы хотим разработать функцию pow(x, n) , которая возводит x в целую степень n , для простоты n≥0 .

Ещё до разработки мы можем представить себе, что эта функция будет делать, и описать это по методике BDD.

Это описание называется спецификация (или, как говорят в обиходе, «спека») и выглядит так:

У спецификации есть три основных строительных блока, которые вы видите в примере выше:

Задаёт, что именно мы описываем, используется для группировки «рабочих лошадок» – блоков it . В данном случае мы описываем функцию pow .

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

Код внутри it , если реализация верна, должен выполняться без ошибок.

Различные функции вида assert.* используются, чтобы проверить, делает ли pow то, что задумано. Пока что нас интересует только одна из них – assert.equal , она сравнивает свой первый аргумент со вторым и выдаёт ошибку в случае, когда они не равны. В данном случае она проверяет, что результат pow(2, 3) равен 8 .

Есть и другие виды сравнений и проверок, которые мы увидим далее.

Поток разработки

Как правило, поток разработки таков:

  1. Пишется спецификация, которая описывает самую базовую функциональность.
  2. Делается начальная реализация.
  3. Для проверки соответствия спецификации мы задействуем фреймворк (в нашем случае Mocha). Фреймворк запускает все тесты it и выводит ошибки, если они возникнут. При ошибках вносятся исправления.
  4. Спецификация расширяется, в неё добавляются возможности, которые пока, возможно, не поддерживаются реализацией.
  5. Идём на пункт 2, делаем реализацию. И так «до победного конца».

Разработка ведётся итеративно: один проход за другим, пока спецификация и реализация не будут завершены.

В нашем случае первый шаг уже завершён, начальная спецификация готова, хорошо бы приступить к реализации. Но перед этим проведём «нулевой» запуск спецификации, просто чтобы увидеть, что уже в таком виде, даже без реализации – тесты работают.

Пример в действии

Для запуска тестов нужны соответствующие JavaScript-библиотеки.

Мы будем использовать:

  • Mocha – эта библиотека содержит общие функции для тестирования, включая describe и it .
  • Chai – библиотека поддерживает разнообразные функции для проверок. Есть разные «стили» проверки результатов, с которыми мы познакомимся позже, на текущий момент мы будем использовать лишь assert.equal .
  • Sinon – для эмуляции и хитрой подмены функций «заглушками», понадобится позднее.

Эти библиотеки позволяют тестировать JS не только в браузере, но и на сервере Node.JS. Здесь мы рассмотрим браузерный вариант, серверный использует те же функции.

Пример HTML-страницы для тестов:

Эту страницу можно условно разделить на четыре части:

  1. Блок – в нём мы подключаем библиотеки и стили для тестирования, нашего кода там нет.
  2. Блок

Этот файл содержит код библиотек, стили, настройки для них и запуск mocha.run по окончании загрузки страницы. Если нет элемента с , то результаты выводятся в .

Сборка сделана исключительно для более компактного представления задач, без рекомендаций использовать именно её в проектах.

11 Best JavaScript Unit Testing Framework and Tools

A little introduction to JS unit testing and its framework and tools

The web development coding scenario has changed exponentially over the last few years. The world is transitioned from conventional programming languages like Java, .NET, and PHP. They have started adapting to the JavaScript framework due to its ease of use in frontend as well as backend and rapid prototyping capabilities.

With this transition, comes the need for excellent testing tools too. In this article, I will take you through some of the best javascript unit testing tools being used in the industry.

Importance of Unit testing

Before we get into understanding the available tools and their benefits, let us understand why unit testing is important.

Unit testing is the process of testing the implemented code at a module level. Unit testing allows you to ensure that your developed modules are meeting the requirements specified by the business document. These tests are written for every module as they are created. After every new module development, the entire suite of test cases is run to ensure that no existing modules are affected by the developed module.

Javascript development could get quite unorganized if the right conventions are not followed. This makes it necessary to utilize the right development & unit testing tools. Javascript unit tests for frontend mainly run on actual or headless browsers

These tests focus on testing the usability and responsiveness of the application. The backend unit testing frameworks focus on testing business logic and service endpoints for NodeJS based backend code.

MochaJS

MochaJS is the most popular testing framework that supports backend and frontend testing. MochaJS is a flexible base for developing tests as you need. It runs the tests asynchronously on Chrome v8 engine or any other browser.

The major benefits of Mocha include:

  • Works for frontend as well as backend
  • Support NodeJS debugger
  • Provides a clean base to develop tests as per the developer’s convenience
  • Supports any browser including headless chrome library
  • Supports object mocking to perform flexible backend tests

Jasmine

Jasmine is a user-behavior mimicker that allows you to perform test cases similar to user behavior on your website. Jasmine is useful for a testing frontend for visibility, click clarity as well as the responsiveness of the UI in different resolutions. Jasmine allows to automate user behavior with customs delays and wait time to simulate actual user behavior.

The major benefits of using Jasmine include:

  • Lower overhead due to almost zero external dependencies
  • Comes with almost every required tool out of the box
  • Supports Frontend as well as Backend tests
  • The coding is pretty similar to writing in natural language
  • Extensive documentation to use it with several frameworks

AVA is a minimalistic light-weight testing framework that leverages asynchronous nature of Javascript. AVA can perform tests concurrently.

It allows you almost complete control over what you do. It is primarily focused on running tests for NodeJS based code. Some of the benefits include:

  • Light footprint makes it faster
  • Runs tests asynchronously and concurrently
  • Faster than most other test frameworks
  • The simpler syntax for Javascript tests
  • Cleaner stack traces for any potential errors that are detected

JEST is one of the most popular frameworks that is maintained regularly by Facebook. It is a preferred framework for the React based applications as it requires zero configuration.

However, it is not limited to use with React. Some of the JEST features are:

  • Single framework fit for NodeJS, VueJS, React, Angular and other Babel based projects
  • Easier to get off the ground
  • Well documentation and standard syntax of coding
  • With Live snapshots, it allows managing tests with larger objects

Karma

Karma is a productive testing environment that supports all the popular test description framework within itself. It provides your application the support to execute tests in different environments. It has wide support for executing tests on different devices and applications.

The primary factor to choose Karma lies in its support to integrate with CI/CD engines and the following features.

  • Can be used to run tests on browsers, headless environments like PhantomJS as well as on devices
  • Supports tests written in most of the popular frameworks
  • Allows to run tests remotely onto other devices by just coming files
  • Supports test case debugging using Chrome as well as Webstorm

Tape is pretty similar to AVA in its architecture. It does not support globals, and hence you need to include Tape in each test file. This decision of restricting globbing of variables has its benefits too. Some of the features highlight:

  • Clean light-weight footprint
  • Provides just bare-metal code and gives the developer complete freedom to write test cases
  • Supports ES6, Typescript and coffee script standards
  • Supports test execution on most modern browsers

Cypress.io

Cypress is an exciting testing framework that practically runs on the browser. It provides an interactive UI on the browser in the form of a web page. It can be easily installed on Mac, Windows as well as Linux. It is an independent test runner that does not need to integrate with your code closely.

Puppeteer

Puppeteer is an excellent test execution framework built by a team at Google. It provides a headless chrome API for NodeJS applications.

Puppeteer is primarily used for applications specific to the browser like crawl test, page structure test, take screenshots and even capture pre-rendered content for single page applications. Additional benefits of using puppeteer are:

  • Ability to set custom resolutions and sizes for the browser
  • Support to test chrome extensions
  • Automation support for form submission, UI testing, and keyboard inputs
  • Supports ES6 functionalities like await and async

ChaiJS

ChaiJS framework focuses on behavior-driven testing. It can be used in parallel with any other framework. It has been around for quite a while now and has evolved with the evolution in Javascript standards.

ChaiJS works with Node, browser, rail and got great support community and documentation.

Qunit

Qunit – a powerful testing framework dedicated to using with a frontend. It is the first choice by developers of the JQuery, JQuery Mobile and JQuery UI libraries.

It can be written as an independent JS file and executed on any webpage. The standard method of testing using Qunit is to include the file onto the webpage and run tests using Qunit plugin. The benefits of QUnit include:

  • Can be used to build re-usable test scripts
  • Provides a ready-to-deploy web interface for viewing test case outputs visually
  • A pool of plugins built on top of it allows faster test case development

Sinon

Sinon.js compliments the unit testing framework to fake/mock the real things. Because during testing – you won’t have all the data! It supports Chrome, IE 11, Firefox, Edge, Safari and Node.js runtimes.

A good alternative to Sinon would be testdouble.js

Conclusion

Unit testing is essential to ensure code changes doesn’t break the application, and it works as per business requirement. And, I hope above helps you with that. If you are a newbie, then you may like this online course which teaches you doing JS unit testing with ChaiJS, Sinon and Mocha.

Ссылка на основную публикацию
Adblock
detector