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

Вот если бы я был бы дизайнером :) Возможно кто-то будет себе делать красивую страничку и захочет поделиться... А по поводу информативности отчетов, тут я бы с вами поспорил, информации тут достаточно, сам текст ошибки (суть) + при желани можно вывести stack-trace, но как по-мне это уже перебор. Хотя конечно при отладке мы получим куда более полную информацию.

Ps конечно очень интересно почему разработчики не предусмотрели нормальных отчетов, которые можно было бы просмотреть после тестирования, но с другой стороны теперь я знаю основы XSLT и XML.

 

Э..ээ ээ а по поводу информативности отчетов, я с вами спор и не начинал даже :)
А вот почему разработчики не предусмотрели нормальных отчетов, то тут у меня ответ есть. 
NUnit в первую очередь – инструмент для модульных тестов, и интеграционных тестов, когда код приложения непосредственно используется из тестов (Белый Ящик). Если тест завалился – то это не из за того, что у дива в спане айдишник поменялся, а из-за того, что что-то серьезное поменялось в коде приложения. 
Для юнит-тестов отчеты в HTML не особо нужны. И если  в тестах произойдет исключение, например NullReferenceException  – то колл-стек приведет программиста из теста прямо в том место, где оно было выброшено в приложении. 
Для программистов вполне хватает той функциональности, что уже есть в NUnit и не нужны красивые отчеты. 
Мы юзаем NUnit для авто тестов. Просто чтобы не изобретать свой велосипед, ведь инструмент по большей частью нам подходит.
Красивые отчеты больше нужны тестировщикам-автоматизаторам, а не программистам. 
А с новым опытом работы с XSLT – я вас поздравляю. 
 

да на картинке смотриться отлично

поздравляю с хорошим отчетом :) 

да по поводу спора интересно почитать :) что же Дима такое спорное написал :)

Прошу прощения, это писал "apetrovskiy" - "NUit'овский 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 мне больше нравится оттопыривание свойств/методов объекта). Жаль, что книжка продукта состоит, главным образом, из пустых страниц.

 

На счет путей, можно отредактировать файл проекта Gallio и указать относительные пути. 
По типу       
  <testPackage shadowCopy="true" debug="false" applicationBaseDirectory="..\..\Bin\Wmm\" workingDirectory="..\..\Bin\Wmm">
    <files>
      <file>..\..\Bin\Wmm\Wmm.Tests.dll</file>
    </files>
    <hintDirectories />
    <excludedFrameworkIds />
    <properties />
  </testPackage>
 
К сожалению, с отчетами относительные пути не очень хорошо работают:
  <reportDirectory>..\Reports</reportDirectory>
После прогона в Icarus, отчеты будут складываться в указанную папку,  но не будут отображается в списке прогнанных отчетов на UI. Потому что Icarus читает файлы отчетов только из дефолтной папки на пользователя. 
В случае нестандартной папки, придется конверитить XML самостоятельно, при помощи команды:
 
"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, и обратно. Иногда - только перезапуском галлио.

 

Как альтернативный вариант, если ведется работа над одним тестом, предлагаю запускать его из Visual Studio, без Gallio Icarus.
Для этого, если у вас проект – типа ClassLibrary, его нужно сделать Test Project ом. 
Для этого , откройте ClassLibrary1.csproj
И в PropertyGroup добавьте строку:
 
    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
 
Выглядеть должно все примерно так:
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{571A8714-C36F-497D-A076-E6C1DEDFFC94}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ClassLibrary1</RootNamespace>
    <AssemblyName>ClassLibrary1</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
  </PropertyGroup>
 
 

 

Спасибо, но я практически не юзаю студию (разве что время от времени подглядеть, как работает Coded UI, или что-то надо в Team Explorer, или вот заценить Moles в применении к проекту). Шарпдевелоп тоже поддержвает плагины с юнит-тестами, в т.ч. и галлио, но я пока не пробовал привинтить.

Пока что отключил автозагрузку проектов.

 

Это вообще беда икаруса - медленная загрузка, да ещё он пытается абсолютно все изменения загрузить... Под это дело вспомнился агнекдот пятилетней давности: писали как-то америкосы UMI (это как WMI, но для Unix/Linux). Для начала, из совсем простецкой версии решили сделать немного посложнее - часть на POSIX, часть через вызов системных утилит. Понятно, что то, что было сделано через утили, быстро не работало (не говоря уже о том, что разные производители этого зоопарка (тогда поддерживалось около 45 платформ) очень по-разному поддерживали POSIX (кто не полностью, а кто нормально, но очень тормозно).

А работало это всё в среде SMS 2003/SCCM 2007 - опрос машинок на предмет софта и прочего, что СМС от рождения делает для виндовых хостов. Так вот, интервал опроса - 10 минут, а полный цикл опроса у них получился 15 минут. Так оно и работало без остановки, подгоняемое всё новыми и новыми запросами, прям как галлио.

 

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

Глобально тестовый проект у меня в TFS – стандарт корпоративный. А локально удалось настроить себе Git и Git tf для интеграции с TFS ( http://gittf.codeplex.com/ ).

Хотел сделать интеграцию с Gallio, даже пытался  что-то там скомпилить, но сразу не получилось, и я забросил это дело (https://github.com/icsharpcode/SharpDevelop/wiki/Gallio-Addin-Sample).  Кроме того, как я понял, интеграция там будет не полная. И такой фичи, как запуск Шаарпдевелоп из Icarus не будет. 

Они предлагают слишком неюзабельную методу - доложить что-то в исходники вместо того, чтобы ставить шарпдевелоп через msi. :)

Посмотрел пристально на юнит тесты в шарпдевелоп - что-то мне кажется, что они работают через какой-то xml и помнят то, чего нет :) Вообще не те проекты, как будто когда-то что-то в xml записалось и навсегда.

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

Пока дело кончилось тем, что я поотключал плагины и поменял настройку Test runner factory на IsolatedAppDomain (как вариант - Local, каждый раз открывать-закрывать приложение, зато открывается быстро).

Если собрать приложение когда выбран IsolatedAppDomain, и отказаться от Reload (ну почему нет настройки вообще никогда не релоадить самостоятельно, даже не спрашивать???), галлио плюётся эксепшеном.

В общем, это терпимо (хотя лишние мессаджбоксы раздражают).

 

Но нашлась гораздо более важная проблема - в галлио, в принципе, отсутствует дебаг командлайном! Поскольку мои фреймфорки основываются (нижний уровень) на командлайне, вывод как средствами пауэршелл, так и простым Console.Writeline(string) ускоряет понимание происходящего на порядки.

Я специально решил побиться (по глубокой ночи) с галлио, чтобы понять, почему у меня юнит-тесты не работали с коллекциями, содержащими более одного элемента. Ага.

На следующее утро я реплейсом скрыб юзинг мбюнита и открыл юзинг нъюнита и вопрос решился за минуты.

Наверное, пока буду действовать так (вариант контрибьючения в галлио на предмет плагина командной строки или встроенной командной строки я исключаю): пока фреймворк в активной работе, и "фреймворк фреймворка" ещё не вызрел, буду работать через нъюнит. Когда уже костяк готов, и остаётся дописывать тесты "по аналогии", буду включать галлио и иметь отчёты.

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

Поскольку нет возможности сохранять/загружать "зачекивания" (architecture flaw, лечится созданием нескольких проектов, вероятно), зачекивания снимать лень, и только-только добавленный проект выполнился последним (а он в дереве самый первый, на латинскую букву A).

 

Я вот что-то недопонял на счет дебага в коммандлайне. Console.Writeline Gallio поддерживает, и все строки из стандартного ввода попадают в лог тест кейса. 
Вторая загадка – это почему же вы все таки так не хотите использовать Visual Studio? Ведь производительность разработки просто возрастает в разы. Будет полная интеграция со всеми плюшками Gallio Icarus. 
Ну, а на других тестовых машинах можно и Шарпдевелопом обойтись. 
Ну, и кроме того, используя Remote Debugger в Visual Studio, вам будут доступны такие фишки, как Edit and Continue (когда под дебаггером можно менять исходный код) и Intellitrace ("путешествие во времени" во время дебага ). 
Вот инструкция по работе с Remote Debugger если что:
https://groups.google.com/forum/?fromgroups=#!topic/gallio-user/j5y38iH3MdA
 
З.Ы.: Я тоже люблю всякие штучки, по типу, а можно ли на Windows PE поставить SQLServer Express и IIS Express и ранать тесты на официально бесплатном окружении. Но, все таки, если цель – это создание фреймворка по тестированию, а не получение удовольствия от настройки системы – то лучше пользовать проверенные инструменты и ходить протоптанными путями. 
З.З.Ы: Надеюсь не заразил вас идеей на счет WinPE
 

Добрый день Михаил,
У меня никак не получается преобразовать результат теста из XML в HTML.
Вот XML коде:

<?xml version="1.0" encoding="UTF-8"?>
<TestRun id="08169a9a-9b28-4e55-8abb-414ed6404e80" name="sbaider@AUTOTEST1 2016-08-12 03:10:57" runUser="MAPSTRAT\sbaider" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
  <TestSettings name="Default Test Settings" id="bebd84e1-6e9b-483c-b1ee-7e3c78cab87b">
    <Execution>
      <TestTypeSpecific />
      <AgentRule name="Execution Agents">
      </AgentRule>
    </Execution>
    <Deployment runDeploymentRoot="sbaider_AUTOTEST1 2016-08-12 03_10_57" />
    <Properties />
  </TestSettings>
  <Times creation="2016-08-12T03:10:57.3200575-05:00" queuing="2016-08-12T03:10:58.0509107-05:00" start="2016-08-12T03:10:58.2219585-05:00" finish="2016-08-12T03:30:45.6702283-05:00" />
  <ResultSummary outcome="Failed">
    <Counters total="11" executed="11" passed="10" error="0" failed="1" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
  </ResultSummary>
  <TestDefinitions>
    <UnitTest name="LoginWithWrongPasswordAndVerifyErrorMessage" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="a1ccde85-662b-9ee1-d60a-8a6906d4ec9e">
      <Execution id="3b775874-7872-41de-a490-b29ca4d8908d" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.CredentialsTest, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LoginWithWrongPasswordAndVerifyErrorMessage" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="TypeTextAndSendMessageFromMessageSendMessagePage" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="60969a90-a9f5-0eee-9352-958101d70ba3">
      <Execution id="6ec687ce-ef77-4663-983e-234cc56bc552" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.SendMessage, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="TypeTextAndSendMessageFromMessageSendMessagePage" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="DownloadOldUpdaterAndOnBoardAppsVersionsThenSendCommandToUpdateOnBoardApps_VerifyThatOldAndNewOnBoardVersionsAreDifferent" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="ed952ee1-d27e-187d-2e60-06f65a0d3514">
      <Execution id="41cf9e61-a205-4f3d-9e44-a6fc70bb49ef" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.Auto_Upgrade_AppsVersion, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="DownloadOldUpdaterAndOnBoardAppsVersionsThenSendCommandToUpdateOnBoardApps_VerifyThatOldAndNewOnBoardVersionsAreDifferent" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="synchronizationTestResult" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="ce14eba0-b7e1-4b8a-fc42-5cb800521cbf">
      <Execution id="e7e39d89-00db-4e8f-a452-cd0c50352551" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.ClientTimeZoneSettingsInDataBaseAndOBU, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="synchronizationTestResult" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="ClickOnEmergencyButtonInOBUAndAcceptPopupMsgInPortal" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="b92bc9eb-ef99-ee1c-0780-20ca0972b13a">
      <Execution id="282ab4b6-6d62-42af-b601-dc4111bc210e" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.SendEmergencyAlert, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="ClickOnEmergencyButtonInOBUAndAcceptPopupMsgInPortal" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="LoginAsDriverAndVerifySettingsButtonIsDisable" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="62991ca9-d372-983a-ec9b-09c949d9d44e">
      <Execution id="cece918e-d0a1-4d8b-a6e1-a9b116210537" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.CredentialsTest, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LoginAsDriverAndVerifySettingsButtonIsDisable" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="SendMessageFromViewVehiclesPage" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="0e842caa-b551-f574-1977-af66b1008750">
      <Execution id="d3b507b1-8635-4b7e-a58f-5f16338fb91d" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.SendMessage, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="SendMessageFromViewVehiclesPage" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="SelectAndSendMessageFromScrolDownOptionListFromMessageSendMessagePage" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="e48b1dc7-81d7-7603-ef8d-975a68e3ae81">
      <Execution id="d84725a2-1377-4014-9324-ddfef561aac9" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.SendMessage, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="SelectAndSendMessageFromScrolDownOptionListFromMessageSendMessagePage" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="LoginAsSysAdminAndVerifySettingsButtonIsEnable" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="335fad92-233f-e926-db2a-3683859a5a97">
      <Execution id="459d660e-16b5-4743-b169-6bf169f022d3" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.CredentialsTest, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LoginAsSysAdminAndVerifySettingsButtonIsEnable" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="synchronizationTestResult" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="763435b6-b5e4-9d6e-a97a-f9e6bbe34012">
      <Execution id="c03bd2ab-79a1-456c-9e0b-52439f53162b" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.SynchronizationTestSuccess, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="synchronizationTestResult" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
    <UnitTest name="SendMessageToDispatch_BusBrokeDown" storage="c:\autotest\autotestobu\autotestobu\bin\debug\autotestobu.dll" id="308dc99f-dab3-4ca5-c904-47f93c35235a">
      <Execution id="7ef44d77-72f6-48f9-b3f4-c734a54df5ec" />
      <TestMethod codeBase="C:/AutoTest/AutoTestOBU/AutoTestOBU/bin/Debug/AutoTestOBU.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="AutoTestOBU.SendMessage, AutoTestOBU, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="SendMessageToDispatch_BusBrokeDown" />
      <Extension>Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute, Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Extension>
    </UnitTest>
  </TestDefinitions>
  <TestLists>
    <TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
  </TestLists>
  <TestEntries>
    <TestEntry testId="ed952ee1-d27e-187d-2e60-06f65a0d3514" executionId="41cf9e61-a205-4f3d-9e44-a6fc70bb49ef" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="ce14eba0-b7e1-4b8a-fc42-5cb800521cbf" executionId="e7e39d89-00db-4e8f-a452-cd0c50352551" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="62991ca9-d372-983a-ec9b-09c949d9d44e" executionId="cece918e-d0a1-4d8b-a6e1-a9b116210537" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="335fad92-233f-e926-db2a-3683859a5a97" executionId="459d660e-16b5-4743-b169-6bf169f022d3" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="a1ccde85-662b-9ee1-d60a-8a6906d4ec9e" executionId="3b775874-7872-41de-a490-b29ca4d8908d" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="b92bc9eb-ef99-ee1c-0780-20ca0972b13a" executionId="282ab4b6-6d62-42af-b601-dc4111bc210e" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="e48b1dc7-81d7-7603-ef8d-975a68e3ae81" executionId="d84725a2-1377-4014-9324-ddfef561aac9" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="0e842caa-b551-f574-1977-af66b1008750" executionId="d3b507b1-8635-4b7e-a58f-5f16338fb91d" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="308dc99f-dab3-4ca5-c904-47f93c35235a" executionId="7ef44d77-72f6-48f9-b3f4-c734a54df5ec" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="60969a90-a9f5-0eee-9352-958101d70ba3" executionId="6ec687ce-ef77-4663-983e-234cc56bc552" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
    <TestEntry testId="763435b6-b5e4-9d6e-a97a-f9e6bbe34012" executionId="c03bd2ab-79a1-456c-9e0b-52439f53162b" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
  </TestEntries>
  <Results>
    <UnitTestResult executionId="41cf9e61-a205-4f3d-9e44-a6fc70bb49ef" testId="ed952ee1-d27e-187d-2e60-06f65a0d3514" testName="DownloadOldUpdaterAndOnBoardAppsVersionsThenSendCommandToUpdateOnBoardApps_VerifyThatOldAndNewOnBoardVersionsAreDifferent" computerName="AUTOTEST1" duration="00:05:06.7130612" startTime="2016-08-12T03:10:58.2841577-05:00" endTime="2016-08-12T03:16:05.1200315-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Failed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="41cf9e61-a205-4f3d-9e44-a6fc70bb49ef">
      <Output>
        <ErrorInfo>
          <Message>Test method AutoTestOBU.Auto_Upgrade_AppsVersion.DownloadOldUpdaterAndOnBoardAppsVersionsThenSendCommandToUpdateOnBoardApps_VerifyThatOldAndNewOnBoardVersionsAreDifferent threw exception: 
System.InvalidOperationException: unknown error: Element is not clickable at point (965, 247). Other element would receive the click: &lt;iframe id="sub-app" src="/HtmlClient/Vehicle.aspx" ng-if="!isSilverlight" ng-style="expanderStatus.collapse?{top:&amp;quot;20px&amp;quot;}:{top:&amp;quot;60px&amp;quot;}" onload="subAppLoaded()" class="ng-scope" ng-src="/HtmlClient/Vehicle.aspx" style="top: 60px; height: 957px;"&gt;...&lt;/iframe&gt;
  (Session info: chrome=52.0.2743.116)
  (Driver info: chromedriver=2.20.353145 (343b531d31eeb933ec778dbcf7081628a1396067),platform=Windows NT 6.1 SP1 x86_64)</Message>
          <StackTrace>    at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
   at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Remote.RemoteWebElement.Click()
   at AutoTestOBU.Auto_Upgrade_AppsVersion.SendCommandUpdateApplication_Portal(String testIndex) in C:\AutoTest\AutoTestOBU\AutoTestOBU\Auto_Upgrade_AppsVersion.cs:line 463
   at AutoTestOBU.Auto_Upgrade_AppsVersion.DownloadOldUpdaterAndOnBoardAppsVersionsThenSendCommandToUpdateOnBoardApps_VerifyThatOldAndNewOnBoardVersionsAreDifferent() in C:\AutoTest\AutoTestOBU\AutoTestOBU\Auto_Upgrade_AppsVersion.cs:line 709
</StackTrace>
        </ErrorInfo>
      </Output>
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
      <ExtensionResult>Exception has been thrown by the target of an invocation.</ExtensionResult>
    </UnitTestResult>
    <UnitTestResult executionId="e7e39d89-00db-4e8f-a452-cd0c50352551" testId="ce14eba0-b7e1-4b8a-fc42-5cb800521cbf" testName="synchronizationTestResult" computerName="AUTOTEST1" duration="00:00:27.3562896" startTime="2016-08-12T03:16:05.1511973-05:00" endTime="2016-08-12T03:16:32.4524381-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="e7e39d89-00db-4e8f-a452-cd0c50352551">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="cece918e-d0a1-4d8b-a6e1-a9b116210537" testId="62991ca9-d372-983a-ec9b-09c949d9d44e" testName="LoginAsDriverAndVerifySettingsButtonIsDisable" computerName="AUTOTEST1" duration="00:01:01.7280335" startTime="2016-08-12T03:16:32.4524381-05:00" endTime="2016-08-12T03:17:34.0344562-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="cece918e-d0a1-4d8b-a6e1-a9b116210537">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="459d660e-16b5-4743-b169-6bf169f022d3" testId="335fad92-233f-e926-db2a-3683859a5a97" testName="LoginAsSysAdminAndVerifySettingsButtonIsEnable" computerName="AUTOTEST1" duration="00:00:58.5588067" startTime="2016-08-12T03:17:34.0344562-05:00" endTime="2016-08-12T03:18:32.4694399-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="459d660e-16b5-4743-b169-6bf169f022d3">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="3b775874-7872-41de-a490-b29ca4d8908d" testId="a1ccde85-662b-9ee1-d60a-8a6906d4ec9e" testName="LoginWithWrongPasswordAndVerifyErrorMessage" computerName="AUTOTEST1" duration="00:00:44.3281648" startTime="2016-08-12T03:18:32.4694399-05:00" endTime="2016-08-12T03:19:16.7264083-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="3b775874-7872-41de-a490-b29ca4d8908d">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="282ab4b6-6d62-42af-b601-dc4111bc210e" testId="b92bc9eb-ef99-ee1c-0780-20ca0972b13a" testName="ClickOnEmergencyButtonInOBUAndAcceptPopupMsgInPortal" computerName="AUTOTEST1" duration="00:02:47.9429740" startTime="2016-08-12T03:19:16.7264083-05:00" endTime="2016-08-12T03:22:04.7664569-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="282ab4b6-6d62-42af-b601-dc4111bc210e">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="d84725a2-1377-4014-9324-ddfef561aac9" testId="e48b1dc7-81d7-7603-ef8d-975a68e3ae81" testName="SelectAndSendMessageFromScrolDownOptionListFromMessageSendMessagePage" computerName="AUTOTEST1" duration="00:01:44.6618061" startTime="2016-08-12T03:22:04.7664569-05:00" endTime="2016-08-12T03:23:49.6917779-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="d84725a2-1377-4014-9324-ddfef561aac9">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="d3b507b1-8635-4b7e-a58f-5f16338fb91d" testId="0e842caa-b551-f574-1977-af66b1008750" testName="SendMessageFromViewVehiclesPage" computerName="AUTOTEST1" duration="00:01:52.4162213" startTime="2016-08-12T03:23:49.6917779-05:00" endTime="2016-08-12T03:25:42.4065159-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="d3b507b1-8635-4b7e-a58f-5f16338fb91d">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="7ef44d77-72f6-48f9-b3f4-c734a54df5ec" testId="308dc99f-dab3-4ca5-c904-47f93c35235a" testName="SendMessageToDispatch_BusBrokeDown" computerName="AUTOTEST1" duration="00:02:16.3699243" startTime="2016-08-12T03:25:42.4065159-05:00" endTime="2016-08-12T03:27:58.9283005-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="7ef44d77-72f6-48f9-b3f4-c734a54df5ec">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="6ec687ce-ef77-4663-983e-234cc56bc552" testId="60969a90-a9f5-0eee-9352-958101d70ba3" testName="TypeTextAndSendMessageFromMessageSendMessagePage" computerName="AUTOTEST1" duration="00:01:45.4448068" startTime="2016-08-12T03:27:58.9283005-05:00" endTime="2016-08-12T03:29:44.4760561-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="6ec687ce-ef77-4663-983e-234cc56bc552">
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
    <UnitTestResult executionId="c03bd2ab-79a1-456c-9e0b-52439f53162b" testId="763435b6-b5e4-9d6e-a97a-f9e6bbe34012" testName="synchronizationTestResult" computerName="AUTOTEST1" duration="00:00:56.5002873" startTime="2016-08-12T03:29:44.4760561-05:00" endTime="2016-08-12T03:30:40.7659483-05:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="c03bd2ab-79a1-456c-9e0b-52439f53162b">
      <Output>
        <StdOut>Synchronization result is:</StdOut>
      </Output>
      <ResultFiles>
        <ResultFile path="AUTOTEST1\UITestActionLog.html" />
      </ResultFiles>
    </UnitTestResult>
  </Results>
</TestRun>

Вот XSLT коде для преобразования:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
   
<h1 align="center">Test Results</h1>
    <table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
        <tr valign="top">
            <th style="text-align:center; font-weight:bold;" bgcolor="yellow">Total - Test Cases</th>
            <th style="text-align:center; font-weight:bold;" bgcolor="yellow">Pass</th>           
            <th style="text-align:center; font-weight:bold;" bgcolor="yellow">Fails</th>
            <th style="text-align:center; font-weight:bold;" bgcolor="yellow">Errors</th>
            <th style="text-align:center; font-weight:bold;" bgcolor="yellow">Success</th>          
        </tr>

<xsl:if test="//@error = '0' and //@failed = '0'"> 
<tr>
<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@total"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@passed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="00FF00">
<xsl:value-of select="//@failed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@error"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="format-number((//@total - //@failed - //@error) div //@total * 100,'#.00')"/> % </td>   
</tr>
</xsl:if>

<xsl:if test="//@error = '0' and //@failed > '0'"> 
<tr>
<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@total"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@passed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="FF0000">
<xsl:value-of select="//@failed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@error"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="format-number((//@total - //@failed - //@error) div //@total * 100,'#.00')"/> % </td>   
</tr>
</xsl:if>


<xsl:if test="//@error > '0' and //@failed = '0'"> 
<tr>
<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@total"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@passed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="00FF00">
<xsl:value-of select="//@failed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#FFA500">
<xsl:value-of select="//@error"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="format-number((//@total - //@failed - //@error) div //@total * 100,'#.00')"/> % </td>   
</tr>
</xsl:if>


<xsl:if test="//@error > '0' and //@failed > '0'"> 
<tr>
<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@total"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="//@passed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="FF0000">
<xsl:value-of select="//@failed"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#FFA500">
<xsl:value-of select="//@error"/> </td>

<td style="text-align:center; font-weight:bold;" bgcolor="#00FF00">
<xsl:value-of select="format-number((//@total - //@failed - //@error) div //@total * 100,'#.00')"/> % </td>   
</tr>
</xsl:if>
</table>







<h1 align="center" >Detail Test Result</h1>
<table border="0" cellpadding="2" cellspacing="0" width="95%" style="border: #dcdcdc 1px solid;">
<tr>
<td width="25%" bgcolor="yellow"><center><b>Test</b></center></td>                       
<td width="15%" align="left" bgcolor="yellow"><center><b>Result</b></center></td>
<td width="25%" align="left" bgcolor="yellow"><center><b>Error Details</b></center></td>  
</tr>
      
<xsl:for-each select="*/Results/UnitTestResult">
 <tr>
<xsl:if test=" @outcome ='Passed'">
 <td><xsl:value-of select="@testName"/></td>
 <td style="text-align:center; color: #228B22; font-weight:bold;"><xsl:value-of select="@outcome"/></td>
 <td><center> N/A </center></td>
</xsl:if>

<xsl:if test=" @outcome ='Failed'">
 <td><xsl:value-of select="@testName"/></td>
 <td style="text-align:center; color: red; font-weight:bold;"><xsl:value-of select="@outcome"/></td>
 <td><xsl:value-of select="substring-after(substring-after(Output/ErrorInfo/Message,'.'), '.')" /></td>
</xsl:if>
</tr>
</xsl:for-each>
</table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Первая таблица работает без проблем но вторая не как не получается.
Может проблема в for-each ?

Спасибо за помощь.