Преобразование XML отчетов Nunit в HTML

Доброго времени суток уважаемые форумчане. Прошу поделиться шаблоном XSLT для преобразования отчетов Webdriver в читабельный вид, например в HTML. Или прошу поделиться опытом, как вы у себя реализовали отчетность после выполнения тестов?
Собственно единственный выход который я вижу это создание шаблона XSLT по которому будет преобразовываться XML.  Возможно кто-то уже делал такую штуку и готов поделиться?

Используется Selenium Webdriver на C# и Nunit 2.6.1

Заранее спасибо.
 

1 лайк

а какой отчет вы имеете ввиду? 

преобразование с помощью xslt, нормалное решение. могу помочь с реализацией если покажите ваш xml

но считаю, что это не нужно, потому что есть инструменты, которые уже отображают результаты

а как вы запускаете тесты и чем формируете отчеты? или вы просто подразумеваете xml сформированный nunit после выполнения тестов?

например, я практически всгеда использую Jenkins для отображения результатов выполнения тестов

Есть готовый аддын, даже два:http://nunit.org/wiki/doku.php?id=nunit:extensions

Test results и test summary

Мопед не мой(с), я просто вспомнил, как гуглил это когда-то...

Jenkins умеет произвольный XML представлять в виде отчета?

если мы говорим об отчетах, которые генерят всякие юнит фремворки, то ДА

только надо подключить правильный плагин https://wiki.jenkins-ci.org/display/JENKINS/xUnit+Plugin

или для nunit https://wiki.jenkins-ci.org/display/JENKINS/NUnit+Plugin

и даже можно отобразить людей html, который ты сформируешь https://wiki.jenkins-ci.org/display/JENKINS/HTML+Publisher+Plugin

Добрый день Михаил, имею ввиду отчет TestResults.xml, который получается на выходе после запуска тестов в Nunit. Готовые инструменты не подходят, объясняю почему:  у меня есть тест-сьют который сейчас запускается в Nunit и результаты я могу видеть толкьо внутри Nunit, но возникла идея автоматически после завершения тестирования отправлять себе email с подробным отчетом о тестировании. Этот отчет создается сам, но в формате XML, мне бы хотелось видеть его наглядно? например в таком формате как делает  программа NUnit2Report. 

У меня в проектах еще нет систем Continius Integration, хотя и планируется их ввести. В связи с этим отчет мне необходимо создать собственными силами а не Дженкинсом, или тим сити.

 

Пример XML файла который я получаю на выходе:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--This file represents the results of running a test suite-->
<test-results name="C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\bin\Debug\Prometeus.dll" total="10" errors="1" failures="2" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2012-09-27" time="09:15:49">
  <environment nunit-version="2.6.0.12035" clr-version="2.0.50727.5456" os-version="Microsoft Windows NT 6.1.7601 Service Pack 1" platform="Win32NT" cwd="C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\bin\Debug" machine-name="QA-WORK" user="Admin" user-domain="QA-work" />
  <culture-info current-culture="ru-RU" current-uiculture="ru-RU" />
  <test-suite type="Assembly" name="C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\bin\Debug\Prometeus.dll" executed="True" result="Failure" success="False" time="211.862" asserts="0">
    <results>
      <test-suite type="Namespace" name="SeleniumTests" executed="True" result="Failure" success="False" time="211.844" asserts="0">
        <results>
          <test-suite type="TestFixture" name="Prometeus_main" executed="True" result="Failure" success="False" time="211.842" asserts="0">
            <results>
              <test-case name="SeleniumTests.Prometeus_main.A1_First_Authorization" executed="True" result="Error" success="False" time="32.063" asserts="12">
                <failure>
                  <message><![CDATA[OpenQA.Selenium.ElementNotVisibleException : Element is not currently visible and so may not be interacted with]]></message>
                  <stack-trace><![CDATA[в OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse) в c:\Projects\WebDriver\trunk\dotnet\src\WebDriver\Remote\RemoteWebDriver.cs:строка 960
в OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters) в c:\Projects\WebDriver\trunk\dotnet\src\WebDriver\Remote\RemoteWebDriver.cs:строка 812
в SeleniumTests.Prometeus_main.A1_First_Authorization() в C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\MAIN.cs:строка 264
]]></stack-trace>
                </failure>
              </test-case>
              <test-case name="SeleniumTests.Prometeus_main.A2_First_News" executed="True" result="Success" success="True" time="14.638" asserts="10" />
              <test-case name="SeleniumTests.Prometeus_main.A3_Valid_Login" executed="True" result="Success" success="True" time="13.630" asserts="6" />
              <test-case name="SeleniumTests.Prometeus_main.A4_Change_Password" executed="True" result="Success" success="True" time="20.311" asserts="12" />
              <test-case name="SeleniumTests.Prometeus_main.A5_Change_Password_back" executed="True" result="Success" success="True" time="16.904" asserts="3" />
              <test-case name="SeleniumTests.Prometeus_main.A6_Password_Requirments" executed="True" result="Success" success="True" time="16.177" asserts="9" />
              <test-case name="SeleniumTests.Prometeus_main.B1_Search_test_by_full_name" executed="True" result="Success" success="True" time="26.632" asserts="13" />
              <test-case name="SeleniumTests.Prometeus_main.B2_Search_test_by_part_of_name" executed="True" result="Success" success="True" time="23.744" asserts="13" />
              <test-case name="SeleniumTests.Prometeus_main.B3_Search_test_by_mask" executed="True" result="Failure" success="False" time="21.292" asserts="7">
                <failure>
                  <message><![CDATA[Ошибка: Тест провален. Не удалось выполнить поиск теста по его названию]]></message>
                  <stack-trace><![CDATA[в SeleniumTests.SearchTests.DoSearchTestAndCourse(IWebDriver& driver, String NameOfTest) в C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\SearchTests.cs:строка 162
в SeleniumTests.Prometeus_main.B3_Search_test_by_mask() в C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\MAIN.cs:строка 747
]]></stack-trace>
                </failure>
              </test-case>
              <test-case name="SeleniumTests.Prometeus_main.C3_Check_button_zakaz_back_confirm" executed="True" result="Failure" success="False" time="26.183" asserts="8">
                <failure>
                  <message><![CDATA[Ошибка: Тест провален. Не удалось выполнить поиск теста по его названию]]></message>
                  <stack-trace><![CDATA[в SeleniumTests.SearchTests.DoSearchTest(IWebDriver& driver, String NameOfTest) в C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\SearchTests.cs:строка 91
в SeleniumTests.Prometeus_main.C3_Check_button_zakaz_back_confirm() в C:\DATA\Dropbox\WORK\Autotests\Prometeus_Project\Prometeus_main\Prometeus_Firefox\MAIN.cs:строка 788
]]></stack-trace>
                </failure>
              </test-case>
            </results>
          </test-suite>
        </results>
      </test-suite>
    </results>
  </test-suite>
</test-results>

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

Посмотрите вот этот проект. 

Он использует XSL файлы для отчета:

https://github.com/jupaol/NUnit2Report.Console

 

Смотрел уже, я оттуда и взял саму идею :) Написал выше как пример этот проект. Да там есть эти файлы, но они для преобразования каких-то других XML. Похоже придется писать данную функциональность самому, гугл молчит по поводу стандартных отчетов Nunit.  Хотя странно конечно, неужели никому из пользователей Webdriver'a не нужны отчеты в нормальном красивом виде, ну или все просто сидят на CI системах...

Ох уж мне эти опенсорсные вёдра! Не может скачать плагин даже в браузере, подключённом в обход корпоративного прокси:

 

  • Checking internet connectivity
  • Checking update center connectivity
  • java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(Unknown Source) at java.net.PlainSocketImpl.connectToAddress(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at hudson.model.UpdateCenter$UpdateCenterConfiguration.testConnection(UpdateCenter.java:800) at hudson.model.UpdateCenter$UpdateCenterConfiguration.checkUpdateCenter(UpdateCenter.java:649) at hudson.model.UpdateCenter$ConnectionCheckJob.run(UpdateCenter.java:966) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

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

все сидят в CI система, это проще :)

Нет не все сидят на CI системах :)

Заюзайте у себя MbUnit Gallio Icarus:

http://gallio.org/

Переход с NUnit будет не сложным, и у вас будут и хорошие отчеты и в момент работы и после прогона. Есть хорошая интеграция с Visual Studio  и на 95% MbUnit совместим с кодом для NUnit. 

http://gallio.org/Screenshots.aspx

 

Gallio Icarus также умеет "читать" и запускать тесты для NUnit, но у родного "MbUnit"  возможностей значительно больше. В том числе это относится и к графическому форматированию отчетов. 

приложи еще пример html, какой хочешь получить на выходе 

и сегодня вечером, накидаю тебе приблизительный xslt для преобразования

Спасибо большое, посмотрим что это за зверь такой MbUnit Gallio Icarus. Посмотрел скриншоты, меня заинтересовало, симпатично, а самое главное человеческий отчет :)

Вот тут есть примеры таких отчетов http://nunit2report.sourceforge.net/NUnit2Report.Examples.html вместе с их HTML, но там слишком круто. Мне было бы достаточно одной таблички с результатами, например с колонками - имя теста, статус (пройден), (завален), если завален то по какой причине (exeptions)  ну  и + общее время выполнение тестов. Другими словами мне бы простенький каркас, чтобы я увидел возможности этого XSLT, а дальше я уже сам попробую красоту навести :) например так как тут - http://nunit2report.sourceforge.net/Compagny-Report.htm

Может не в тему, но есть еще task nunit2report в NantConrtlib, который из xml файла создает html

http://nantcontrib.sourceforge.net/release/0.91/help/tasks/nunit2report.html

Мне было бы достаточно одной таблички с результатами, например с колонками - имя теста, статус (пройден), (завален), если завален то по какой причине (exeptions)  ну  и + общее время выполнение тестов.

NUint-results (только красный цвет потерялся по дороге):

 

 

Class

Tests

Not Run

Failures

CloseTMXTestDBCommandTestFixture

1

0

1

NewTMXTestDBCommandTestFixture

1

0

0

OpenTMXTestDBCommandTestFixture

1

0

0

AddTMXTestBucketCommandTestFixture

1

0

1

AddTMXTestConstantCommandTestFixture

1

0

1

GetTMXTestBucketCommandTestFixture

1

0

1

GetTMXTestConstantValueCommandTestFixture

1

0

1

RemoveTMXTestBucketCommandTestFixture

1

0

1

RemoveTMXTestConstantCommandTestFixture

1

0

1

SetTMXTestBucketCommandTestFixture

1

0

1

SetTMXTestConstantValueCommandTestFixture

1

0

1

BackupTMXTestResultsCommandTestFixture

1

0

1

RestoreTMXTestResultsCommandTestFixture

1

0

1

SaveTMXTestScreenshotCommandTestFixture

1

0

1

SearchTMXTestResultCommandTestFixture

18

0

0

SearchTMXTestScenarioCommandTestFixture

16

0

0

SearchTMXTestSuiteCommandTestFixture

22

0

0

AddTMXTestCaseCommandTestFixture

1

0

1

AddTMXTestResultDetailCommandTestFixture

4

0

0

AddTMXTestScenarioCommandTestFixture

14

0

0

CloseTMXTestResultCommandTestFixture

23

0

0

GetTMXTestCaseCommandTestFixture

1

0

1

NewTMXTestSuiteCommandTestFixture

11

0

0

OpenTMXTestScenarioCommandTestFixture

6

0

0

OpenTMXTestSuiteCommandTestFixture

6

0

0

RemoveTMXTestCaseCommandTestFixture

1

0

1

SetTMXTestCaseCommandTestFixture

1

0

1

TMXProviderTestFixture

6

0

0

TMXEventsTestFixture

6

0

0

Total

150

0

16

 

 

Failures

1

CloseTMXTestDBCommandTestFixture.CloseTestDB_Simple
Expected: null But was: < null >

at CmdletUnitTest.TestRunspace.RunAndEvaluateIsNull(String codeSnippet)
at TMXTest.Commands.Database.CloseTMXTestDBCommandTestFixture.CloseTestDB_Simple()

2

AddTMXTestBucketCommandTestFixture.AddTestBucket_Simple
System.NullReferenceException : Object reference not set to an instance of an object.

at CmdletUnitTest.TestRunspace.RunAndEvaluateAreEqual(String codeSnippet, String strValue)
at TMXTest.Commands.Repository.AddTMXTestBucketCommandTestFixture.AddTestBucket_Simple()
 

P.S. Я бы сказал, что даже для простенького фреймворка детализация по каждому тесту - это выше крыши. Они показывают эксепшн, и этого достаточно. ОБщая масса тестов идёт с разбивкой на фиксчи, и если этого недостаточно, их можно разбить на мелкие фиксчи.

Показ отдельного теста - зачем это? NUit'овский XML всё равно не содержит подробностей. Я, к примеру, вывожу в NUnit некоторое описание и код, который запускается, но это можно увидеть только в самом приложении (если не сделать дами в файл). А сам по себе репорт NUnit'а не особо информативен: счётчики результатов с разбивкой на фиксчи, да время выполнения.

 

 

так что XSLT уже делать нет желаения? :)

а ты просто скачай плагин, который ты хочешь поставить и загрузи его через upload и проблем нету

да, я в итоге поставил (результат ещё не посмотрел).

Хорошо, что по дженкинсу книжки есть - нашёл две, в одной случайно наткнулся: оказывается, настройка прокси не в настройках дженкинса, где я искал, а (кто бы мог догадаться! :)) в настройках плагинов.