This post is a slightly shorter follow on post to my last one, F# Has Won Me Over: Coming to .Net World from Outside .Net
In that post, I showed how to set up a basic F# development workflow using Visual Studio Code. It probably seemed a little overkill just to get simple tests up and running.I’m glad I took this longer approach though as, coming into .NET world, it made me aware of how the tools and F# projects fit together under the hood – something that wouldn’t be as clear if I went the all out IDE approach.
Since publishing that blog, I have gotten a lot of really helpful feedback from others in the F# community and I have taken a look at an F# testing tool called Expecto
The Ionide plugin for Visual Studio Code has a really nice integration for running tests using Expecto – it’s a whole lot simpler then the workflow I showed in my last post!
Following from my last post, lets add a different test project to test the MusicLibrary project and we’ll use Expecto this time to run our test.
Again, I’m running Visual Studio Code on Mac OSX in this example but the steps should be more or less the same for other operating systems.
So, back in Visual Studio Code, type cmd-shift-p to open the command palette
Type F# and select F#:New Project
Choose a console as this will give us a main entry point for Expecto to run tests.
You will be prompted for the name of the project directory.
Lets just call it MusicLibraryExpectoTests
You will then be prompted for the name of the project.
Again, MusicLibraryExpectoTests will be grand.
Now we need to add our Expecto dependencies with Paket.
So open up the newly creted MusicLibraryExpectoTests directory and open MusicLibraryExpectoTests.fsproj
Open the command palette again, cmd-shift-p
Type Paket and select Paket:Add NuGet Package (to current project)
Then type Expecto and Enter.
You will see, info in the Paket output terminal.
Afterwards, you should be able to search Expecto in the MusicLibraryExpectoTests.fsproj file and find something like
After all this, our paket.references file within the MusicLibraryExpectoTests project should contain
FSharp.Core Expecto Expecto.BenchmarkDotNet Expecto.FsCheck
Lets try out a hello world expecto test. So, open up MusicLibraryExpectoTests.fs which will have automatically been created for us when we created our MusicLibraryExpectoTests project.
Replace the contents of that file with the following:
module MusicLibraryExpectoTests open Expecto [<Tests>] let tests = testCase "yes" <| fun () -> let subject = "Hello World" Expect.equal subject "Hello world" "The strings should equal" [<EntryPoint>] let main args = runTestsInAssembly defaultConfig args
Here we have added one test case and a main function as an entry point for expecto to run our tests.
We can easily run our test simply as follows:
Open command palette, cmd-shift-p
Type Ex and choose Expecto:Run
In the expecto output terminal, we can see our failing test!
We can fix our failing test by changing that ‘w’ to upper case so our MusicLibraryExpectoTests.fs becomes:
module MusicLibraryExpectoTests open Expecto [<Tests>] let tests = testCase "yes" <| fun () -> let subject = "Hello World" Expect.equal subject "Hello World" "The strings should equal" [<EntryPoint>] let main args = runTestsInAssembly defaultConfig args
This time to run the tests, lets just use a shortcut, ctrl-f6
Now, our test passes and you should see this along with other output in the Expecto terminal output in Visual Studio Code:
[21:28:12 INF] EXPECTO?! Summary... Passed: 1 yes Ignored: 0 Failed: 0 Errored: 0
Now, we can use Expecto to test our addSongToLibrary function from the MusicLibrary project that I went through in my last post.
We need to link our MusicLibraryExpectoTests project to this library first. So, open the MusicLibraryExpectoTests.fsproj file again.
Then we can use the command palette, cmd-shift-p to add a project reference.
Choose MusicLibraryExpectoTests for the project to edit
and MusicLibrary as the project to reference
Your MusicLibraryExpectoTests.fsproj should now contain something like
We can add our test for addSongToLibrary to MusicLibraryExpectoTests.fs as follows:
module MusicLibraryExpectoTests open Expecto open MusicLibrary [<Tests>] let tests = testList "test group" [ testCase "yes" <| fun _ -> let subject = "Hello World" Expect.equal subject "Hello World" "The strings should equal" testCase "addSongToLibrary adds song to library" <| fun _ -> let expected = ["Sir Duke";"Superstition"] Expect.equal expected (addSongToLibrary ["Superstition"] "Sir Duke") "The library list should contain the new song" ] [<EntryPoint>] let main args = runTestsInAssembly defaultConfig args
Now, we can run the tests with ctrl-F6
And in the Expecto terminal output in Visual Studio code,
you should see something like this along with other output
Passed: 2 test group/yes .... .... test group/addSongToLibrary adds song to library [/Users/tom/Dropbox/software- Ignored: 0 Failed: 0 Errored: 0
There is a lot more you can do with Expecto. I have just scratched the surface here but, even with the basics here, you can very quickly create and run test cases from within Visual Studio Code. It’s definitely a tool that I will be using a lot!