Какие рамки модульного тестирования доступны для F #

Я ищу специально для фреймворков, которые позволяют мне использовать уникальные возможности языка. Я знаю FsUnit. Вы порекомендовали бы что-нибудь еще и почему?

Ответ 1

Моя собственная библиотека тестирования модулей, Unquote, использует F # quotations, чтобы вы могли писать утверждения теста как простые, статически проверенные логические выражения F # и автоматически генерировали приятные пошаговые сообщения об ошибках тестирования. Например, следующий неудачный тест xUnit

[<Fact>]
let ``demo Unquote xUnit support`` () =
    test <@ ([3; 2; 1; 0] |> List.map ((+) 1)) = [1 + 3..1 + 0] @>

выводит следующее сообщение об ошибке

Test 'Module.demo Unquote xUnit support' failed: 

([3; 2; 1; 0] |> List.map ((+) 1)) = [1 + 3..1 + 0]
[4; 3; 2; 1] = [4..1]
[4; 3; 2; 1] = []
false

        C:\File.fs(28,0): at Module.demo Unquote xUnit support()

FsUnit и Unquote имеют аналогичные задачи: позволить вам писать тесты по идиоматическому пути и создавать информационные сообщения об ошибках. Но FsUnit - это всего лишь небольшая обертка вокруг NUnit Constraints, создающая DSL, которая скрывает построение объекта за композиционными вызовами функций. Но это стоит дорого: вы теряете контроль статического типа в своих утверждениях. Например, в FsUnit

действует следующее:
[<Test>]
let test1 () =
    1 |> should not (equal "2")

Но с Unquote вы получаете все статические функции проверки типов F #, поэтому эквивалентное утверждение даже не компилируется, не позволяя нам вводить ошибку в нашем тестовом коде

[<Test>] //yes, Unquote supports both xUnit and NUnit automatically
let test2 () =
    test <@ 1 <> "2" @> //simple assertions may be written more concisely, e.g. 1 <>! "2"
    //           ^^^
    //Error 22 This expression was expected to have type int but here has type string

Кроме того, поскольку котировки способны захватывать больше информации во время компиляции относительно выражения утверждения, сообщения об ошибках намного богаче. Например, неудачное утверждение FsUnit 1 |> should not (equal 1) вызывает сообщение

Test 'Test.Swensen.Unquote.VerifyNunitSupport.test1' failed: 
  Expected: not 1
  But was:  1
    C:\Users\Stephen\Documents\Visual Studio 2010\Projects\Unquote\VerifyNunitSupport\FsUnit.fs(11,0): at FsUnit.should[a,a](FSharpFunc`2 f, a x, Object y)
    C:\Users\Stephen\Documents\Visual Studio 2010\Projects\Unquote\VerifyNunitSupport\VerifyNunitSupport.fs(29,0): at Test.Swensen.Unquote.VerifyNunitSupport.test1()

В то время как утверждение об отказе Unquote 1 <>! 1 вызывает следующее сообщение об ошибке (также обратите внимание на трассировку стека фильтра)

Test 'Test.Swensen.Unquote.VerifyNunitSupport.test1' failed: 

1 <> 1
false

    C:\Users\Stephen\Documents\Visual Studio 2010\Projects\Unquote\VerifyNunitSupport\VerifyNunitSupport.fs(29,0): at Test.Swensen.Unquote.VerifyNunitSupport.test1()

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

Другим важным преимуществом использования простых выражений F # в качестве утверждений теста над DSL FsUnit является то, что он отлично вписывается в процесс F # разработки модульных тестов. Я думаю, что многие разработчики F # начинают с разработки и тестирования кода с помощью FSI. Следовательно, очень легко перейти от специальных тестов FSI к формальным испытаниям. На самом деле, помимо специальной поддержки для xUnit и NUnit (хотя поддерживается также единая платформа тестирования на основе исключений), все операторы Unquote также работают в сессиях FSI.

Ответ 2

Я еще не пробовал Unquote, но я чувствую, что должен упомянуть FsCheck: http://fscheck.codeplex.com/ Это порт библиотеки QuickCheck от Haskells, где вместо того, чтобы указывать, какие конкретные тесты выполнять, вы указываете, какие свойства в вашей функции должны выполняться. Для меня это немного сложнее, чем использование традиционных тестов, но как только вы выясните свойства, у вас будут более прочные тесты. Читайте введение: http://fscheck.codeplex.com/wikipage?title=QuickStart&referringTitle=Home

Я бы предположил, что сочетание FsCheck и Unquote было бы идеальным.