Search code examples
f#.net-coremstest

F#: How to include external test data in mstest unit tests


I want to test my code with some data defined in an external file. I tried the following:

namespace blub

open System
open Microsoft.VisualStudio.TestTools.UnitTesting

[<TestClass>]
type TestClass () =

    [<TestMethod>]
    member this.TestMethodPassing () =
        let txt = System.IO.File.ReadAllText "data.txt"
        Assert.IsTrue(txt.Contains "Hello");

I just created the project with dotnet new mstest -lang F# and put the data.txt file next to the Test.fs file.

project files

However, when I run the tests with dotnet test I get the following error:

Failed   TestMethodPassing
Error Message:
 Test method blub.TestClass.TestMethodPassing threw exception:
System.IO.FileNotFoundException: Could not find file '/home/peter/Desktop/blub/bin/Debug/netcoreapp2.1/data.txt'.
Stack Trace:
    at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
   at System.IO.File.InternalReadAllText(String path, Encoding encoding)
   at System.IO.File.ReadAllText(String path)
   at blub.TestClass.TestMethodPassing() in /home/peter/Desktop/blub/Tests.fs:line 11

I can of course fix this by changing the path to "../../../data.txt", but this does not seem like a stable solution -- I did not find any documentation that states how test execution affects the current directory.

Can I somehow declare my test file as a resource to be copied to the correct folder?


Solution

  • You will need to add the data.txt file to the fsproj and set it to copy to the output folder:

    <ItemGroup>
      <Content Include="data.txt">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </Content>  
    </ItemGroup>
    

    If it still isn't found, you may you need to use the [<DeploymentItem("data.txt")>] against the TestClass.

    This will copy the files from the output folder to the folder where the tests are executed.