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

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


person GregC    schedule 14.04.2011    source источник
comment
См. также некоторые предложения здесь: stackoverflow .com/questions/1468772/   -  person Laurent    schedule 15.04.2011
comment
Нет времени на развернутый ответ, но IIRC вы также можете использовать Pex с F # (я даже однажды задал вопрос об этом). Мой текущий фаворит — Xunit.   -  person Benjol    schedule 15.04.2011
comment
Вы говорите, что Pex может генерировать код F#? Можете дать ссылку? Изначально я надеялся написать тестовый код на F#, чтобы тестировщики могли его читать.   -  person GregC    schedule 15.04.2011
comment
Здесь также были хорошие предложения: stackoverflow.com/questions/ 1989487/   -  person Mathias    schedule 17.04.2011


Ответы (3)


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

person Stephen Swensen    schedule 14.04.2011
comment
Я попробовал Unquote из-за всех голосов здесь, и через неделю я был убежден в этом. Пока что я нашел ценным: написание тестов в fsi, а затем перенос их в NUnit; интеграция с NUnit; строгая типизация тестовых выражений (Unquote нашел мой тест, который проходил случайно); утилиты котировок, такие как eval. Если у вас есть Nuget, то Unquote можно установить с помощью установочного пакета Unquote. - person Stephen Hosking; 16.12.2011

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

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

person Robert Jeppesen    schedule 25.02.2012
comment
Я еще не пробовал это сам, но я слышал, что FsCheck и Unquote действительно очень хорошо сочетаются друг с другом. - person Stephen Swensen; 11.12.2012

Вы можете попробовать мою библиотеку модульного тестирования 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
person Henrik    schedule 17.11.2018