Поиск:

Ответ в темуСоздание новой темы Создание опроса
> nodeunit, unit testing в JS, дискуссия как бы 
:(
    Опции темы
bilbobagginz
Дата 5.4.2013, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



привет.
Вопрос немного философский конечно, но у кого есть мысли по сабжу ... буду рад услышать.
Тема такая - тестирование.
Пишется код (client side) на JS. пишется в форме модуля. 
Ессно, это не реально код приложения, а пример поясняющий проблему.
Если бы не было тестов, было бы грубо говоря так, mymodule.js:
Код

var mymodule = (function () {
    var that = {};
    var private_method = function (s) {
        if ( "undefined" === typeof s || "" === s ) {
           return undefined;
        }
        return "Hello, " + s + "!";
    };
    that.public_method = function (s) {
        return private_method(s);
    };
    return that;
})();

запуск этого кода - после добавки в файл HTML:
Код

// где-то в блоке script
mymodule.public_method("kuku");

Надо "покрыть" тестами (не слишком, но покрыть).
проблема в том, что я не нашел "архитектурно чистый" подход к тестированию приватных методов модуля.
с помощью nodeunit, я могу тестировать "public_method", создав каталог "test", и в нем файлик test_mymodule.js:
Код

var mymodule = require ('../mymodule.js');
exports.mymodule = {};
exports.mymodule.test_public = function (test) {
    test.equal(mymodule.public_method('kuku'), 'Hello, kuku!');
    test.done();
};

запуск теста просто:
Код

cd js # каталог, в котором скрипт и каталог test
nodeunit test/

Проблема в том, что доступа до mymodule.private_method() нету.
В данном примере, ессно, публичная метода - просто обертка и ни хрена не делает.
Но в реальном коде приватные методы - как раз то, что хотелось бы протестить.
И внешний API тоже, есссно. В общем идеи были разные.
Две наиболее популярные были:
1. "загрязнить" боевой модуль дополнительным тестовым кодом
Он потом отошлется клиенту непонятно к чему), приведея его к форме:
Код

var UNIT_TEST = ('UNIT_TEST' === process.env.NODE_ENV);
var mymodule = (function () {
    var that = {};
    var private_method = function (s) {
        if ( "undefined" === typeof s || "" === s ) {
           return undefined;
        }
        return "Hello, " + s + "!";
    };
    if (UNIT_TEST) { that.export.private_method = private_method; }
    that.public_method = function (s) {
        return private_method(s);
    };
    return that;
})();
if (UNIT_TEST) {
  module.exports.mymodule = mymodule;
} else {
  module.exports = mymodule;
}

в тесте определить переменную:
Код

process.env.NODE_ENV = 'UNIT_TEST';
var mymodule = require ('../mymodule.js');
exports.mymodule = {};
exports.mymodule.test_public = function (test) {
    test.equal(mymodule.mymodule.public_method('kuku'), 'Hello, kuku!');
    test.done();
};
exports.mymodule.test_public = function (test) {
    test.equal(mymodule.private_method('kuku'), 'Hello, kuku!');
    test.done();
};


2. разделить mymodule на внутренний под-модуль и тестить оный извне
т.е.:

Код

var UNIT_TEST = ('UNIT_TEST' === process.env.NODE_ENV);
var mymodule_util = (function () {
    var that = {};
    that.private_method = function (s) {
        if ( "undefined" === typeof s || "" === s ) {
           return undefined;
        }
        return "Hello, " + s + "!";
    };
    return that;
})();

var mymodule = (function () {
    var that = {};
    that.public_method = function (s) {
        return mymodule_util.private_method(s);
    };
    return that;
})();

if (UNIT_TEST) {
    module.exports.mymodule = mymodule;
    module.exports.mymodule_util = mymodule_util;
}


И соотв. в тесте будет 2 региона тестирования:
Код

process.env.NODE_ENV = 'UNIT_TEST';
var mymodule = require ('../mymodule.js');
exports.mymodule = {};
exports.mymodule.test_public = function (test) {
    test.equal(mymodule.mymodule.public_method('kuku'), 'Hello, kuku!');
    test.done();
};
exports.mymodule.test_public = function (test) {
    test.equal(mymodule.mymodule_util.private_method('kuku'), 'Hello, kuku!');
    test.done();
};


в C++ можно было сделать какой-то изврат с #ifdef, и этот изврат не попал бы в релизный бинарник.
Как же быть в JS?


Это сообщение отредактировал(а) bilbobagginz - 5.4.2013, 15:05


--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
CruorVult
Дата 5.4.2013, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 868
Регистрация: 24.9.2008
Где: г.Киев, Украина

Репутация: нет
Всего: 28



Цитата(bilbobagginz @  5.4.2013,  15:03 Найти цитируемый пост)
проблема в том, что я не нашел "архитектурно чистый" подход к тестированию приватных методов модуля.


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

К тому же скоро готовится к релизу ECMAScript 6, где есть поддержка модулей. Там-то приватные методы вообще не получится протестировать. 

PM MAIL Skype   Вверх
bilbobagginz
Дата 6.4.2013, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



CruorVult, спасибо.
т.е. второй вариант (если много приватных метод вынести их в "утиль"ный модуль, использовать в главном, и тестить утильный модуль отдельно)

насчет "скоро".... 
гугл тут свой дротик (в смысле Dart) замутили... и сидят они как стандартные члены борда ECMA.
у тебя есть какая-то секретная инфа насчет когда это произойдет ?



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
CruorVult
Дата 8.4.2013, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 868
Регистрация: 24.9.2008
Где: г.Киев, Украина

Репутация: нет
Всего: 28



Цитата(bilbobagginz @  6.4.2013,  10:56 Найти цитируемый пост)
т.е. второй вариант (если много приватных метод вынести их в "утиль"ный модуль, использовать в главном, и тестить утильный модуль отдельно)


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

Изначально ты все правильно сделал.

Код

test.equal(mymodule.public_method('kuku'), 'Hello, kuku!');
 

Осталось протестировать, когда метод ничего не принимает

Код

test.equal(mymodule.public_method(), undefined);
 

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

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

 

Цитата(bilbobagginz @  6.4.2013,  10:56 Найти цитируемый пост)
у тебя есть какая-то секретная инфа насчет когда это произойдет ?


Точной информации нету, но предположительно к концу года.

PM MAIL Skype   Вверх
bilbobagginz
Дата 9.4.2013, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



Цитата(CruorVult @  8.4.2013,  10:09 Найти цитируемый пост)
Точной информации нету, но предположительно к концу года.

т.е. к концу года браузеры волшебным образом запоют на новом жаргоне ? smile (не верю)

Добавлено через 2 минуты и 34 секунды
Цитата(CruorVult @  8.4.2013,  10:09 Найти цитируемый пост)
Лучше всего, при разработке с написанием тестов, использовать подход TDD. Эта техника по началу кажется непонятной и запутанной, но позволяет очень глубоко обдумать архитектуру приложения без строчки рабочего кода.

знаком, но по физиологическим причинам страдаю излишним покрытием ненужного тестами, что нередко приводит к непокрытию нужноого smile
не знаю как лечиться smile



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
CruorVult
Дата 10.4.2013, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 868
Регистрация: 24.9.2008
Где: г.Киев, Украина

Репутация: нет
Всего: 28



Цитата(bilbobagginz @  9.4.2013,  21:12 Найти цитируемый пост)
т.е. к концу года браузеры волшебным образом запоют на новом жаргоне ?  (не верю)


На фоне того, что Google переводит Chrome на новый движок рендеринга (Ripple) а также того, что Mozilla и Samsung разрабатывают новый движок для браузеров(под Android), переход на ECMAScript 6 меня ни капельки не удивляет  smile 
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Node.js | Следующая тема »


 




[ Время генерации скрипта: 0.1241 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.