Функция конфиденциальности и юнит-тестирование Haskell

Как вы справляетесь с видимостью функций и модульным тестированием в Haskell?

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

Я думал об использовании {-# LANGUAGE CPP #-} а затем, окружив экспорт #ifdef:

{-# LANGUAGE CPP #-}

module SomeModule
#ifndef TESTING
( export1
, export2
)
#endif
where

Есть ли способ лучше?

2 ответа

Решение

Обычное соглашение состоит в том, чтобы разделить ваш модуль на открытую и закрытую части, т.е.

module SomeModule.Internal where

-- ... exports all private methods

а затем публичный API

module SomeModule where (export1, export2)

import SomeModule.Internal

Тогда вы можете импортировать SomeModule.Internal в тестах и ​​других местах, где важно получить доступ к внутренней реализации.

Идея состоит в том, что пользователи вашей библиотеки никогда не вызывают случайный частный API, но они могут использовать его, если знают, что делают (отладка и т. Д.). Это значительно повышает удобство использования вашей библиотеки по сравнению с принудительным скрытием частного API.

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

Для наглядности внешних функций вы разделяете библиотечные модули между разделом "Открытые модули" и разделом "Другие модули".

Другие вопросы по тегам