Тестирование софта - статьи
ce076b8f

Универсальное расширение языков программирования


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

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

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

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

В качестве примера мы рассмотрим спецификации функции, вычисляющей квадратный корень. Спецификации на расширениях различных языков программирования приводятся в левом столбце таблиц, представленных ниже. В правом столбце даются краткие пояснения, касающиеся структуры спецификаций.

Java
specification package example; class SqrtSpecification { specification static double sqrt ( double x ) reads x, epsilon { pre { return x >= 0; } post { if(x == 0) { branch "Zero argument"; return sqrt == 0; } else { branch "Positive argument";

return sqrt >= 0 && Math.abs((sqrt*sqrt-x)/x)
Декларация
пакета Декларация класса Сигнатура операции Описание доступа
на чтение/запись Предусловие Постусловие Определение ветви
функциональности Ограничения
на результат Определение ветви
функциональности Ограничения
на результат
C#
namespace Examples { specification class SqrtSpecification { specification static double Sqrt ( double x ) reads x, epsilon { pre { return x >= 0; } post { if(x == 0) { branch ZERO ("Zero argument"); return $this.Result == 0; } else { branch POS ("Positive argument"); return $this.Result >= 0 && Math.Abs( ($this.Result * $this. Result - x)/x) < epsilon; } } } } } Декларация
пространства имен Декларация класса Сигнатура операции Описание доступа
на чтение/запись Предусловие Постусловие Определение ветви
функциональности Ограничения
на результат Определение ветви
функциональности Ограничения
на результат
C
specification double SQRT ( double x ) reads x, epsilon { pre { return x >= 0.; } coverage BRANCHES { if(x == 0) return(ZERO, "Zero argument"); else return(POS, "Positive argument"); } post { if(coverage(BRANCHES)==ZERO) return SQRT == 0.; else return SQRT >= 0. && abs((SQRT*SQRT - x)/x) < epsilon; } } } Сигнатура операции Описание доступа
на чтение/запись Предусловие Описание
структуры тестового
покрытия Определение ветви
функциональности Определение ветви
функциональности Постусловие Ограничения
на результат Ограничения
на результат


Содержание раздела