Anatoly Levenchuk (ailev) wrote,
Anatoly Levenchuk
ailev

Автоматизация тестов приёмки: к постановке задачи

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

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

Приёмка (валидация) -- это то, насколько собранная система (как целостная конструкция, работающий механизм) выполняет свои функции. Если автомобиль выполняет функцию безопасной доставки людей из А в Б, то доедет ли до Б, выехав из А, и выживут ли при этом перевозимые и окружающие люди? Приёмка -- это тестирование на предмет того, что решалась правильная задача, а не что задача решалась правильными методами. Ничего не знаем про правильность кода, проекта, учебного артефакта, но зато знаем, что именно нужно было сделать, и какие именно грабли нужно было при этом учесть.

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

В принципе, многие функции, особенно "ости" (ilities -- все эти "безопасности", "ремонтопригодности", "надёжности", "адаптивности", "гибкости" и т.д.) крайне трудно проверить. Поэтому используются хитрые способы типа включения в состав проектных моделей "инженерного обоснования" (assurance case -- тут case по аналогии с "судебным делом", как обоснованием для приговора) с явным указанием логических приёмов ("от противного", "перечисление всех возможных случаев", "проверка экспериментом", "субъективная оценка эксперта" и т.д.), используемых для доказательства обеспечения этих "остей". Из литературы по assurance case можно вычитать, что когда-то в комитетах по стандартизации схлестнулось много разных методов обеспечения доказательства этих "остей", но победил assurance case.

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

Это я просто в порядке восстановления контекста разговора про всяческие приёмки и проверки, это всё прелюдия.

Далее идёт пятиголосная фуга: я хотел бы как-то компактифицировать знание о методах приёмки -- ибо язык тут крайне разнится. Меня будут интересовать методы приёмки в:
-- программной инженерии (источник лучших на сегодня методов приёмки, из которых ожидается миграция в другие дисциплины и технологии)
-- учебной инженерии (приёмка как автоматизированная проверка результатов учебных заданий -- примером может служить современный КуМир и кейс проверки студенческих заданий от VivoMind)
-- системной инженерии (приёмка "железных" систем -- включая обеспечение compliance в той части, в какой речь идет не о предписании конструкции/механизма, а реализован подход по performance. Хотя ввиду необъятности системной инженерии мы предложим пока для рассмотрения только пример простейшей системы: физического робота).

Результатом мог бы быть модуль библиотеки справочных данных PraxOS (ага, модуль RDL в смысле ISO 15926), который помог бы компактно описывать лучшие на сегодня методы приёмки и мэппить описания методов приёмки разных дисциплин друг ко другу, тем самым помогая побыстрее осуществить миграцию лучших практик.

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

Пять голосов этой приёмной фуги (напомню: в фуге разные голоса ведут в основном или измененном виде одну и ту же мелодию -- её-то и нужно найти, и подобрать слова для ее выражения):

1. Нужно понять, в чём лучшие практики тестов приёмки в софте. На текущий момент приёмка выведена в отдельные специализированные продукты testware (test automation frameworks, http://en.wikipedia.org/wiki/Test_automation_framework -- только помним, что жизнь много богаче википедийной статьи!), которые:
-- определяют формат выражения ожиданий
-- каким-то образом ставят тестируемое приложение под свой контроль
-- выполняют тесты
-- выполняют аналитику для результатов тестирования (отчёты)

Начиналось всё с простых попыток определить подать что-то на вход приложений и прочитать выводы (чтобы сравнить с эталонными), второе поколение добавило скрипты для тестирования, третье поколение отделило данные тестирования от собственно скриптов (data-driven), четвертое поколение научилось генерировать сами скрипты (keyword-driven), пятое поколение уже насквозь гибридно и может включать всё что угодно (например, логику типа используемой в business rules).

Типичный пример современного testware -- RobotFramework (http://code.google.com/p/robotframework/), это keyword-driven.
Нужно бы поглядеть, что сейчас есть в университетских разработках.
И нужно понять, что можно сделать, если встраивать систему тестирования в язык/IDE, а не делать отдельный движок сбоку.

2. Если мы рассмотрим КуМир с возможностью проверки результатов работы, то:
-- в нём есть Миры, предполагающие действия Исполнителя в какой-то Обстановке;
-- ученик в каждой задаче должен писать алгоритмы для действий Исполнителя: в общем виде задаются Дано и Надо (формулируется функция алгоритма -- тут я использую слово "функция" как "то, что нужно сделать в данной Обстановке" в отличие от "конструкции", т.е. предложений по тому, как писать код. Никакого отношения к функциональному программированию!);
-- для каждой задачи определяется несколько (обычно от 5 до 12 даже для простых задач) разных тестовых Обстановок с прописанными в них конкретными вариантами Дано и Надо;
-- требуется, чтобы созданный учеником алгоритм мог работать во всех тестовых Обстановках, предлагаемых для этой задачи
-- может дополнительно контролироваться способ решения (конструкция), но только косвенно (например, можно считать перемещения нарисованного робота, чтобы отслеживать неэффективные алгоритмы с лишними перемещениями. Или проверять в каждой клетке счётчик закрасок, чтобы отслеживать неэффективные закраски. Но нельзя распознать код!).

Используемый язык -- смесь "пакетного программирования" в варианте группы "Аттик" (Обстановка, Мир, Исполнитель, Выполнитель и т.д.) и математического (Дано, Надо).

Очень интересно наблюдать, как программирует дитятко в такой среде. Сначала дитятко пытается пройти со своим алгоритмом каждый отдельный тест, и исправляемая ошибка одного теста неминуемо приводит к ошибке в другом тесте. Через некоторое время дитятко начинает решать любую задачу с того, что внимательно просматривает все обстановки -- и уже не так стремительно пытается исправлять ошибки "по месту", как в первое время, он пытается сохранить результаты в уже работающих тестовых Обстановках. Еще через некоторое время дитятко начинает "предугадывать" возможные тестовые Обстановки и сразу пишет все необходимые проверки и условия в код решения.

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

3. Всё это также нужно будет приложить и к ОнтоМиру (см. про .15926 trainer, http://dot15926.livejournal.com/23094.html). Тут (поскольку язык декларативный, и непонятно, что "исполняется" -- плюс само моделирование слишком субъективно, чтобы легко договориться о наборе задач и заведомо правильных ответах) уже существенно другая ситуация, и нужно уже много думать и изобретать.

4. В плане декларативных текстов для проверки хорошо бы учесть опыт VivoMind, где автомагиески проверяется правильность даже не декларативного кода, а нарратива. Построение проверяемого артефакта учеником присутствует, но не требуется его выражение в каком-то формальном исполняемом языке. Так, в примере рассматривается традиционный математический текст: http://www.jfsowa.com/talks/pursue.pdf, слайды 17-24.

5. Отдельно про системную инженерию я писать не буду, нам для разбирательства в проблеме пока и учебный физический робот сойдёт, проблема понятна и с ним.

Когда мы переходим к работе с физическим роботом (например, Lego Mindstorms NXT 2.0), то ситуация существенно ухудшается. Дело не в том, что на текущий момент у нас нет КуМира, который бы работал с физическим Роботом (хотя что-то в этом плане разработчиками КуМира и делается, но результат еще будет не скоро). Прямо сейчас есть, например, RobotC и еще десяток языковых сред с библиотеками управления тем же NXT 2.0. Не это отсутствие "стандартной учебной среды" главное, и не отсутствие учебных задач (их тьма -- и они формулируются независимо от языка программирования робота, ровно то, что нам нужно).

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

Конечно, нужно еще и правильно формулировать задачи, чтобы облегчить приёмку, нужно еще для этого правильно подбирать начальные и конечные Обстановки для каждой задачи. И учитывать, что один раз робот за секунду проезжает 680 градусов поворота правого колеса, а в другой раз вполне может проехать 674, это ведь не цифровой мир, и не прецизионное оборудование.

Намёки, впрочем, есть: так, RobotC имеет среду виртуальных роботов (http://www.robotc.net/download/rvw/) -- это очень похоже на моделеориентированную системную инженерию, когда сначала алгоритм начинает работать "в компьютерном мире", и только потом мы проходим изготовление, сборку и приёмку в физическом мире -- но это не означает, что проверять поведение робота в физическом мире не нужно!
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

  • 10 comments