Вышел test.it v1.1.0 — что дальше?

    Добрый день хабр.
    Вчера вышла версия 1.1.0 test.it — фреймворка для тестирования js кода.
    Он, наконец, обзавёлся функционалом, отсутствие которого делало его неполноценным:
    • Асинхронные тесты/группы
    • Запуск отдельных тестов/групп
    А так же прочими мелочами.

    картинка для привлечения внимания
    Кто не любит много слов — Сайт на котором можно увидеть код в действии, GitHub, Wiki

    Ченджлог


    • Изменения под капотом
      • серьёзный рефакторинг — изменение технологии цепочности и наследования
      • возможность запуска в безоконной среде (в которой нету объекта window, например node.js)
        Это подготовительная операция для порта под node.js, angular.js и им подобным

    • Изменения в интерфейсе
      .done() получил дополнительный функционал как метода завершающего цепь.
      Появились новые методы и атрибуты:
      • звено цепи .addTrace(level)
      • подготовитель цепи .time
      • подготовитель цепи .exclude

    • Исправлены:
      • огромное количество грамматических ошибок (спасибо tenphi и asmgf)
      • баг с расчётом времени у root при многократном вызове test.done()

    • Обновлены Вики, сайт и пример


    Новые возможности


    Звено цепи .addtrace(level) — добавляет к тесту/группе trace — список строк, приведших к его исполнению.
    level — задаёт количество выводимых строк (или глубину областей видимости, на которую будет подниматься trace).
    Метод был добавлен по просьбе пользователя vk Denya Tatarinov, с пояснением, что это полезно для наблюдения за большим количеством асинхронных вызовов (тестов).
    У меня есть хорошая привычка, логгировать каждый ajax запрос. точнее ответ от сервера. и когда случается какая то херь, я бы хотел знать в какой строчке это случилось) не писать жеж что вот чувак, это 45 строчка в каждом вызове. + помогает ориентироваться по коду

    Для данной задачи хватает вывода только одной (текущей) строки, но мало ли кому понадобиться отследить какой-нибудь запутанный код.
    Пример и скриншот
    (function firstFunction() {
        (function secondFunction() {
            (function lastFunction() {
                test.it(1).addTrace(0); // добавит только текущую строку
                test.it(1).addTrace();  // добавит полный трейс
            })();
        })();
    })();
    addTrace


    Подготовитель цепи .time — добавляет к выводу теста время, затраченное на его исполнение (или исполнение функции результат которой был передан тесту)
    Обратите внимание, что это не метод, а именно аттрибут. Не ставьте после него скобки!
    Пример и скриншот
    test.time.it(someThing());
    time


    Подготовитель цепи .exclude — предотвращает попадание теста или группы в стек текущего уровня. Это тоже атрибут не ставьте после него скобки!
    Может быть полезен для асинхронных тестов.
    Пример
    alert(test.exclude.it(someThing).result()); //выдаст alert с результатом теста
    test.exclude.group('some group',function(){ ... }).done(); //выведет группу в консоль


    Вывод отдельных тестов и групп

    Наконец все эти .group обрели смысл!
    .done() — в зависимости от того, как и где был вызван выводит:
    • Как метод объекта test вне групп — выведет результат как и раньше.
      Пример
      test.done();
      test.done
    • Как метод объекта test внутри группы — выведет эту группу включая все тесты и подгруппы, которые успели туда попасть.
      Пример
      test.group('group of tests',function(){
          test.it(false);
          test.done();
          test.it(true);
      });
      test.done in group scope
    • Как оканчивающее звено в цепи групп — выведет последнюю группу в цепи
      Пример
      test.group('group of tests',function(){
          test.it(true);
          test.it(false);
      }).done();
      // или
      test.group('group of tests').done();
      
      test.group.done
    • Как оканчивающее звено в цепи теста — выведет этот тест
      Пример
      test.it(true).comment('выведет только этот тест').done();
      test.it.done


    Асинхронные тесты


    Благодаря новому поведению .done() (и немного .exclude) теперь доступны асинхронные тесты:
    var a = false; // переменная, которую мы изменим через 2 секунды
    setTimeout(function () {a=true}, 2000) // асинхронное (через время) изменение переменной
    setTimeout(function () {
         test.group('async tests',function(){
            test.it(a).comment('переменная ещё не изменилась');
         }).comment('async group').done(); // вывод результата
    }, 1000);
    setTimeout(function () {
        test.exclude.it(a).comment('переменная уже изменилась').done(); // вывод результата, без добавления его в root
    }, 3000);
    Через ~3 секунды в консоли будет:
    async

    TODO


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

    Ссылки


    Сайт на котором можно увидеть код в действии, GitHub, Wiki

    P.S.


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

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

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Какими из тестов вы пользуетесь/будете пользоваться

    Поделиться публикацией

    Комментарии 12

      +1
      А моки есть?
        0
        А разве для них необходим какой-то особый функционал фреймворка? Всегда думал, что для создания моков достаточно стандартных средств языка.
        Если опишете подробнее, что именно требуется, то почему бы и нет — добавлю!
          +1
          Суть в том чтобы просто замокать объект, настроить мок, иметь возможность проверить его вызовы и после теста очистить мок.

          Например, было бы приятно делать что-то наподобии:

          var myMock = test.mock('namespace.Class.prototype.method').returnValue('test');
          
          // логика теста, которя использует namespace.Class.prototype.method
          
          myMock.hasCalls(['this', 'arg1', 'arg2], ['this', 'arg3', 'arg4']);
          


          Отдельного внимае можно уделить мокам window.location, window.history и тд.
        0
        можно вопрос? а чем от Qunit отличается, кроме того, что выводится в консоль?
          0
          1. В Qunit есть киллерфича — смена последовательности запуска тестов, в зависимости от предыдущего результата. Из-за чего нажимая на F5 есть реальный шанс получать разное количество пройденных/проваленных тестов. В test.it — один и тот же тест одного и того же кода, всегда выдаёт один и тот же результат.
          2. В Qunit есть только 2 уровня вложенности — тест и модуль. В test.it — неограниченный уровень вложенности групп (группы в test.it чем-то идейно близки тестам в Qunit).
          3. Qunit не выводит (не всякий раз выводит / криво выводит) тестируемые данные, что мешает отладке, заставляя писать рядом с тестами console.log(). В test.it во всех тестах, в не зависимости от результата выводится массив с переданными аргументами.
          4. Для тестирования асинхронного функционала Qunit предлагает ставить на паузу своё ядро методом stop() и возобновлять его спустя какое-то время методом start(). В test.it асинхронные тесты и группы никак не мешают остальным и могут отрабатывать в принципе без попадания в общий результат.
          5. Всё-таки! В Qunit весь результат выводится на страницу, что, по моему субъективному мнению. является огромным недостатком. В test.it весь результат выводится в консоль из-за её огромных возможностей для отладки. Я мало работал с асинхронными тестами в Qunit. Так что если в этом пункте ошибаюсь — смело меня поправляйте.
          6. Рюшечки! В Qunit нету вывода времени затраченного на ok или equal, нету возможности добавить в результат trace, нету callback'ов зависящих от результата, нету возможности использовать результат теста дальше в коде.

          Имхо рюшечки самый малозначимый пункт. Главные отличия перечислены в первых пяти.
          0
          вот и консоль для Qunit github.com/Horsed/qunit-logging
            0
            после этого
            equal({a:1,b:2},{a:1,c:2},'obj equal');
            

            [---] initial test : obj equal qunit-logging.js:45
            (actual = Object, expected = Object)
            

            Считаю этот репозиторий абсолютно бессмысленным.
            В то время, когда в консоли есть огромный функционал для просмотра сложных объектов, выводить их туда через .toString() — кощунство.
              0
              Но смотреть в консоли полотнища репортов, тоже не комильфо… да и поиск не особо, у Qunit есть возможность раскидать по модулям, а потом выбрать в selectbox интересующий нас модуль, значительно лучше чем пролистывать полотнища в консоли.
                0
                В test.it можно выводить отдельно только одну группу и даже только один тест, не важно как глубоко они вложены.
                Более того можно вывести часть одной группы, 1 тест из другой, 1 тест который находиться вне групп и ещё одну целую группу. (можно — не значит нужно) Это не будет полотнищем.

                И, кстати все группы со статусом 'pass' по-умолчанию выводятся свёрнутыми, что тоже значительно сокращает полотнище, до, буквально, десятка строк, на сотни и даже десятки сотен тестов.

                Напоминаю, в test.it в отличае от Qunit настоящая многоуровневая вложенность. Если про это забывать, то и действительно можно получить огромные полотнища в стиле Qunit.
                0
                Поясню.
                Я считаю вывод в консоль преимуществом не потому, что выводить сложные данные на страницу — плохо (хотя и это в какой-то степени тоже), а потому что выводить их в консоль — хорошо.

                Консоль в отличае от HTML обладает следующими возможностями:
                • встроенной поддержкой древовидной структуры данных
                • умением перемещаться вверх по прототипам
                • различием в отображении различных типов данных
                • переходом по клику на определённую строчку в коде
                • переходом по клику на определённую ветвь в DOM дереве
                • группировкой вывода
                И это далеко не полный список.

                Конечно это всё можно реализовать в HTML.
                Но, во-первых — ни Qunit ни даже Jasmine не стали заморачиваться над этой довольно сложной задачай. Во вторых — зачем это реализовывать, если оно уже всё давно реализовано в консоли?
                  0
                  А как быть с браузерами, которые не поддерживают новомодные фичи консоли?
                    0
                    Operа больше не существует, для IE есть плагин о котором была статья на хабре (кстати надо бы его хорошенько протестировать). Если вы про всякие Konqueror и иже с ним. то мне остаётся только посочувствовать и предложить использовать другой фреймворк.

                    Если что, я планирую в ближайшем будущем заняться портом под node.js. И практически всё, что он из себя будет представлять — переписанный модуль вывода в консоль. Он позволит комфортно (более менее) себя чувствовать даже в браузерах, которые только console.log и умеют

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое