[unit-testing] F # 개발 및 단위 테스트?

제 첫 번째 기능 언어 인 F #으로 막 시작했습니다. 저는 C #과 유사하게 작업 해 왔으며 F #이 코드 작성 방법을 다시 생각하게하는 방법을 많이 즐깁니다. 내가 조금 혼란스러워하는 한 가지 측면은 코드 작성 과정의 변화입니다. 저는 C #에서 수년 동안 TDD를 사용해 왔으며 현재 위치를 알 수있는 단위 테스트가 있다는 점에 감사드립니다.

지금까지 F #을 사용한 저의 프로세스는 일부 함수를 작성하고, “합리적으로”작동하는지 “합리적으로”확인 될 때까지 대화 형 콘솔로 재생하고, 조정 및 결합하는 것이 었습니다. 이것은 오일러 프로젝트와 같은 소규모 문제에서 잘 작동하지만 그렇게 큰 것을 만드는 것을 상상할 수 없습니다.

사람들은 어떻게 단위 테스트에 접근하고 F # 프로그램을위한 테스트 제품군을 구축합니까? TDD에 상응하는 것이 있습니까? 어떤 조언이나 생각이라도 감사합니다.



답변

테스트 기반 개발자는 F #과 같은 기능적 언어를 사용하는 편이 좋습니다. 결정적으로 반복 가능한 결과를 제공하는 작은 함수가 단위 테스트에 완벽하게 적합합니다. F # 언어에는 테스트 작성을 용이하게하는 기능도 있습니다. 예를 들어, Object Expressions . 인터페이스 유형을 입력으로 취하는 함수에 대한 가짜를 매우 쉽게 작성할 수 있습니다.

F #은 최고 수준의 개체 지향 언어이며 C #에서 TDD를 수행 할 때 사용하는 것과 동일한 도구와 트릭을 사용할 수 있습니다. 또한 F #으로 작성되었거나 특별히 작성된 몇 가지 테스트 도구가 있습니다.

Matthew Podwysocki는 기능적 언어의 단위 테스트에 대한 훌륭한 시리즈 를 썼습니다 . 밥 삼촌도 여기에 생각을 자극하는 기사를 썼다 .


답변

나는 NUnit을 사용하고 있으며 읽기가 어렵거나 쓰기가 번거롭지 않습니다.

open NUnit.Framework

[<TestFixture>]
type myFixture() = class

    [<Test>]
    member self.myTest() =
       //test code

end

내 코드는 F #과 다른 .Net 언어가 혼합되어 있기 때문에 기본적으로 동일한 방식으로 F #과 C #에서 유사한 구문으로 단위 테스트를 작성한다는 사실이 마음에 듭니다.


답변

한 번 봐 가지고 FsCheck , F #의 자동 테스트 도구를 기본적으로 하스켈의 QuickCheck의 포트입니다. 이를 통해 함수 나 메서드가 충족해야하는 속성의 형태로 프로그램 사양을 제공 할 수 있으며, 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

[<Fact>]
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 # 코드에서 내부적으로 만 사용할 수 있지만 공용 API의 일부로 노출 할 수없는 F #의 특정 기능이 있다는 것을 이해합니다. C #을 사용하면 uintCLS 규격이 아닌 것을 표현 (예 🙂 할 수 있으므로 사용하지 않습니다.


답변

FSUnit을 살펴볼 수 있습니다. 아직 사용하지는 않았지만 시도해 볼 가치가 있습니다. 예를 들어 F #에서 (네이티브) NUnit을 사용하는 것보다 확실히 낫습니다.


답변

파티에 조금 늦었음에도 불구하고 Mathias를 F #으로 환영하고 싶습니다. (아무것보다 늦었습니다;)) 내 단위 테스트 라이브러리 인 Expecto가 마음에 드실 수 있습니다.

Expecto에는 다음과 같은 몇 가지 기능이 있습니다.

  • F # 구문은 전체적으로 값으로 테스트됩니다. 일반 F #을 작성하여 테스트 생성
  • 내장 된 Expect 모듈을 사용하거나 어설 션을 위해 Unquote와 같은 외부 라이브러리를 사용하십시오.
  • 기본적으로 병렬 테스트
  • Hopac 코드 또는 비동기 코드를 테스트하십시오. 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

https://github.com/haf/expecto/