Есть желание !! И есть нужда :)
вот очень простая трансформация, улучшать можно сколько хочешь
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<body>
<h1>total is <xsl:value-of select="test-results/@total"/></h1>
<h1>errors: <xsl:value-of select="test-results/@errors"/></h1>
<h1>failures <xsl:value-of select="test-results/@failures"/></h1>
<h1>time taken <xsl:value-of select="test-results/test-suite/@time"/></h1>
<table>
<tr>
<td>
<b>name</b>
</td>
<td>
<b>status</b>
</td>
<td>
<b>time</b>
</td>
</tr>
<xsl:for-each select="//test-case">
<tr>
<td>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:value-of select="@result"/>
</td>
<td>
<xsl:value-of select="@time"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
и результат получился вот таким вот
total is 10
errors: 1 vs failures 2
time taken 211.862
name | status | time |
SeleniumTests.Prometeus_main.A1_First_Authorization | Error | 32.063 |
SeleniumTests.Prometeus_main.A2_First_News | Success | 14.638 |
SeleniumTests.Prometeus_main.A3_Valid_Login | Success | 13.630 |
SeleniumTests.Prometeus_main.A4_Change_Password | Success | 20.311 |
SeleniumTests.Prometeus_main.A5_Change_Password_back | Success | 16.904 |
SeleniumTests.Prometeus_main.A6_Password_Requirments | Success | 16.177 |
SeleniumTests.Prometeus_main.B1_Search_test_by_full_name | Success | 26.632 |
SeleniumTests.Prometeus_main.B2_Search_test_by_part_of_name | Success | 23.744 |
SeleniumTests.Prometeus_main.B3_Search_test_by_mask | Failure | 21.292 |
SeleniumTests.Prometeus_main.C3_Check_button_zakaz_back_confirm | Failure | 26.183 |
хорошо, тогда можно смотреть на трансформацию :)
http://automated-testing.info/forum/preobrazovanie-xml-otchetov-nunit-v-html#comment-3709
Большое вам спасибо!!! Получилось, уже немного понял принцип, как появится время постараюсь сделать разные украшательства, но главное что есть каркас. Осталось только украсить его и добавить рюшечек, плюшек и прочих приятностей :)
ну вот и чудно, пользуйтесь на здоровье
только потом покажите окончательный вид, который вы разработаете для себя
чтобы мы увидили, что означает простой репорт для ваших нужд в конечном виде :)
Сделал себе отчетик :) Может быть кому понадобится:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head>
<title>Отчет об автоматизированном тестировании</title>
</head>
<body>
<h1 align="center">Отчет об автоматизированном тестировании</h1>
<table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
<xsl:variable name="percent" select="format-number((test-results/@total - test-results/@errors) div test-results/@total * 100,'#.00')"/>
<xsl:if test="$percent > 95">
<tr>
<td bgcolor='#33CC00' align="left">
Generated by: <xsl:value-of select="test-results/@date"/> - <xsl:value-of select="test-results/@time"/>
</td>
</tr>
<tr>
<td bgcolor='#33CC00'>
$Name_of_Project
</td>
</tr>
</xsl:if>
<xsl:if test='$percent <= 95'>
<tr>
<td bgcolor='#FF3300'>
$Name_of_Project
</td>
</tr>
<tr>
<td bgcolor='#FF3300' align="left">
Generated: <xsl:value-of select="test-results/@date"/> - <xsl:value-of select="test-results/@time"/>
</td>
</tr>
</xsl:if>
</table>
<h2 align="center">Результаты</h2>
<table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
<tr valign="top">
<td>
<b>Тестовых сценариев</b>
</td>
<td>
<b>Успешных</b>
</td>
<td>
<b>С ошибками</b>
</td>
<td>
<b>Успешных</b>
</td>
<td>
<b>Общее время выполнения</b>
</td>
</tr>
<tr>
<td>
<xsl:value-of select="test-results/@total"/>
</td>
<td>
<xsl:value-of select="test-results/@total - test-results/@errors"/>
</td>
<td>
<xsl:value-of select="test-results/@errors"/>
</td>
<td>
<xsl:value-of select="format-number((test-results/@total - test-results/@errors) div test-results/@total * 100,'#.00')"/> %
</td>
<td>
<xsl:value-of select="test-results/test-suite/@time"/>
</td>
</tr>
</table>
<h2 align="center">Техническая информация</h2>
<table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
<tr>
<td>
<b>Программное обеспечение</b>
</td>
<td>
<b>Версия</b>
</td>
</tr>
<tr>
<td>
Browser
</td>
<td>
$Browser
</td>
</tr>
<tr>
<td>
Nunit version
</td>
<td>
<xsl:value-of select="test-results/environment/@nunit-version"/>
</td>
</tr>
<tr>
<td>
Clr-version
</td>
<td>
<xsl:value-of select="test-results/environment/@clr-version"/>
</td>
</tr>
<tr>
<td>
Platform
</td>
<td>
<xsl:value-of select="test-results/environment/@platform"/>
</td>
</tr>
<tr>
<td>
Operating System
</td>
<td>
<xsl:value-of select="test-results/environment/@os-version"/>
</td>
</tr>
</table>
<h2 align="center" >Результаты в разрезе сценариев</h2>
<table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
<tr>
<td width="25%">
<center><b>Тестовый сценарий</b></center>
</td>
<td width="15%" align="left">
<center><b>Результат</b></center>
</td>
<td width="25%" align="left">
<center><b>Детали ошибки</b></center>
</td>
<td width="15%" align="left">
<center><b>Время выполнения</b></center>
</td>
</tr>
<xsl:for-each select="//test-case">
<tr>
<td>
<xsl:value-of select="@name"/>
</td>
<xsl:if test="@result!='Error'">
<td bgcolor='#33CC00'>
<center><xsl:value-of select="@result"/></center>
</td>
<td>
<center> — </center>
</td>
</xsl:if>
<xsl:if test="@result!='Success'">
<td bgcolor='#FF3300'>
<center><xsl:value-of select="@result"/></center>
</td>
<td>
<center><xsl:value-of select="//message"/></center>
</td>
</xsl:if>
<td>
<center><xsl:value-of select="@time"/></center>
</td>
</tr>
</xsl:for-each>
</table>
<!-- <hr size="1" width="95%" align="left"></hr> -->
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Круто. Я впечатлен :)
Вот если бы я был бы дизайнером :) Возможно кто-то будет себе делать красивую страничку и захочет поделиться... А по поводу информативности отчетов, тут я бы с вами поспорил, информации тут достаточно, сам текст ошибки (суть) + при желани можно вывести stack-trace, но как по-мне это уже перебор. Хотя конечно при отладке мы получим куда более полную информацию.
Ps конечно очень интересно почему разработчики не предусмотрели нормальных отчетов, которые можно было бы просмотреть после тестирования, но с другой стороны теперь я знаю основы XSLT и XML.
да на картинке смотриться отлично
поздравляю с хорошим отчетом :)
да по поводу спора интересно почитать :) что же Дима такое спорное написал :)
А в чём вопрос? Наш репортер (TMX) помимо названия, статуса, времени выполнения содержит имя файла и строку кода, коллекцию ошибок (ErrorRecord), скриншоты контрола или десктопа (как минимум, по ошибке). Подумываю добавить (сделано в другом нашем фреймворке) выдёргивание данных с операционки ("другой" фреймворк копирует кусок лога нашего агента от начала работы тест-кейса до конца. Если агент падает или спотыкается, инфа подшивается автоматически).
К примеру, без скриншотов (которые или кидаются в SQLite базку, или вставляются в HTML репорт как ссылки на картинки с открытием в новом табе) разбираться с гуёвыми тестами не так удобно. Хотя, если ваши тесты атомарны, вы можете запустить красные результаты заново. Но всё равно, без актуальной инфы (логи, скриншоты) отчёты в NUnit'е пресноваты.
Я ещё вывожу на экран NUnit'а исходный код всех тестов. В отчёт это попасть не может (с экрана в отчёт никак не положить), но скопипэйстить в файл сэмплового кода можно.
Кстати, это вам ещё везет, что вы можете использовать NUnit: летом я приводил пример (не знаю, может сейчас они починили баги): omenahotels.com (довольно удобно, если надо провести праздники в Финляндии,и а коттедж на три дня брать или невыгодно, или все уже расхватаны).
Можете сами оформить заказ чисто из профессионального интереса - такое впечатление, что странички сами по себе потестили (чем-нибудь юниттестовым, к примеру), а вот когда надо взять три периода в разных гостиницах, да на трёх человек, вот тут начинается жесть. Я не только про то, что каждому постояльцу в комнате надо иметь уникальный номер тлф и имейл (пятилетний сын только-только начал что-то набирать на клавиатуре :) и мобильника пока не имеет, чтобы не заиграл его), в этих ходах можно лишиться всех набранных паспортных данных и адресов, и набирать заново.
Это я заглубился уже в сторону "юнит-тесты против сценарийных тестов". :)
Подумываю перейти на Gallio: из минусов пока заметил 1) какая-то ругань при фильтрации по категориям (наверное, у меня не везде категории были) 2) довольно неудобно выбрать две категории в дереве из всех - это ж надо схлопнуть почти все категории, чтобы увидеть нужные. Он ведь показывает категории из всех файлов проекта. 3) при добавлении файла к проекту, раскрывает всё дерево проекта (но это делается очень редко).
командлайн в нъюните не пользовал, поэтому сравнить не могу.
А, ещё такой полу-минус: у меня есть заготовки тестов на не первой актуальности фичи (файл с атрибутами/SetUP-TearDown, но без самих тестов). NUnit их не замечал (только цвет менял, а не счётчики), а Gallio считает их проблемными.
Ещё нашёл минорный недостаток: шесть ошибок в тесте, пошёл в Execution Log, справа только четыре красные зарубки (как будто только по одной категории показало, а не по двум). На самом деле, мелочь - оставшиесе две тоже в этих же местах лога расположены.
Перехвалил: в некоторых случаях (например, переход от категорий к неймспейсам, и не только), может потерять часть или все ветки проекта - приходится загружать проект заново.
Сама по себе загрузка проекта и тестов не быстрая, но это ещё может быть связано и с тем, что в нъюнит я грузил по одному проекту (но там это заметно быстрее).
Да, в автоэкспандом омжно бороться: есть контекстное меню в дереве, но хотелось бы вообще обойтись без бессмысленного автоэкспанда.
Пока резюме такое: можно работать с Moles (мне их не удалось завести даже на специально выкачанном нъюнит 2.5.2), но надо опасаться багов гуя ( и привыкать к ним).
а где же Дима Жарий, который хвалил Gallio? :)
К примеру, юзкейс: я архивирую сьюту моих проектов целиком (обычным севензипом ультра), включая нъюнитовские (теперь - галлиевские) проекты, стайлкоповские рулы, и т.д., и т.п. Юзкейс весьма неплох (я не юзаю сорс контрол, поскольку инет не всегда доступен, да и через корпоративный прокси не хочу долбиться), всё своё носится с собой на флешках и копируется в облако для пущей сохранности.
По известной теореме, на каждый юзкейс есть ненулевое число багов в произвольно взятом софте. Баг на мой юзкейс: при создании проекта, галлио прописывает путь вида c:\users\%username%\blah-blah-blah. В чём баг, спросите вы? Да вот, поделка-то как раз и не использует %username%. На машинках w8 у меня юзернейм генерится из хотмэйловского аккаунта, на других - сам задаю. Да и вообще я могу быть не один, но команда людей со строго разными именами. :) Итак, на всех машинках, кроме хостов w8 я имею эксепшн на ровном месте, после выполнения тестов, выдающий текст, что по пути c:\users\alexander\... gallio поджидал большой облом ввиду отсутствия пути. Кстати, создать путь галлио даже не собирается. Просто эксепшн, ниачём.
Опенсорс - это всегда весело!
Другой незначительный, но достающий баг - это NUnit add-in. NUnit поддерживает дескришены вида [TestFixture(Description="blah")], [Test(Description="description")]. Я их усердно заполнял в течение многих месяцев существования данной сьюты (ради хорошего тона, они в нъюните, на самом деле, не особо нужны). Кое-где у меня не было дескрипшена. Это стабильно вызывало серьёзнейшее недовольство галлио (хотя дескрипшен необязателен).
Сегодня я перешёл на MBUnit (тут надо похвалить - всго две автозамены в атрибутах, автозамена юзинга, автоазмена NotNull -> IsNotNull и немного замен в местах, где был полный путь вида NUnit.Framework.Assert...) и баг перестал меня беспокоить (нет-нет, он не пролечился, просто аддын нъюнит более не используется).
ну и были ещё баги по мелочам, или пролечились, или обошлись стороной. Поскольку галлио я запускаю обычно на хосте, где и сижу, все эти эксепшены по нескольку (десятков) раз в день не особо приятны. :)
А вообще продукт мощный, и параллельный запуск, и более-менее удобный доступ через рефлексию (всё же, в Moles и Moq мне больше нравится оттопыривание свойств/методов объекта). Жаль, что книжка продукта состоит, главным образом, из пустых страниц.
<testPackage shadowCopy="true" debug="false" applicationBaseDirectory="..\..\Bin\Wmm\" workingDirectory="..\..\Bin\Wmm"><files><file>..\..\Bin\Wmm\Wmm.Tests.dll</file></files><hintDirectories /><excludedFrameworkIds /><properties /></testPackage>
"C:\Program Files\Gallio\bin\Gallio.Utility.exe" FormatReport D:\TestReports\test-report-20121013-132029.xml /ReportType:Html
Вот ещё баг - опишу "от аналога". Писали мы некогда один популярный редактор, с автосохранением конечно, и прочими финтифлюшками. И вот был такой баг (и, в какой-то степени остался): открыть файл в чём-то и в редакторе, или просто два раза в редакторе. Затем несколько раз файл поменять и сохранить. Чё делает умный редактор (даже если отредактировали в том же инстансе редактора в другом табе)? Спрашивает, загрузить ли обновлённую версию файла.
Редактор просто ловит событие в файловой системе и выкидывает этот вопрос. Не важно, что из n сохранений можно спокойно не загружать первые (n - 1).
Точно также поступает и галлио. Я компилю быстро и охотно (Core i7, 8GB RAM, Vertex 4 - контора наконец-то шевельнула задом и проапгрейдила компы не только документаторам, и тем, кто пишет и компилит :)). И вот эта св загружает мои тесты (эксплорит, как это там называется) много раз. А загрузка - процесс не быстрый. Мои менее чем тысяча тестов из пяти пока проектов загружаются не меньше времени, чем компилятся. И так n раз.
Процесс прервать можно, но сложно и стрёмно: тут на сцену выходит другой баг: из таба Test Explorer легко теряются несколько или все проекты. Т.е., в Project Explorer они есть. Иногда помогает сделать Recent project этого самого проекта. Иногда помогает перейти из показа Namespace в Category, и обратно. Иногда - только перезапуском галлио.