Как заставить NUnit запускать тесты F#, не экспортируемые модулем
Я написал большой модуль в F#, который имеет тривиальный интерфейс. Модуль содержит около 1000 строк кода, 50 модульных тестов и экспортирует только одну легко понятную функцию.
естественно, что дальше нужно написать крошечный файл fsi. Это имеет многочисленные преимущества, включая предотвращение загрязнения пространства имен, предоставление очевидного места для документации, гарантируя, что если кто-то решит повторно использовать внутренние компоненты, у них будет стимул к чистоте учитывайте их и, без сомнения, многих других. Я уверен, что я проповедую хору здесь, но все же чувствовал, что стоит объяснить, почему я чувствую, что полезно иметь файл fsi.
теперь проблема. Нанит не запускать модульные тесты больше, recalcitrantly утверждая, что они не являются публичными. Ну, это было бы потому, что они никоим образом не являются частью интерфейса. Я не особенно хочу добавлять их в интерфейс, несмотря на это, видя, как это будет означать обновление его каждый раз, когда я добавил еще один тест, а также то, что он будет раздуваться файл fsi на порядок.
Я полагаю, что тривиальным обходным путем является перемещение кода в другое место, импорт его в крошечный .FS файл, и просто переслать одну функцию. Если повезет, все согласятся, что это просто отвратительно. Есть ли лучший способ, пожалуйста?
Edit: большое спасибо всем, кто ответил. Я повторил оба ответа. Я хотел бы разделить щедрость, однако, поскольку это не похоже на возможно, я (несколько произвольно) приму ответ Томаса.
2 ответов
если вы добавляете fsi
file чтобы указать видимость модулей и функций в вашем источнике, вам нужно будет включить объявления всех функций, которые должны быть общедоступными. Это означает, что если NUnit требует, чтобы тесты были общедоступными функциями, вам нужно будет включить их в .
однако есть и другой способ указать видимость в F# - вместо использования fsi
файл, вы можете просто добавить соответствующие модификаторы видимости в свой декларативные заявления. Таким образом, вы можете скрыть все детали реализации и экспортировать только основную функцию и тесты:
namespace MyLibrary
open NUnit.Framework
// Implementation details can be in this module
// (which will not be visible outside of the library)
module private Internal =
let foo n = n * 2
let bar n = n + 1
// A public module can contain the public API (and use internal implementation)
module public MyModule =
open Internal
let doWork n = foo (bar n)
// To make the tests visible to NUnit, these can be placed in a public module
// (but they can still access all functions from 'Internal')
module public Tests =
open MyModule
[<Test>]
let ``does work for n = 1``() =
Assert.Equals(doWork 1, 4)
по сравнению с использованием fsi
files, это имеет тот недостаток, что у вас нет отдельного файла, который хорошо описывает только важные части вашего API. Однако вы получите то, что вам нужно - скрыть детали реализации и предоставить только одну функцию и тесты.
подход
вы можете прибегнуть к использованию отражения для вызова ваших частных методов тестирования: у вас будет один общедоступный метод тестирования NUnit, который выполняет цикл над всеми частными методами в сборке, вызывающей те, у которых есть атрибут Test. Большой недостаток этого подхода заключается в том, что вы можете видеть только один неудачный метод тестирования за раз (но, возможно, вы могли бы изучить что-то творческое, например, использование параметризованных тестов для исправления этот.)