2011-12-17 3 views
7

Я написал конечный автомат для небольшой футбольной игры, в которой я сейчас работаю. Он предоставляет интерфейс для настройки FSM (в основном, его состояний и переходов). Для каждого состояния вы можете предоставить функции, которые будут запущены при входе и выходе или пока FSM останется в одном состоянии, эти функции затем возвратят некоторые сообщения. Он также обеспечивает реактивный интерфейс (Yampa), который дает изменяющееся во времени состояние и собирает сообщения, которые происходят со временем. Код находится здесь Data/FSM.hs.Haskell: Как протестировать (реактивный) FSM с помощью quickcheck?

Я ищу хороший подход для тестирования этого модуля. Поскольку он чист, я подумал о том, чтобы попробовать quickcheck. Я не знаком с быстрым чеком, поэтому любой совет будет оценен! Мое основное понимание до сих пор: можно было бы предоставить некоторые функции, которые будут создавать FSM более или менее случайным образом, а затем запускать некоторые (снова более или менее случайные) переходы на них. Но я не могу понять, как построить тест таким образом ...

+0

Ну, какие тесты вы хотите написать? Какие свойства или поведение необходимо проверить? –

+0

Ну, может быть, проблема в том, что я действительно не знаю ... Для чего-то простого типа «для каждого действительного fsm любой конечный список переходов приводит либо к состоянию« Nothing », либо к состоянию« Just s », где s - состояние в fsm ", ок. Но более сложные вещи, такие как «для каждого допустимого fsm и списка (изменяющихся во времени) переходов и восприятий, следует собирать каждую коллекцию сообщений по пути перехода», я не знаю, как это сделать. Я бы знал, как настроить для этого единичные тесты, но с помощью quickcheck я немного потерян. – martingw

+0

Ссылка мертва (https://patch-tag.com/r/martingw/Rasenschach/snapshot/current/content/pretty/Data/FSM.hs), и нет архива, который я могу найти – icc97

ответ

4

Прежде всего, QuickCheck, вероятно, лучше всего подходит для проверки общих общих свойств. Для произвольных данных какого-либо типа выполните некоторые операции, затем используйте предикат, чтобы гарантировать, что результат имеет некоторое свойство относительно ввода. То, что связано с точными деталями поэтапного поведения, может не так хорошо работать в этом стиле, и вы не должны чувствовать себя обязанным делать все в QuickCheck!

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

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

+0

Так что, наверное, лучше всего подходит сочетание: тест для конкретного результата для определенного fsm и ввода с HUnit для пошаговых ситуаций и quickcheck для более общих свойств? – martingw

+1

@martingw: Я думаю, что это лучший подход по умолчанию, да. Я уверен, что в Hackage есть вещи, которые предоставляют унифицированные тестовые жгуты для HUnit, QuickCheck и, возможно, другие вещи. Я бы предположил, что QuickCheck должен быть предпочтительным, когда это возможно, но он лучше всего работает, когда все, что вы тестируете, это то, что вы получаете от A до B, а не детали маршрута. –