понедельник, 20 октября 2014 г.

Mocha with Chai and Sinon in Browser

Тестирование JavaScript-кода через Mocha JS вместе с Chai и Sinon в браузере.



Представим, что ваш проект имеет следующую структуру расположения папок и файлов:

/css
/js/jquery.js
/js/index.js
/index.html

Файл jquery.js вы можете скачать с сайта jquery.com

Код файла index.js

function sayOK(){
    return 'OK';
}

function hello(name, callback) {
    callback('hello ' + name);
}

Код файла index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    alert(sayOK());
    hello('Boris', alert);
});
</script>
<title>My Page</title>
</head>
<body>
<h1>My Page</h1>
</body>
</html>

При открытии файла index.html в браузере будет выполнен код функции sayOK() и выведено сообщение "ОК", после чего будет выполнена функция hello и выведено сообщение "Hello Boris".

Для функций sayOK() и hello() нам необходимо будет написать тесты, которые будут выполняться через Mocha JS в браузере.

Для тестирования JavaScript-кода через Mocha JS в браузере необходимо скачать и файл "mocha.js" с кодом библиотеки Mocha JS, который расположен в GitHub по адресу

https://raw.githubusercontent.com/visionmedia/mocha/master/mocha.js

и файл "mocha.css" со стилями оформления для вывода результатов тестирования на страницу в браузере, который расположен в GitHub по адресу

https://raw.githubusercontent.com/visionmedia/mocha/master/mocha.css

Файл mocha.js скопируйте в папку js. А файл mocha.css скопируйте в папку css.

После этого структура расположения папок и файлов в проекте будет выглядеть так:

/css/mocha.css
/js/mocha.js
/js/jquery.js
/js/index.js
/index.html

Далее в папке js создадим файл tests.js, к котором напишем тесты для функции sayOK() с применением Mocha JS.

Код файла tests.js

// Код функции запуска тестов

function runTests() {

    mocha.setup('bdd');  // Устанавливаем тип тестов BDD
 
    // Определяем функцию assert, которую будем использовать для тестов ниже.

    function assert(expr, msg) {
        if (!expr) throw new Error(msg || 'failed');
    }

    // Создаем набор тестов, использующих Mocha JS
 
    describe("Say OK Tests", function() {
 
      describe("Function must return OK", function() {
        it("returns OK", function() {
          var result = sayOK();
          assert(result === 'OK');
        });
      });
 
      describe("Function return OKI", function() {
        it("returns OK", function() {
          var result = sayOK() + 'I';
          assert(result === 'OKI');
        });
      });
 
      describe("Function return Not a Number", function() {
        it("returns NaN", function() {
          var result = sayOK();
          assert(isNaN(result));
        });
      });
   
    });
 
    var runner = mocha.run(); // Запускаем наш набор тестов

}

$(document).ready(function(){
    runTests(); // Запускаем наши тесты после загрузки страницы
});

Теперь структура нашего проекта будет выглядеть так:

/css/mocha.css
/js/mocha.js
/js/jquery.js
/js/index.js
/js/tests.js
/index.html

Далее создадим HTML-файл testrunner.html, который мы будем открывать в браузере для запуска тестов нашего кода.

Код файла testrunner.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="css/mocha.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/mocha.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/tests.js"></script>
<title>Test Runner</title>
</head>
<body>
    <div id="mocha"></div>
</body>
</html>

В файле testrunner.html производится загрузка файла библиотеки Mocha JS, файла index.js с кодом функции sayOK(), которую мы будем тестировать и набор тестов для этой функции в файле tests.js, которые автоматически запускаются после загрузки файла testrunner.html в браузере.

Результаты выполнения тестов помещаются в специальный блок <div id="mocha"></div> внутри тэга <body>.

Полная структура проекта в итоге будет выглядеть так:

/css/mocha.css
/js/mocha.js
/js/jquery.js
/js/index.js
/js/tests.js
/index.html
/testrunner.html

Теперь, если вместо определенной нами в файле tests.js функции

    function assert(expr, msg) {
        if (!expr) throw new Error(msg || 'failed');
    }

мы захотим использовать для тестирования JavaScript-кода библиотеку Chai, то скопируем в папку js файл chai.js, который можно взять по адресу

chaijs.com/chai.js

В результате структура нашего проекта станет выглядеть так:

/css/mocha.css
/js/mocha.js
/js/chai.js
/js/jquery.js
/js/index.js
/js/tests.js
/index.html
/testrunner.html

В HTML-файле для запуска тестов testrunner.html добавим ссылку на файл chai.js

Итоговый код файла testrunner.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="css/mocha.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/mocha.js"></script>
<script type="text/javascript" src="js/chai.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/tests.js"></script>
<title>Test Runner</title>
</head>
<body>
    <div id="mocha"></div>
</body>
</html>

В файле tests.js удалим код функции assert() и заменим старые тесты на тесты, использующие код билиотеки Chai.

Итоговый код файла tests.js

// Код функции запуска тестов

function runTests() {
 
    mocha.setup('bdd'); // Устанавливаем тип тестов BDD    
 
    // Создаем набор функций для тестирования с использованием библиотеки Chai.

    var assert = chai.assert,
          expect = chai.expect,
          should = chai.should(); // Обратите внимание, что should должна быть иметь скобки ()

    // Создаем набор тестов, использующих Mocha JS вместе с Chai

    describe('Say OK Tests', function() {
                             
      describe('Function sayOK()', function() {
                                   
        it('should work with assert', function() {
            assert.equal(sayOK(), 'OK');
        });
 
        it('should work with expect', function() {
            expect(sayOK()).to.equal('OK');
        })
 
        it('should work with should', function() {
            sayOK().should.equal('OK');
        });
     
      });
   
    });
 
    var runner = mocha.run();
 
}

$(document).ready(function(){
    runTests();
});

Таким образом для тестирования JavaScript-кода в браузере можно использовать Mocha JS вместе с Chai.

Если вам потребуется использовать библиотеку Sinon, то вам необходимо будет скачать файл "sinon.js" с кодом библиотеки Sinon, который расположен в GitHub по адресу

http://sinonjs.org/releases/sinon-1.10.3.js

и плагин для библиотеки Chai, который расположен по адресу

https://raw.githubusercontent.com/domenic/sinon-chai/master/lib/sinon-chai.js

Файл sinon-1.10.3.js переименуем в sinon.js. Теперь скопируйте в папку js файлы sinon.js и sinon-chai.js.

В файле testrunner.html после строчки

<script type="text/javascript" src="js/chai.js"></script>

вставьте эти строки

<script type="text/javascript" src="js/sinon-chai.js"></script>
<script type="text/javascript" src="js/sinon.js"></script>

Итоговый код файла testrunner.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="css/mocha.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/mocha.js"></script>
<script type="text/javascript" src="js/chai.js"></script>
<script type="text/javascript" src="js/sinon-chai.js"></script>
<script type="text/javascript" src="js/sinon.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/tests.js"></script>
<title>Test Runner</title>
</head>
<body>
    <div id="mocha"></div>
</body>

</html>

В файл tests.js добавим следующие тесты функции hello(), использующие библиотеку Sinon

    describe('Say Hello Tests with Expect', function () {
        it('should call callback with correct greeting', function () {
            var callback = sinon.spy();
            hello('foo', callback);
            expect(callback).to.have.been.calledWith('Hello foo');
        });
    });
 
    describe('Say Hello Tests with Should', function () {
        it('should call callback with correct greeting', function () {
            var callback = sinon.spy();
            hello('foo', callback);
            callback.should.have.been.calledWith('Hello foo');
        });
    });

Итоговый вид файла tests.js

function runTests() {

    mocha.setup('bdd');

    var assert = chai.assert,
          expect = chai.expect,
          should = chai.should(); // Note that should has to be executed

    describe('Say OK Tests', function() {
                             
      describe('Function sayOK()', function() {
                                     
        it('should work with assert', function() {
            assert.equal(sayOK(), 'OK');
        });

        it('should work with expect', function() {
            expect(sayOK()).to.equal('OK');
        })

        it('should work with should', function() {
            sayOK().should.equal('OK');
        });

      });
   
    });

    describe('Say Hello Tests with Expect', function () {
        it('should call callback with correct greeting', function () {
            var callback = sinon.spy();
            hello('foo', callback);
            expect(callback).to.have.been.calledWith('Hello foo');
        });
    });
 
    describe('Say Hello Tests with Should', function () {
        it('should call callback with correct greeting', function () {
            var callback = sinon.spy();
            hello('foo', callback);
            callback.should.have.been.calledWith('Hello foo');
        });
    });
 
    var runner = mocha.run();

}

$(document).ready(function(){
    runTests();
});

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

Структуру расположения папок и файлов

/css/mocha.css
/js/mocha.js
/js/chai.js
/js/sinon.js
/js/sinon-chai.js
/js/jquery.js
/js/index.js
/js/tests.js
/index.html
/testrunner.html

Файл index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    alert(sayOK());
    hello('Boris', alert);
});
</script>
<title>My Page</title>
</head>
<body>
<h1>My Page</h1>
</body>
</html>

Файл testrunner.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="css/mocha.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/mocha.js"></script>
<script type="text/javascript" src="js/chai.js"></script>
<script type="text/javascript" src="js/sinon-chai.js"></script>
<script type="text/javascript" src="js/sinon.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/tests.js"></script>
<title>Test Runner</title>
</head>
<body>
    <div id="mocha"></div>
</body>
</html>

Файл index.js

function sayOK(){
    return 'OK';
}

function hello(name, callback) {
    callback('Hello ' + name);
}

Файл tests.js

function runTests() {

    mocha.setup('bdd');

    var assert = chai.assert,
          expect = chai.expect,
          should = chai.should(); // Note that should has to be executed

    describe('Say OK Tests', function() {
                             
      describe('Function sayOK()', function() {
                                     
        it('should work with assert', function() {
            assert.equal(sayOK(), 'OK');
        });

        it('should work with expect', function() {
            expect(sayOK()).to.equal('OK');
        })

        it('should work with should', function() {
            sayOK().should.equal('OK');
        });

      });
   
    });

    describe('Say Hello Tests with Expect', function () {
        it('should call callback with correct greeting', function () {
            var callback = sinon.spy();
            hello('foo', callback);
            expect(callback).to.have.been.calledWith('Hello foo');
        });
    });
 
    describe('Say Hello Tests with Should', function () {
        it('should call callback with correct greeting', function () {
            var callback = sinon.spy();
            hello('foo', callback);
            callback.should.have.been.calledWith('Hello foo');
        });
    });
 
    var runner = mocha.run();

}

$(document).ready(function(){
    runTests();
});

Комментариев нет:

Отправить комментарий