совместное использование списков сценариев html / javascript… или выполнение CI с помощью jasmine и selenium

#javascript #html #extjs #selenium #jasmine

#javascript #HTML #extjs #селен #jasmine

Вопрос:

Я довольно новичок в js html. Я настроил некоторые приемочные тесты на основе js (extjs) с использованием jasmine и теперь собираюсь настроить для них непрерывную интеграцию.

Поскольку они запускаются в браузере, придется немного повозиться, чтобы заставить их работать под CI. Я думал о том, чтобы использовать selenium для запуска тестов (у нас уже есть рабочая настройка selenium, так что это должно быть легко) и использовать jasmine-reporters для вывода результатов в файл, который CruiseControl.net могу понять.

Jasmine довольно прост в том, как он работает, и в итоге вы пишете html-страницу, которая выглядит следующим образом:

 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>

<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">

<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>

<script type="text/javascript">
    //set this a bit higher to aid debugging
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
</script>

<!-- include source files here... -->
<script type="text/javascript" src="Sample/src/Player.js"></script>
<script type="text/javascript" src="Sample/src/Song.js"></script>

<script type="text/javascript" src="/native/WeatherVane.js"></script>
<script type="text/javascript" src="/native/EventCreator.js"></script>

<script type="text/javascript" src="/ext/ext-all-dev.js"></script>
<script type="text/javascript" src="/api/api.js"></script>
<script type="text/javascript">
    Ext.app.REMOTING_API.maxRetries = 0;
    Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
</script>

<!-- include spec files here... -->
<script type="text/javascript" src="Sample/spec/SpecHelper.js"></script>
<script type="text/javascript" src="Sample/spec/PlayerSpec.js"></script>
<script type="text/javascript" src="Tests/EventCreation.js"></script>

<!-- note this needs to be last as it fires up the tests-->
<script type="text/javascript" src="TestApp.js"></script>
 

На самом деле я еще не успел удалить образцы тестов!
В любом случае, самый простой способ, который я мог бы сделать, — это перейти на другую страницу, которая использует другое тестовое приложение (последняя запись), которое настраивает jasmine на использование nunitreporter из библиотеки jasmine-reporters и просто заставить selenium запускать эту страницу

Очевидно, я не хочу просто копировать вставлять все туда и изменять только последний бит. Это будет список, в который мы будем добавлять много, и это будет настоящей болью, если CI и локальное тестирование не работают в основном одинаково.

По сути, я хотел бы эффективно разделить его на два документа / набора включений, подобных этому:

Документ A — общая настройка

 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>

<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">

<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>

<script type="text/javascript">
    //set this a bit higher to aid debugging
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
</script>

<!-- include source files here... -->
<script type="text/javascript" src="Sample/src/Player.js"></script>
<script type="text/javascript" src="Sample/src/Song.js"></script>

<script type="text/javascript" src="/native/WeatherVane.js"></script>
<script type="text/javascript" src="/native/EventCreator.js"></script>

<script type="text/javascript" src="/ext/ext-all-dev.js"></script>
<script type="text/javascript" src="/api/api.js"></script>
<script type="text/javascript">
    Ext.app.REMOTING_API.maxRetries = 0;
    Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
</script>

<!-- include spec files here... -->
<script type="text/javascript" src="Sample/spec/SpecHelper.js"></script>
<script type="text/javascript" src="Sample/spec/PlayerSpec.js"></script>
<script type="text/javascript" src="Tests/EventCreation.js"></script>
 

Документ B — текущий метод вывода браузера:

  SomeCommandToInclude(documentA);

<!-- note this needs to be last as it fires up the tests-->
<script type="text/javascript" src="TestApp.js"></script>
 

Документ C — метод вывода CI / xml:

  SomeCommandToInclude(documentA);

<!-- note this needs to be last as it fires up the tests-->
<script type="text/javascript" src="XmlOutputApp.js"></script>
 

Я несколько раз чувствовал, что хочу сделать что-то очень похожее с этими списками сценариев html. Как вы это делаете? Возможно ли это вообще? Некоторое время назад я просматривал некоторые вещи, связанные с document.write, но, похоже, это не совсем правильно.

Если невозможно включить эти списки сценариев друг в друга, я открыт для других подходов к запуску CI, хотя я предпочитаю делать это с помощью selenium, поскольку я не хочу изучать еще одну библиотеку / технологию и тратить годы на то, чтобы заставить ее работать.

Ответ №1:

Вот что я сделал. Я не понял, как включить html-файлы, но у меня что-то работает.

Базовый подход

Я передал параметр в URL, который указывает, находимся ли мы в режиме CI. Библиотека тестирования на стороне клиента анализирует URL-адрес, чтобы проверить, должен ли он создавать вывод xml. Поскольку selenium запускает это в браузере, оно не может быть сохранено непосредственно в файл. Вместо этого я записал это в строку, а затем запросил эту строку у Selenium и оттуда записал ее на диск.

Jasmine-репортеры

Jasmine-reporters был разветвлен, чтобы справиться с jasmine-2.0, который я использую, обратите внимание, что ветвь 2.0 не является основной ветвью. Я не знаком с git и был брошен им, скрывая другую ветку от вас в истории. Там есть совместимая версия jasmine-reporters.

Я использовал NUnit reporter, и для облегчения использования с selenium я совершил массовый взлом и заменил метод записи файла следующим:

     self.writeFile = function(text) {
        self.output(text, totalSpecsFailed > 0);
    };
 

Я также добавил это в конструктор:

 self.output = options.output;
 

Затем мой вызывающий / конфигурационный код выполняет это, если мы находимся в режиме CI:

 var jasmineEnv = jasmine.getEnv();
jasmineEnv.addReporter(new jasmineReporters.NUnitXmlReporter(
    {
        output: function (xmlOutput, anyFailures) {
            testConfig.xmlOutput = xmlOutput;
            testConfig.anyFailures = anyFailures;
        }
    }));
 

Селен

Код selenium выглядит следующим образом (обратите внимание, что это не сырой selenium — он проходит через API, который я обернул вокруг основного материала, но вы должны быть в состоянии понять суть)

     public void PokeTheTestPage()
    {
        try
        {
            NavigateTo(WebAppUrl   "Tests/Jasmine/SpecRunner.html?outputFile=true");

            var error = Driver.GetStringWith("return weatherVane.testConfig.errorText;");

            if (error != "")
                ExitWithError(error);

            var testOutput = LongWait.Until(d => d.GetStringWith("return weatherVane.testConfig.xmlOutput;"));
            var failed = Driver.GetBoolWith("return weatherVane.testConfig.anyFailures;");

            using (var file = File.OpenWrite(_outputFile))
            using (var writer = new StreamWriter(file))
                writer.Write(testOutput);

            if (failed)
                ExitWithError("tests failed");
        }
        catch (Exception e)
        {
            ExitWithError(e.ToString());
        }
    }

    private void ExitWithError(string error)
    {
        Console.WriteLine("got Error:");
        Console.WriteLine(error);
        Driver.Close();
        Environment.Exit(1);
    }
}