лучший / наиболее эффективный способ тестирования XSLT

#xml #xslt

#xml #xslt

Вопрос:

Я работаю с большими и сложными словарными данными (XML), которые необходимо анализировать с помощью XSL и выводить XML.

что будет рассматриваться как «лучший» способ проверить, обрабатывает ли XSL все узлы из XML (ввода)?

пожалуйста, рассмотрите этот простой пример, я думаю, он будет отражать суть проблемы:

input.xml

 <?xml version="1.0" encoding="UTF-8"?>
<a>
   <b>
      <c>
         some1
         <d>text2</d>
         more text1
      </c>
   </b>
   <b>
      <c>
         some2
         <d>text2</d>
         more text2
      </c>
   </b>
   <d>text3</d>
   <e>
      text
      <d>4</d>
   </e>
</a>
  

некоторые tarnsformations.xsl

output.xml

 <?xml version="1.0" encoding="UTF-8"?>
<amodified>
   <bmodified>
      some1
      <dd>text2</dd>
      more text1
   </bmodified>
   <bmodified>
      some2
      <dd>text2</dd>
      more text2
   </bmodified>
   <dd>text3</dd>
   <ed>text</ed>
   <dd>4</dd>
</amodified>
  

В output.xml названия тегов были изменены, а также порядок содержимого (по сравнению с входным файлом).
Мне нужно сравнить, доступны ли все текстовые поля из ввода на выходе.
Я думаю, что лучшим решением было бы создать тест, который будет извлекать текст из каждого тега и сравнивать его строка за строкой, выводя теги, которые не существуют в output.xml в файл журнала … ?

Комментарии:

1. Вопрос без единого примера не является конструктивным. Что такое «лучший» и что такое «обработка всех узлов»? Я предполагаю, что простая обработка всех узлов — это не то, что должны проверять тесты. Как насчет «генерации правильных результатов»? Этот вопрос, как и было задано, имеет очень мало общего с XSLT и с тестированием. Пожалуйста, отредактируйте и улучшите.

Ответ №1:

Я бы рекомендовал два вида тестов: сначала модульный тест на меньшем контролируемом наборе данных, который должен быть моделью для данных, которые вы найдете в своем большом словаре. Это можно рассматривать как модульный тест для вашего процесса xslt. Обычно я извлекал несколько репрезентативных фрагментов из большего набора данных и сохранял их вместе с тестовым кодом. Затем тест применяет преобразование к тестовым данным и делает утверждения о результате, проверяя, что преобразование было успешно использовано.

Затем дополнительно вы должны встроить проверки работоспособности в свою производственную систему, чтобы (например) убедиться, что общее количество обработанных узлов соответствует ожидаемому. Например, в словаре с большим количеством записей вы можете выполнить один шаг для подсчета всех записей, а затем еще один для их обработки. Затем в конце посмотрите, сколько записей вы обработали, и убедитесь, что количество совпадает с тем, что вы ожидали. Это также полезно, поскольку предоставляет средство вывода индикатора выполнения (% завершения).

В любом случае, это то, что мы делаем.

Если текст на выходе совпадает с текстом на входе, как в вашем примере, Марчин, вы можете довольно легко сравнить их с помощью xslt. Если вы обрабатываете XML-файл с пустой таблицей стилей xslt (только <xslt:stylesheet /> узел), вы получите обратно только текст без разметки. Я думаю, что xmllint тоже может это сделать. Так что просто запустите это как для ввода, так и для вывода и сравните, используя простое сравнение текста (например, diff).

Комментарии:

1. @_Mike: Как правило, нет сопоставления 1: 1 между обрабатываемыми узлами и выводом узлов. Общее решение состоит в том, чтобы предоставлять отладочный вывод всякий раз, когда обрабатывается узел, чтобы можно было подсчитать «обработанные показатели» в конечном выводе.

2. @Dmitri — это правда; но во многих случаях вы могли бы посчитать количество ожидаемых выходных узлов и сравнить.

3. @_Mike: Да, но вопрос не в том, как проверить количество выходных узлов. Вопрос в том, как проверить, что каждый входной узел был обработан .

4. @Dmitri Да, я понимаю. Подход в вашем ответе заключается в создании некоторого специального вывода, который гарантированно создает один выходной узел на входной узел. Я предлагаю убедиться, что фактический результат соответствует ожиданиям, используя какое-то независимо вычисляемое свойство ожидаемого результата, например, подсчет количества выходных узлов — очень часто это может быть функцией правильной обработки всех входных данных. По общему признанию, это не всегда так, но особенно в словаре, состоящем в основном из списка записей, это, вероятно, будет хорошим подходом?

5. @_Mike: Чтобы ответить на ваш вопрос: даже если входные данные представляют собой словарь, если задача не требует создания соответствующего вывода для некоторых записей, в зависимости от определенных условий, то, просто проверяя выходные данные, мы не можем выяснить, был ли обработан каждый узел словаря или нет.

Ответ №2:

Можно использовать этот метод:

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output method="text"/>

 <xsl:template match="/*">
     <xsl:variable name="vrtfResults">
       <xsl:apply-templates select="num"/>
     </xsl:variable>

     <xsl:variable name="vProcessed" select=
     "count(ext:node-set($vrtfResults)/nodeProcessed)"/>

     <xsl:variable name="vAll" select="count(num)"/>

     <xsl:text>From the existing </xsl:text>
     <xsl:value-of select="$vAll"/>
     <xsl:text> amp;<num> elements </xsl:text>
     <xsl:value-of select="$vProcessed"/>
     <xsl:text> were processed.</xsl:text>
 </xsl:template>

 <xsl:template match="num">
  <nodeProcessed/>
  <num><xsl:value-of select="2*."/></num>
 </xsl:template>
</xsl:stylesheet>
  

при применении к следующему XML-документу:

 <nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>
  

получен желаемый результат:

 From the existing 10 <num> elements 10 were processed.
  

Объяснение:

  1. Для обработки каждого элемента был добавлен специальный элемент только для тестирования ( <nodeProcessed/> ) <num> .

  2. Мы фиксируем выходные данные в переменной, затем подсчитываем количество <nodeProcessed/> элементов и сравниваем их с общим количеством <num> элементов, которые должны быть обработаны.