Автоматическое тестирование модулей с помощью JavaScript
Я пытаюсь включить тестирование модуля JavaScript в мой процесс автоматической сборки. В настоящее время JSUnit хорошо работает с JUnit, но, похоже, он отказывается от программного обеспечения и не имеет хорошей поддержки AJAX, отладки и тайм-аутов.
Кто-нибудь удалил автоматизацию (с помощью ANT) модульной библиотеки тестирования, такой как тест YUI, JQuery QUnit или jQUnit (http://code.google.com/p/jqunit/)?
Примечание. Я использую специально созданную библиотеку AJAX, поэтому проблема с Dojo DOH заключается в том, что она требует, чтобы вы использовали свои собственные вызовы функций AJAX и обработчики событий для работы с любым тестированием модулей AJAX.
Ответы
Ответ 1
Существует много фреймворков javascript unit test (jsUnit, scriptaculous,...), но jsUnit - единственное, что я знаю, которое можно использовать с автоматической сборкой.
Если вы выполняете "true" unit test, вам не нужна поддержка AJAX. Например, если вы используете инфраструктуру ajax RPC, такую как DWR, вы можете легко написать функцию mock:
function mockFunction(someArg, callback) {
var result = ...; // some treatments
setTimeout(
function() { callback(result); },
300 // some fake latency
);
}
И да, JsUnit действительно обрабатывает таймауты: Имитация времени в тестах jsUnit
Ответ 2
Я собираюсь начать Javascript TDD над новым проектом, над которым я работаю. Мой текущий план заключается в использовании qunit для проведения модульного тестирования. При разработке тестов можно запустить, просто обновив тестовую страницу в браузере.
Для непрерывного интегрирования (и обеспечения выполнения тестов во всех браузерах) я буду использовать Selenium, чтобы автоматически загружать тестовый жгут в каждом браузера и прочитайте результат. Эти тесты будут выполняться при каждой проверке до источника.
Я также собираюсь использовать JSCoverage, чтобы получить анализ покрытия кода. Это также будет автоматизировано с помощью Selenium.
В настоящее время я занимаюсь этим. Я уточню этот ответ с более точными подробностями, как только у меня получится настройка.
Инструменты тестирования:
Ответ 3
Я большой поклонник js-test-driver
Он хорошо работает в среде CI и способен захватывать фактические браузеры для кросс-браузерного тестирования.
Ответ 4
Недавно я прочитал статью Бруно, используя JsUnit и создав структуру JsMock поверх этого... очень интересно. Я думаю использовать его работу, чтобы начать модульное тестирование моего кода Javascript.
Mock Javascript или unit test Javascript вне среды браузера
Ответ 5
Я просто получил Hudson CI для запуска JasmineBDD (без головы), по крайней мере, для чистого модульного тестирования javascript.
(Хадсон запускает Java через оболочку, запускает Envjs, запускает JasmineBDD.)
У меня пока не получилось хорошо играть с большой библиотекой, хотя, как прототип.
Ответ 6
Посмотрите YUITest
Ответ 7
Я согласен, что jsunit скорее умирает на лозе. Мы только что закончили замену с помощью теста YUI.
Как и в примере с использованием qUnit, мы запускаем тесты с использованием Selenium. Мы проводим этот тест независимо от наших других тестов на селен просто потому, что у него нет зависимостей, которые испытывают обычные регрессионные тесты UI (например, развертывание приложения на сервере).
Для начала у нас есть базовый файл javascript, который входит во все наши тестовые html файлы. Это позволяет настроить экземпляр YUI, тестовый бегун, объект YUI.Test.Suite, а также Test.Case. У него есть методы, к которым можно получить доступ через 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 в методе данных, анализируя результаты теста в список массивов объектов с каждым массивом, содержащим имя браузера, имя тестового файла, имя теста, результат (пропуск, отказ или игнорирование) и сообщение.
Фактический тест просто подтверждает результат теста. Если он не равен "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));
}
}
Я надеюсь, что это будет полезно.
Ответ 8
Там есть новый проект, который позволяет запускать qunit тесты в среде Java (например, ant), чтобы вы могли полностью интегрировать свои клиентский пакет тестов с другими модульными тестами.
http://qunit-test-runner.googlecode.com
Я использовал его для unit test плагинов jQuery, objx код, пользовательский OO JavaScript и работает для всего без изменений.
Ответ 9
В проекте, над которым я работаю, используется Js-Test-Driver хостинг Jasmine в Chrome 10 с Jasmine-JSTD-Adapter, включая использование Code Coverage, включенных в JS-Test-Driver. Несмотря на некоторые проблемы при каждом изменении или обновлении браузеров в среде CI, тесты жасмина работают довольно гладко с незначительными проблемами с антисинхронными тестами, но насколько я знаю, они могут работать с использованием Jasmine Clock, но у меня еще не было возможности их исправлять.
Ответ 10
Я опубликовал небольшую библиотеку для проверки зависимых от браузера JavaScript-тестов без использования браузера. Это модуль node.js, который использует zombie.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();
}
});
});
});
Ответ 11
Я посмотрел вашу дату вопроса и обратно, тогда было несколько хороших JS-тестов lib/framework.
Сегодня вы можете найти гораздо больше и в разных фокусах, таких как TDD, BDD, Assetion и с поддержкой/без поддержки бегунов.
В этой игре много игроков, таких как Mocha, Chai, QUnit, Jasmine и т.д.
Вы можете найти дополнительную информацию в этом блоге о тестировании JS/Mobile/web...
Ответ 12
Другая структура тестирования JS, которая может быть запущена с помощью Ant, CrossCheck. Пример использования CrossCheck с помощью Ant в файле сборки для проекта.
CrossCheck пытается с ограниченным успехом эмулировать браузер, включая макетные реализации XMLHttpRequest и тайм-аута/интервала.
В настоящее время он не обрабатывает загрузку javascript с веб-страницы. Вы должны указать файлы javascript, которые хотите загрузить и протестировать. Если вы сохраните все свои JS, отделенные от вашего HTML, это может сработать для вас.
Ответ 13
Я написал задачу Ant, которая использует Phantom JS, браузер безглавых веб-китов, для запуска тестовых файлов QUnit html внутри процесс сборки Ant. Это может также привести к сбою сборки, если какие-либо тесты не удались.
https://github.com/philmander/ant-jstestrunner
Ответ 14
Это хорошая оценка нескольких инструментов тестирования.
JavaScript unit test инструменты для TDD
Я лично предпочитаю
https://code.google.com/p/js-test-driver/