Автоматизированное поблочное тестирование с JavaScript

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Обратный вызов передается возвращенными данными, которые будут объектом или массивом JavaScript, как определено структурой JSON, и анализируются с использованием метода $.parseJSON().

60
задан Chris MacDonald 19 September 2008 в 13:46
поделиться

7 ответов

Существует много платформ модульного теста JavaScript там (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

20
ответ дан Matthew Murdoch 7 November 2019 в 14:20
поделиться

Изучите YUITest

2
ответ дан Hank Gay 7 November 2019 в 14:20
поделиться

Другая среда тестирования JS, которая может быть выполнена с Муравьем, CrossCheck. Существует пример выполнения CrossCheck через Муравья в файле типа "build" для проекта.

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

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

0
ответ дан Jason Wadsworth 7 November 2019 в 14:20
поделиться

Я недавно прочитал статью использования Bruno JsUnit и создания платформы JsMock, к тому же... очень интересной. Я думаю об использовании его работы для запуска поблочного тестирования мой код JavaScript.

Насмешка JavaScript или Как к модульному тесту JavaScript вне среды Браузера

4
ответ дан Elijah Manor 7 November 2019 в 14:20
поделиться

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

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

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

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

<час>

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

24
ответ дан Karl 7 November 2019 в 14:20
поделиться

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

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

13
ответ дан 24 November 2019 в 17:52
поделиться

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

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

Для начала у нас есть базовый файл 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 в методе данных, анализируя результаты теста в список массивов объектов, каждый из которых содержит имя браузера, имя тестового файла, имя теста, результат (пройти, не пройти или игнорировать) и сообщение.

Фактический тест просто подтверждает результат теста. Если он не равен «пройден», то тест не пройден с сообщением, возвращенным из результата теста 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));
    }
}

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

сбой или игнорирование) и сообщение.

Фактический тест просто подтверждает результат теста. Если он не равен «пройден», то тест не пройден с сообщением, возвращенным из результата теста 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));
    }
}

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

сбой или игнорирование) и сообщение.

Фактический тест просто подтверждает результат теста. Если он не равен «пройден», то тест не пройден с сообщением, возвращенным из результата теста 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));
    }
}

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

2
ответ дан 24 November 2019 в 17:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: