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

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

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

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

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

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

  • NaturalSpec
  • FsCheck
  • FsTest
  • FsUnit

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

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

open NUnit.Framework [] type myFixture() = class [] member self.myTest() = //test code end 

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

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

Страница FsCheck CodePlex

Страница регистрации FsCheck

Как предполагает 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 [] 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) 

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

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

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

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

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

  • Связать Vs Лямбда?
  • Каково точное определение замыкания?
  • Почему java.util.Collection не реализует новый интерфейс Stream?
  • Обработка инкрементного моделирования данных Изменения в функциональном программировании
  • Какова мотивация присвоения Scala для оценки Unit вместо присвоенного значения?
  • Функциональное реактивное программирование в Scala
  • Разница между сокращением и foldLeft / fold в функциональном программировании (в частности, Scala и Scala API)?
  • Возможно ли программирование графического интерфейса?
  • Зачем избегать подтипов?
  • В чем разница между def foo = {} и def foo () = {} в Scala?
  • Вычисление функции, которая принимает бесконечные аргументы
  • Давайте будем гением компьютера.