Подтвердить что ты не робот

Каковы некоторые стратегии тестирования крупных государственных машин?

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

  • Enum: Текущее состояние (так 0 → 30)
  • Enum: source (в настоящее время только 2 записи)
  • Boolean: Request
  • Boolean: Тип
  • Enum: Status (3 состояния)
  • Перечисление: обработка (3 состояния)
  • Boolean: завершено

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

[Subject("Application Process States")]
public class When_state_is_meeting2Requested : AppProcessBase
{
    Establish context = () =>
    {
        //Setup....
    };

    Because of = () => process.Load(jas, vac);

    It Current_node_should_be_meeting2Requested = () => process.CurrentNode.ShouldBeOfType<meetingRequestedNode>();
    It Can_move_to_clientDeclined = () => Check(process, process.clientDeclined);
    It Can_move_to_meeting1Arranged = () => Check(process, process.meeting1Arranged);
    It Can_move_to_meeting2Arranged = () => Check(process, process.meeting2Arranged);
    It Can_move_to_Reject = () => Check(process, process.Reject);
    It Cannot_move_to_any_other_state = () => AllOthersFalse(process);
}

Никто не уверен, какой должен быть выход для каждого состояния и набора входов. Я начал писать тесты для этого. Однако мне нужно написать что-то вроде тестов 4320 (30 * 2 * 2 * 2 * 3 * 3 * 2).

Какие предложения у вас есть для проверки состояния машин?


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

4b9b3361

Ответ 1

Я вижу проблему, но я определенно попытаюсь разделить логику.

Большая проблемная область в моих глазах:

  • Он имеет 31 возможное состояние.
  • Он имеет следующие входы:
    • Enum: Текущее состояние (так 0 → 30)
    • Enum: source (в настоящее время только 2 записи)
    • Boolean: Request
    • Boolean: type
    • Enum: Status (3 состояния)
    • Перечисление: обработка (3 состояния)
    • Boolean: завершено

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

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

Тестирование устаревшего кода

Отъезд Pex. Вы утверждаете, что унаследовали этот код, поэтому на самом деле это не Test-Driven-Development. Вы просто хотите, чтобы модульные тесты охватывали каждый аспект. Это хорошо, поскольку любая дальнейшая работа будет проверена. Я лично лично не использовал Pex, но я был поражен видео, которое я видел. По существу, он будет генерировать модульные тесты на основе ввода, который в этом случае будет конечным автоматом. Он будет генерировать тестовые примеры, о которых вам не о чем подумать. Конечно, это не TDD, но в этом случае, тестируя устаревший код, он должен быть идеальным.

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

Ответ 2

Сколько тестов, по вашему мнению, необходимо для "полной" проверки функции sum (int a, int b)? В С# это будет что-то вроде 18446744056529682436 тестов... Намного хуже, чем в вашем случае.

Я бы предложил следующее:

  • Проверьте наиболее возможные ситуации, граничные условия.
  • Проверьте некоторые критические части вашего SUT отдельно.
  • Добавить тестовые примеры, когда ошибки найдены в QA или в производстве.

В этом конкретном случае лучший способ - проверить, как система переключается из одного состояния в другое. Создайте DSL для проверки состояния машины и использования наиболее часто используемых случаев использования. Например:

Start
  .UploadDocument("name1")
  .SendDocumentOnReviewTo("user1")
  .Review()
  .RejectWithComment("Not enough details")
  .AssertIsCompleted()

Пример создания простых тестов для потоков приведен здесь: http://slmoloch.blogspot.com/2009/12/design-of-selenium-tests-for-aspnet_09.html

Ответ 3

Я построил машину конечного состояния для части медицинского оборудования. FSM настраивался через формат XML, который я определил.

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

Вы должны использовать то, что я называю переходной картой. На Восточном побережье Соединенных Штатов большинство автомагистралей называют променами. Власти Тернпайка выпускают карту тарифов с платной оплатой. Если в платной секции было 50 выходов, карта ценообразования имела бы таблицу 50rows x 50cols, содержащую исчерпывающие списки как строки и столбцы. Чтобы узнать плату за вход для выхода 20 и выйти из выхода 30, вы просто ищете пересечение строк 20 и столбца 30.

Для конечного автомата из 30 состояний карта перехода на магистраль будет представлять собой матрицу размером 30 х 30, в которой перечислены все 30 возможных состояний строк и столбцов. Выберем строки, которые будут состоять из состояний CURRENT и столбцов, в состояние NEXT.

Каждая пересекающаяся ячейка перечислит "цену" перехода из состояния CURRENT (строка) в состояние NEXT (col). Однако вместо одного значения $ячейка будет ссылаться на строку в таблице Inputs, которую мы могли бы назвать идентификатором перехода.

В разработанном нами медицинском оборудовании FSM были введены значения, которые представляют собой String, enums, int и т.д. В таблице Inputs перечислены эти входные стимулы по столбцам.

Чтобы построить таблицу Inputs, вы должны написать простую процедуру для перечисления всех возможных комбинаций входов. Но таблица была бы огромной. В вашем случае таблица будет содержать 4320 строк и, следовательно, 4320 идентификаторов перехода. Но это не утомительный стол, потому что вы создавали таблицу программно. В моем случае я написал простой JSP, чтобы перечислить таблицу ввода переходов (и таблицу маршрутизации) в браузере или загрузить как csv для отображения в MS Excel.

В построении этих двух таблиц существует два направления.

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

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

Вы хотите, чтобы подпрограмма циклически изменяла все 4320 строк входов, которые она считывает из таблицы Inputs, чтобы гарантировать, что неиспользуемые переходные идентификаторы не влияют на состояние CURRENT. Вы хотите проверить, что все эффективные переходы являются действительными переходами.

Но вы не можете - потому что после того, как будет осуществлен эффективный переход, он изменит состояние машины в состояние NEXT и не позволит вам завершить тестирование остальных идентификаторов перехода в предыдущем состоянии CURRENT. После того, как машина изменит состояние, вам нужно снова начать тестирование с перехода id 0.

Пути перехода могут быть циклическими или необратимыми или иметь комбинацию циклических и необратимых секций вдоль пути.

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

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

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

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

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

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

Для java-списка конечного контроллера конечной машины http://code.google.com/p/synthfuljava/source/browse/#svn/trunk/xml/org/synthful. Тестовые процедуры не включены.

Ответ 4

Тестирование всех пар

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

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

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

Пример файла модели Pict

Данная модель генерирует 93 тестовых экрана, охватывающих все пары входных параметров.

#
# This is a PICT  model for testing a complex state machine at work 
#

CurrentState  :0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
Source        :1,2
Request       :True, False
Type          :True, False
Status        :State1, State2, State3
Handling      :State1, State2, State3
Completed     :True,False

#
# One can add constraints to the model to exclude impossible 
# combinations if needed.
#
# For example:
# IF [Completed]="True" THEN CurrentState>15;
#

#
# This is the PICT output of "pict ComplexStateMachine.pict /s /r1"
#
# Combinations:    515
# Generated tests: 93

Ответ 5

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

Грубая сила: Напишите что-то, что будет генерировать все 4320 тестовых случаев в некоторых декларативных манерах, в основном с неверными данными. Я бы рекомендовал поместить это в CSV файл, а затем использовать что-то вроде параметрического тестирования NUnits для загрузки всех тестовых примеров. В настоящее время большинство из этих тестовых случаев не удастся, поэтому вам придется обновлять декларативный файл вручную, чтобы быть правильным, и произвольно произвольно выборку случайных случаев для исправления.

Техника машинного обучения: Вы могли бы использовать некоторые векторные машины или алгоритмы/эвристики MDA, чтобы попытаться изучить пример, который вы взяли из того, что мы упоминали выше, и научить вашу программу ML вашим FSM. Затем запустите алгоритм на всех входах 4320 и посмотрите, где эти два не согласны.

Ответ 7

Тестирование на основе требований. Если требуется определенное состояние для перехода в какое-либо другое состояние, когда Completed is true, тогда напишите тест, который автоматически циклически перебирает все комбинации других входов (это должно быть только пара для циклов), чтобы доказать, что другие входы правильно проигнорировано. Вы должны получить один тест для каждой дуги перехода, который я бы оценил где-то порядка 100 или 150 тестов, а не 4000.

Ответ 8

Вы можете рассмотреть возможность исследования Тестирование на основе модели. Есть несколько инструментов, которые могут помочь в генерации тестов в таких ситуациях. Обычно я рекомендую MBT.

Ответ 9

Грубая сила с проверками покрытия кажется очень началом.