简体   繁体   中英

F#'s Scaffold and FsUnit/FsCheck

I'm struggling to get started with F# on Linux using ProjectScaffold. Specifically: I can't get a project to work with FsUnit/FsCheck/xunit. I have F# 3.1 and mono 3.12.1 and I'm on Linux (Ubuntu) x64.

I start "MyProject" with:

$ git clone --depth=1 git@github.com:fsprojects/ProjectScaffold.git
$ cd ProjectScaffold && ./build.sh

Then I add a bit of code to "src/MyProject/Library.fs":

module MyProject.X

let four = 4

And then two tests to "tests/MyProject.Tests/Tests.fs":

module MyProject.Tests.X

open Xunit
open FsUnit.Xunit
open FsCheck
open FsCheck.Xunit
open MyProject.X

[<Fact>]
let ``Two plus two is four.`` () =
    2 + 2 |> should equal four

[<Property>]
let ``Sorting a sorted list is idempotent.`` (l: int list) =
    let s = List.sort l
    s = List.sort s

This code works on Visual Studio where I manually added FsCheck, FsUnit, anx xunit 1.9.2 (it fails with later version for some reason). My test project on Windows/Visual Studio has this config file:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="FsCheck" version="1.0.4" targetFramework="net45" />
  <package id="FsCheck.Xunit" version="1.0.4" targetFramework="net45" />
  <package id="FsUnit.xUnit" version="1.3.0.1" targetFramework="net45" />
  <package id="xunit" version="1.9.2" targetFramework="net45" />
  <package id="xunit.runner.visualstudio" version="2.0.0" targetFramework="net45" />
</packages>

So I edit paket.dependencies to add these packages and remove Nunit:

source https://nuget.org/api/v2

nuget FSharp.Formatting 2.8.0
nuget FSharpVSPowerTools.Core 1.7.0
nuget FAKE
nuget FsCheck 1.0.4
nuget FsCheck.Xunit 1.0.4
nuget FsUnit.xUnit 1.3.0.1
nuget xunit 1.9.2
nuget SourceLink.Fake

github fsharp/FAKE modules/Octokit/Octokit.fsx

Then:

$ mono .paket/paket.exe install

...and it fails because NUnit is referenced somewhere, so I delete the references in tests/MyProject.Tests/paket.references and

$ mono .paket/paket.exe install

works, but

$ ./build.sh

fails, at it cannot find references to FsCheck et al. So I assume that I need to add the references manually, so tests/MyProject.Tests/paket.references is now:

FsCheck
FsCheck.Xunit
FsUnit.xUnit
xunit

...built build.sh fails again: it cannot find FsCheck. I could not find in the paket doc how to add a local dependency (MyProject.Tests should reference MyProject), it might be done automatically.

I had this problem and it took a while for me to figure out a fix. For the project file in the Tests directory, I had to change this:

<Reference Include="FsUnit.NUnit">
    <HintPath>..\..\packages\FsUnit.1.3.0.1\Lib\Net40\FsUnit.NUnit.dll</HintPath>
    <Private>True</Private>
</Reference>

To this:

<Reference Include="FsUnit.NUnit">
    <HintPath>..\..\packages\FsUnit\Lib\Net40\FsUnit.NUnit.dll</HintPath>
    <Private>True</Private>
</Reference>

Similarly, for NUnit:

<Reference Include="nunit.framework">
  <HintPath>..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
  <Private>True</Private>
</Reference>

To:

<Reference Include="nunit.framework">
  <HintPath>..\..\packages\NUnit\lib\nunit.framework.dll</HintPath>
  <Private>True</Private>
</Reference>

The issue is that on mono, the packages don't have the version in the path but under Visual Studio they do. Once I found this fix, I created two .fsproj files for the tests and I modified the build.sh script to swap the mono-compatible one in when under mono via:

#!/bin/bash
if test "$OS" = "Windows_NT"
then
  # no changes in here
else
  # fix test fsproj file
  mv tests/ProjectName.Tests/ProjectName.Tests.fsproj tests/ProjectName.Tests/ProjectName.Tests.fsproj.vs
  mv tests/ProjectName.Tests/ProjectName.Tests.fsproj.mono tests/ProjectName.Tests/ProjectName.Tests.fsproj  

  # leave the script logic for mono in place

  # put project files back to avoid git noticing the swap
  mv tests/ProjectName.Tests/ProjectName.Tests.fsproj tests/ProjectName.Tests/ProjectName.Tests.fsproj.mono
  mv tests/ProjectName.Tests/ProjectName.Tests.fsproj.vs tests/ProjectName.Tests/ProjectName.Tests.fsproj

fi

Once I made these changes the project works fine under both Visual Studio as well as mono.

I am not quite sure, I understand you: Do you have two fsproj files, one for the production code and one for the unit tests? And are you referencing FsCheck in the fsproj?

Plus, I remember an issue, where if you compile against an older version of .net and reference an assembly compiled against a newer version of .net, it will behave as though there was no reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM