Доброго времени суток уважаемые форумчане. Прошу поделиться шаблоном XSLT для преобразования отчетов Webdriver в читабельный вид, например в HTML. Или прошу поделиться опытом, как вы у себя реализовали отчетность после выполнения тестов? Собственно единственный выход который я вижу это создание шаблона XSLT по которому будет преобразовываться XML. Возможно кто-то уже делал такую штуку и готов поделиться?
Используется Selenium Webdriver на C# и Nunit 2.6.1
Добрый день Михаил, имею ввиду отчет 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>
Смотрел уже, я оттуда и взял саму идею :) Написал выше как пример этот проект. Да там есть эти файлы, но они для преобразования каких-то других 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)
Может быть, где-то в самом дженкинсе задать прокси или обход прокси надо? Наверняка надо какую-то переменную создать и задать туда обход прокси, иначе лежать моему корпоративному логину-паролю где-нибудь в текстовом файле...
Переход с NUnit будет не сложным, и у вас будут и хорошие отчеты и в момент работы и после прогона. Есть хорошая интеграция с Visual Studio и на 95% MbUnit совместим с кодом для NUnit.
Gallio Icarus также умеет "читать" и запускать тесты для NUnit, но у родного "MbUnit" возможностей значительно больше. В том числе это относится и к графическому форматированию отчетов.
Спасибо большое, посмотрим что это за зверь такой MbUnit Gallio Icarus. Посмотрел скриншоты, меня заинтересовало, симпатично, а самое главное человеческий отчет :)
Вот тут есть примеры таких отчетов http://nunit2report.sourceforge.net/NUnit2Report.Examples.html вместе с их HTML, но там слишком круто. Мне было бы достаточно одной таблички с результатами, например с колонками - имя теста, статус (пройден), (завален), если завален то по какой причине (exeptions) ну и + общее время выполнение тестов. Другими словами мне бы простенький каркас, чтобы я увидел возможности этого XSLT, а дальше я уже сам попробую красоту навести :) например так как тут - http://nunit2report.sourceforge.net/Compagny-Report.htm
Мне было бы достаточно одной таблички с результатами, например с колонками - имя теста, статус (пройден), (завален), если завален то по какой причине (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'а не особо информативен: счётчики результатов с разбивкой на фиксчи, да время выполнения.
да, я в итоге поставил (результат ещё не посмотрел).
Хорошо, что по дженкинсу книжки есть - нашёл две, в одной случайно наткнулся: оказывается, настройка прокси не в настройках дженкинса, где я искал, а (кто бы мог догадаться! :)) в настройках плагинов.