F # разработка и модульное тестирование?

Я только что начал с F #, который является моим первым функциональным языком. Я работаю квази-исключительно с С#, и наслаждаюсь тем, как F # заставляет меня передумать, как я пишу код. Один из аспектов, который я нахожу немного дезориентирующим, - это изменение в процессе написания кода. Я использую TDD в течение многих лет на С#, и действительно ценю, чтобы модульные тесты знали, где я нахожусь.

До сих пор мой процесс с F # заключался в том, чтобы писать некоторые функции, играть с ними с помощью интерактивной консоли, пока я не "разумно" уверен, что они работают, а также настраивают и объединяют. Это хорошо работает на мелкомасштабных проблемах, таких как проект Эйлера, но я не могу себе представить, чтобы что-то было таким большим.

Как люди подходят к модульному тестированию и созданию набора тестов для программы F #? Есть ли эквивалент TDD? Любые указатели или мысли оценены.

Ответ 1

Разработчики, основанные на тестах, должны чувствовать себя как дома в функциональных языках, таких как F #: небольшие функции, которые дают детерминистически повторяемые результаты, отлично подходят для модульных тестов. Существуют также возможности на языке F #, которые облегчают запись тестов. Возьмем, к примеру, Объектные выражения. Вы можете очень легко писать подделки для функций, которые принимают в качестве входных данных тип интерфейса.

Если что-либо, F # - это первоклассный объектно-ориентированный язык, и вы можете использовать те же инструменты и трюки, которые вы используете при выполнении TDD на С#. Существуют также некоторые инструменты тестирования, написанные или специально для F #:

Мэтью Подвиски написал большую серию для модульного тестирования на функциональных языках. Дядя Боб также написал статью здесь.

Ответ 2

Я использую NUnit, и мне не кажется, что это трудно читать или обременительно писать:

open NUnit.Framework

[<TestFixture>]
type myFixture() = class

    [<Test>]
    member self.myTest() =
       //test code

end

Поскольку мой код представляет собой сочетание F # и других языков .Net, мне нравится тот факт, что я пишу модульные тесты в основном таким же образом и с похожим синтаксисом как в F #, так и в С#.

Ответ 3

Посмотрите FsCheck, инструмент автоматического тестирования для F #, в основном порт Haskell QuickCheck. Это позволяет вам специфицировать программа, в виде свойств, которые функции или методы должны удовлетворяют, а FsCheck проверяет, что свойства сохраняются в большом количестве случайно сгенерированные случаи.

Страница FsCheck CodePlex

Страница авторизации FsCheck

Ответ 4

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

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

Одной из основных преимуществ .NET является возможность перекрестного языка. Я знаю, что скоро буду писать производственный код F #, но мой план - написать модульные тесты на С#, чтобы облегчить мне путь к тому, что для меня новый язык. Таким образом, я также проверю, что то, что я пишу в F #, будет совместимо с С# (и другими языками .NET).

При таком подходе я понимаю, что есть некоторые функции F #, которые я могу использовать только внутри своего кода F #, но не раскрывать их как часть моего публичного API, но я соглашусь с этим, так же, как я принимаю сегодня, это некоторые вещи, которые С# позволяет мне выражать (например, uint), которые не соответствуют требованиям CLS, и поэтому я воздерживаюсь от их использования.

Ответ 5

Как говорит dglaubman, вы можете использовать NUnit. xUnit.net также обеспечивает поддержку этого и хорошо работает с TestDriven.net. Код похож на тесты NUnit, но без требования обернуть тест в содержащем типе.

#light

// Supply a module name here not a combination of module and namespace, otherwise
// F# cannot resolve individual tests nfrom the UI.
module NBody.DomainModel.FSharp.Tests

open System
open Xunit

open Internal

[<Fact>]
let CreateOctantBoundaryReordersMinMax() =
    let Max = VectorFloat(1.0, 1.0, 1.0)
    let Min = VectorFloat(-1.0, -1.0, -1.0)

    let result = OctantBoundary.create Min Max

    Assert.Equal(Min, result.Min)     
    Assert.Equal(Max, result.Max) 

Ответ 6

Вы могли бы взглянуть на FSUnit - хотя я еще не использовал его, это может стоить попробовать. Конечно, лучше, чем использовать, например, (native) NUnit в F #.