Я только что запустил новый проект Haskell и хотел настроить хороший рабочий процесс тестирования с начала. Кажется, что у Haskell есть много превосходных и уникальных инструментов тестирования и многих различных способов интегрировать их.
Я изучил:
Который все, кажется, работают очень хорошо в их доменах, но я ищу комплексный подход к тестированию и задавался вопросом, что работало хорошо на других людей.
Чтобы получить правильное модульное тестирование, покрытие кода и тесты производительности, нужно в основном выбрать правильные инструменты.
Я буду использовать в качестве рабочего примера пакет, который я только что начал использовать с модульным тестированием, покрытием кода и тестами:
http: // github.com / ekmett / speculation
Вы можете интегрировать свои тесты и эталонные тесты прямо в свой файл cabal, добавляя для них разделы и маскируя их за флагами, чтобы они не делали этого так, чтобы каждый пользователь вашей библиотеки имел доступ (и хотят использовать для себя) точную версию выбранных вами инструментов тестирования.
http://github.com/ekmett/speculation/blob/master/speculation.cabal
Затем вы можете сообщить Cabal о том, как запустить свой набор тестов. Поскольку тест Кабала еще не существует - у нас есть студент, работающий над ним на лето кода в этом году! - лучший механизм, который у нас есть, это Вот как использовать механизм ловушки пользователя Кабала. Это означает переключение на «кастомную» сборку с Cabal и настройку testHook. Пример testHook, который запускает тестовую программу, написанную с помощью test-framework, а затем применяет hpc к профилю, можно найти здесь:
http://github.com/ekmett/speculation/blob/master/Setup.lhs
И затем вы можете использовать test-framework для объединения тестов QuickCheck и HUnit в одну программу:
http://github.com/ekmett/speculation/blob/master/Test.hs
Файл Кабала следует осторожно включить -fhpc, чтобы включить тестирование покрытия кода, а затем testHook в Setup.lhs вручную запускает hpc и записывает свои выходные данные в ваш каталог dist.
Что касается бенчмаркинга, история немного больше ручная, здесь нет опции «бенчмарк Кабала». Вы можете связать свои тесты производительности с вашим тестовым крючком, но мне нравится запускать их вручную, поскольку Criterion имеет так много опций графической отчетности.Вы можете добавить свои тесты производительности в файл Кабала, как показано выше, присвоить им отдельные флаги компиляции, скрыть их за флагом Кабала, а затем использовать Criterion для выполнения всей тяжелой работы:
http://github.com/ekmett/ speculation / blob / master / Benchmark.hs
Затем вы можете запускать тесты из командной строки и получать всплывающие окна KDE с результатами тестов и т. д.
Поскольку на практике вы все равно живете в клике во время разработки Код на Haskell имеет большой смысл интегрировать с ним вашу инструментальную цепочку.
Править : Теперь существует поддержка тестирования Кабала. См. http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/developing-packages.html#test-suites
Этот подход пропагандируется в RWH ch 11 и в XMonad приблизительно:
После того, как ваши основные инварианты установлены с помощью QuickCheck, вы можете начать рефакторинг, переведя эти тесты в инварианты типов.
Способы поддержки ваших усилий:
Пакет тестовой среды действительно великолепен. Вы можете легко интегрировать тесты HUnit и QuickCheck и получать исполняемые файлы, которые запускают только указанные наборы, на основе флагов командной строки, с несколькими целевыми объектами вывода.
Однако тестирование и профилирование - разные вещи. Для профилирования я бы создал отдельный исполняемый файл, который подчеркивает только тот раздел, который вы хотите профилировать, и просто внимательно просматривает результаты профилирующих сборок и запусков (с -prof-auto-all для компиляции и + RTS -p для среды выполнения флаг).
При тестировании я полагаюсь на свойства HUnit и QuickCheck и использую Haskell Test Framework для автоматического сбора всех модульных тестов и всех свойств QuickCheck.
Отказ от ответственности: Я являюсь основным разработчиком Haskell Test Framework.