Я специально ищу фреймворки, которые позволят мне воспользоваться уникальными возможностями языка. Мне известно о FsUnit. Могли бы вы порекомендовать что-то другое и почему?
Какие платформы модульного тестирования доступны для F#
Ответы (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.
Я еще не пробовал Unquote, но чувствую, что должен упомянуть FsCheck: http://fscheck.codeplex.com/ Это порт библиотеки Haskells QuickCheck, где вместо того, чтобы указывать, какие конкретные тесты выполнять, вы указываете, какие свойства вашей функции должны оставаться истинными. Для меня это немного сложнее, чем использование традиционных тестов, но как только вы разберетесь со свойствами, у вас будут более надежные тесты. Прочтите введение: http://fscheck.codeplex.com/wikipage?title=QuickStart&referringTitle=Home
Я думаю, сочетание FsCheck и Unquote было бы идеальным.
Вы можете попробовать мою библиотеку модульного тестирования 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