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

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

Ответы [ 3 ]

26 голосов
/ 15 апреля 2011

Моя собственная библиотека модульного тестирования, Unquote , использует F # кавычки , чтобы позволить вам записывать тестовые утверждения в виде простых, статически проверенных логических выражений 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 #, поэтому эквивалентное утверждение даже не скомпилируется, что не позволяет нам ввести ошибку в нашем тестеcode

[<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 # в качестве проверочных утверждений надFsUnit DSL заключается в том, что он очень хорошо подходит для процесса разработки модульных тестов в F #.Я думаю, что многие разработчики F # начинают с разработки и тестирования кода с помощью FSI.Следовательно, очень легко перейти от специальных тестов FSI к формальным тестам.Фактически, в дополнение к специальной поддержке xUnit и NUnit (хотя также поддерживается любая основанная на исключениях инфраструктура модульного тестирования), все операторы Unquote также работают в сеансах FSI.

3 голосов
/ 26 февраля 2012

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

Я думаю, что сочетание FsCheck и Unquote было бы идеальным.

1 голос
/ 17 ноября 2018

Вы можете попробовать Expecto ; в нем есть некоторые функции, которые вам могут понравиться:

  • F # синтаксис во всем, тесты как значения; написать простой F # для генерации тестов
  • Используйте встроенный модуль Expect или внешнюю библиотеку, например Unquote для утверждений
  • Параллельные тесты по умолчанию
  • Проверьте ваш код Hopac или ваш код Async; Expecto асинхронен на протяжении всего
  • Подключаемое ведение журнала и метрики через Logary Facade; легко написать адаптеры для систем сборки или использовать механизм синхронизации для построения панели мониторинга InfluxDB + Grafana по времени выполнения ваших тестов
  • Встроенная поддержка BenchmarkDotNet
  • Встроенная поддержка FsCheck; упрощает создание тестов с использованием сгенерированных / случайных данных или построение инвариантных моделей пространства состояний вашего объекта / субъекта

Привет, мир выглядит так

open Expecto

let tests =
  test "A simple test" {
    let subject = "Hello World"
    Expect.equal subject "Hello World" "The strings should equal"
  }

[<EntryPoint>]
let main args =
  runTestsWithArgs defaultConfig args tests
...