Автоматизированное модульное тестирование на JavaScript



Я пытаюсь включить некоторые модульные тесты JavaScript в мой автоматизированный процесс сборки. В настоящее время JSUnit хорошо работает с JUnit, но, похоже, он является abandonware и не имеет хорошей поддержки AJAX, отладки и таймаутов.



кому-нибудь повезло автоматизировать (с помощью ANT) библиотеку модульного тестирования, такую как Yui test, jQuery QUnit или jQUnit (http://code.google.com/p/jqunit/)?



Примечание: я использую специально построенную библиотеку AJAX, поэтому проблема с Додзе Doh является то, что она требует от вас, чтобы использовать свои собственные технологии Ajax вызовы функций и обработчиков событий для работы с любым модульное тестирование "Аякс".

628   14  

14 ответов:

есть много Javascript unit test framework там (jsUnit, scriptaculous,...) но jsUnit-единственный, который я знаю, который может использоваться с автоматической сборкой.

Если вы делаете "истинный" модульный тест, вам не нужна поддержка AJAX. Например, если вы используете структуру RPC ajax, такую как DWR, вы можете легко написать макет функции:

   function mockFunction(someArg, callback) {
      var result = ...; // some treatments   
      setTimeout(
function() { callback(result); }, 300 // some fake latency
); }

и да, JsUnit действительно обрабатывает таймауты:моделирование времени в тестах jsUnit

Я как раз собираюсь начать делать Javascript TDD в новом проекте, над которым я работаю. Мой текущий план заключается в использовании qunit для выполнения модульного тестирования. Во время разработки тесты можно запустить, просто обновив тестовую страницу в браузере.

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

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

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


тестирование инструменты:

Я большой поклонник JS-test-driver

Он хорошо работает в среде CI и способен захватывать фактические браузеры для кросс-браузерного тестирования.

недавно я прочитал статью Бруно, используя JsUnit и создав структуру JsMock поверх этого... весьма интересный. Я думаю использовать его работу, чтобы начать модульное тестирование моего кода Javascript.

макет Javascript или как модульный тест Javascript вне среды браузера

Я получил Хадсон CI для запуска JasmineBDD (безголовый), по крайней мере, для чистого модульного тестирования javascript.

(Гудзон Java с помощью консоли, запущенной Envjs, работает JasmineBDD.)

Я не получил его, чтобы играть с большой библиотекой, хотя, как прототип.

посмотреть в YUITest

Я согласен, что jsunit как бы умирает на корню. Мы только что закончили заменять его тестом YUI.

Как и в Примере с использованием qUnit, мы запускаем тесты с использованием Селена. Мы запускаем этот тест независимо от других тестов selenium просто потому, что он не имеет зависимостей, которые имеют обычные тесты регрессии пользовательского интерфейса (например, развертывание приложения на сервере).

для начала, у нас есть базовый файл javascript, который входит во все из наших тестовых html файлов. Это обрабатывает настройку экземпляра YUI, тестового бегуна, YUI.Тест.Набор объектов, а также Тест.Случай. Он имеет методы, к которым можно получить доступ через Selenium, чтобы запустить набор тестов, проверить, работает ли тестовый бегун (результаты не доступны до тех пор, пока это не будет сделано), и получить результаты теста (мы выбрали формат JSON)

var yui_instance; //the YUI instance
var runner;  //The YAHOO.Test.Runner
var Assert; //an instance of YAHOO.Test.Assert to save coding
var testSuite; //The YAHOO.Test.Suite that will get run.

/**
 * Sets the required value for the name property on the given template, creates
 * and returns a new YUI Test.Case object.
 * 
 * @param template the template object containing all of the tests
 */
function setupTestCase(template) {
    template.name = "jsTestCase";
    var test_case = new yui_instance.Test.Case(template);
    return test_case;
}

/**
 * Sets up the test suite with a single test case using the given 
 * template.
 * 
 * @param template the template object containing all of the tests
 */
function setupTestSuite(template) {
    var test_case = setupTestCase(template);
    testSuite = new yui_instance.Test.Suite("Bond JS Test Suite");
    testSuite.add(test_case);
}

/**
 * Runs the YAHOO.Test.Suite
 */
function runTestSuite() {
    runner = yui_instance.Test.Runner;
    Assert = yui_instance.Assert;

    runner.clear();
    runner.add(testSuite);
    runner.run();
}

/**
 * Used to see if the YAHOO.Test.Runner is still running.  The
 * test results are not available until it is done running.
 */
function isRunning() {
    return runner.isRunning();
}

/**
 * Gets the results from the YAHOO.Test.Runner
 */
function getTestResults() {
    return runner.getResults(yui_instance.Test.Format.JSON);
}

что касается селеновой стороны вещей, мы использовали параметризованный тест. Мы запускаем наши тесты как в IE, так и в FireFox метод data, разбирающий результаты теста в список массивов объектов с каждым массивом, содержащим имя браузера, имя тестового файла, имя теста, результат (pass, fail или ignore) и сообщение.

фактический тест просто утверждает результат теста. Если он не равен "pass", то он не проходит тест с сообщением, возвращенным из результата теста YUI.

    @Parameters
public static List<Object[]> data() throws Exception {
    yui_test_codebase = "file:///c://myapppath/yui/tests";

    List<Object[]> testResults = new ArrayList<Object[]>();

    pageNames = new ArrayList<String>();
    pageNames.add("yuiTest1.html");
    pageNames.add("yuiTest2.html");

    testResults.addAll(runJSTestsInBrowser(IE_NOPROXY));
    testResults.addAll(runJSTestsInBrowser(FIREFOX));
    return testResults;
}

/**
 * Creates a selenium instance for the given browser, and runs each
 * YUI Test page.
 * 
 * @param aBrowser
 * @return
 */
private static List<Object[]> runJSTestsInBrowser(Browser aBrowser) {
    String yui_test_codebase = "file:///c://myapppath/yui/tests/";
    String browser_bot = "this.browserbot.getCurrentWindow()"
    List<Object[]> testResults = new ArrayList<Object[]>();
    selenium = new DefaultSelenium(APPLICATION_SERVER, REMOTE_CONTROL_PORT, aBrowser.getCommand(), yui_test_codebase);
    try {
        selenium.start();

        /*
         * Run the test here
         */
        for (String page_name : pageNames) {
            selenium.open(yui_test_codebase + page_name);
            //Wait for the YAHOO instance to be available
            selenium.waitForCondition(browser_bot + ".yui_instance != undefined", "10000");
            selenium.getEval("dom=runYUITestSuite(" + browser_bot + ")");

            //Output from the tests is not available until 
            //the YAHOO.Test.Runner is done running the suite
            selenium.waitForCondition("!" + browser_bot + ".isRunning()", "10000");
            String output = selenium.getEval("dom=getYUITestResults(" + browser_bot + ")");

            JSONObject results = JSONObject.fromObject(output);
            JSONObject test_case = results.getJSONObject("jsTestCase");
            JSONArray testCasePropertyNames = test_case.names();
            Iterator itr = testCasePropertyNames.iterator();

            /*
             * From the output, build an array with the following:
             *  Test file
             *  Test name
             *  status (result)
             *  message
             */
            while(itr.hasNext()) {
                String name = (String)itr.next();
                if(name.startsWith("test")) {
                    JSONObject testResult = test_case.getJSONObject(name);
                    String test_name = testResult.getString("name");
                    String test_result = testResult.getString("result");
                    String test_message = testResult.getString("message");
                    Object[] testResultObject = {aBrowser.getCommand(), page_name, test_name, test_result, test_message};
                    testResults.add(testResultObject);
                }
            }

        }
    } finally {
        //if an exception is thrown, this will guarantee that the selenium instance
        //is shut down properly
        selenium.stop();
        selenium = null;
    }
    return testResults;
}
/**
 * Inspects each test result and fails if the testResult was not "pass"
 */
@Test
public void inspectTestResults() {
    if(!this.testResult.equalsIgnoreCase("pass")) {
        fail(String.format(MESSAGE_FORMAT, this.browser, this.pageName, this.testName, this.message));
    }
}

Я надеюсь, что это полезно.

появился новый проект, который позволяет запускать qunit тесты в среде Java (например, ant), чтобы вы могли полностью интегрировать свой набор тестов на стороне клиента с другими модульными тестами.

http://qunit-test-runner.googlecode.com

Я использовал его для модульного тестирования плагинов jQuery, objx код, пользовательский Oo JavaScript и он работает для всего без изменений.

проект, над которым я работаю, использует JS-Test-Driver хостинг Жасмин на Chrome 10 с Jasmine-Jstd-Adapter в том числе с использованием Покрытия Кода тесты, включенные в JS-Test-Driver. Хотя есть некоторые проблемы каждый раз, когда мы меняем или обновляем браузеры на CI environment тесты jasmine работают довольно гладко с незначительными проблемами с ансинхронными тестами, но, насколько мне известно, они могут работать вокруг использования часов жасмина, но у меня еще не было возможности их исправить.

я опубликовал маленькая библиотека для проверки зависящих от браузера тестов JavaScript без использования браузера. Это узел.модуль на JS, который использует зомби.js для загрузки тестовой страницы и проверки результатов. Я уже писал об этом мой блог. Вот как выглядит автоматизация:

var browsertest = require('../browsertest.js').browsertest;

describe('browser tests', function () {

it('should properly report the result of a mocha test page', function (done) {
    browsertest({
        url: "file:///home/liam/work/browser-js-testing/tests.html",
        callback: function() { 
            done();
        }
    });
});

});

Я посмотрел на дату вашего вопроса, и тогда было несколько хороших JS-тестов lib/framework. Сегодня вы можете найти гораздо больше и в другом фокусе, как TDD, BDD, Assetion и с/без поддержки бегунов.

есть много игроков в этой игре, как Мокко, чай, помощью QUnit, Жасмин и др... Вы можете найти дополнительную информацию в этой блог о тестировании JS/Mobile/web...

еще одна платформа тестирования JS, которая может быть запущена с Ant, - это CrossCheck. Есть пример выполнения CrossCheck через Ant в файле сборки для проекта.

CrossCheck пытается, с ограниченным успехом, эмулировать браузер, включая макетные реализации стиля XMLHttpRequest и timeout/interval.

в настоящее время он не обрабатывает загрузку javascript с веб-страницы. Вы должны указать файлы javascript, которые вы хотите загрузить и тест. Если вы держите все свои JS отдельно от вашего HTML, это может сработать для вас.

Я написал Ant-задачу, которая использует Phantom JS, безголовый браузер webkit, для запуска тестовых файлов QUnit html в процессе сборки Ant. Он также может не выполнить сборку, если какие-либо тесты не выполняются.

https://github.com/philmander/ant-jstestrunner

Это хорошая оценка нескольких инструментов тестирования.

инструменты модульного тестирования JavaScript для TDD

лично я предпочитаю https://code.google.com/p/js-test-driver/

Comments

    Ничего не найдено.