Conversation
|
|
||
| let mutable internal colours = None | ||
| let internal setColourLevel c = if colours.IsNone then colours <- Some c | ||
| let internal setColourLevel c = colours <- Some c |
There was a problem hiding this comment.
I couldn't discern a reason this needed to be settable only once, and it prevents the colour setting from working as expected in interactive environments
| let runTestsInAssemblyWithCLIArgs cliArgs args = | ||
| runTestsInAssemblyWithCLIArgsAndCancel CancellationToken.None cliArgs args | ||
|
|
||
| let runTestsReturnLogs cliArgs args tests = |
There was a problem hiding this comment.
I could use feedback on this method name.
There was a problem hiding this comment.
Maybe runTestsForInteractive
There was a problem hiding this comment.
What do you think about runTestsInteractively?
There was a problem hiding this comment.
I thought of a similar name, but I feel like it denotes the test run itself is interactive, as in there will be decision points for the user during the test run.
There was a problem hiding this comment.
Well, runTestsForInteractive seems reasonable to me, then.
Expecto/Expecto.fs
Outdated
| Seq.fold (fun s a -> foldCLIArgumentToConfig a s) | ||
| ExpectoConfig.defaultConfig cliArgs | ||
|
|
||
| match ExpectoConfig.fillFromArgs config args with |
There was a problem hiding this comment.
I believe this results in double args parsing, but it seemed like the least complex option (and easiest to follow) and we're not doing that much parsing generally. It also only applies to this interactive run method
|
I will review this later today! |
| Accepts the same arguments as `runTestsWithCLIArgs`, but returns the console output as a string. | ||
|
|
||
| This is useful for interactive environments like [F# interactive](https://learn.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-interactive/) and [Polyglot Notebooks](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode), where console output is not available but the returned string can be displayed instead. | ||
|
|
There was a problem hiding this comment.
I plan to add a screen shot once I can show the proper package reference.
Something like #r "nuget: Expecto, 10.2.0".
|
One question, instead of expanding the API with a function that only changes the logging output, wouldn't it be better to add an option that tells where the output should go? |
|
In short, I don't think we can generally redirect output for interactive environments. So, configuration creates a more complex experience in exchange for leveraging the existing methods. It'd look something like let output = StringBuilder()
runTestsWithCLIArgs [CLIArguments.OutputWriter (fun outputSegment -> output.Append(outputSegment) |> ignore)] [||] tests
outputTo me, it seems unlikely we'll want any of the reflection-based runTests variants in interactive mode, but the complexity of |
|
Hmm, I was thinking of introducing a new case to I mean, your code looks good to me, but I'm not convinced we should have a function for something that should be a configuration option and be documented on some sort of FAQ. |
|
Suppose we have a call like Do you have a more concrete vision of how LogOutput would work? |
I was considering something like this: let runTestsForInteractive cliArgs args =
let cliArgs = (LogOutput <some-cool-output>)::cliArgs
runTestsWithCLIArgsAndCancel cliArgs argsThis way we can control how the log output is handled inside |
|
The In a polyglot notebook we could do something like If we accumulate in a string builder, then we're asking users to use at least 3 lines to display output, like demonstrated previously. |
|
Oh, I ran an interactive session like on your screenshots and now I see what you mean. The notebook expects an explicit return value to output something, this is why we need to return a string itself... Well, in this case, I think this code does what is needed! I'm still not comfortable expanding the API with this, but you perhaps found people that use this a lot. If it's useful for them, let's add it. |
I don't want to block your work here, if you feel that we should add this, let's merge it! I just feel that a third-party is a better way to deal with it, indeed. It just doesn't feel correct to introduce a new function on the library's API that is responsible to change something that should be a configuration. |
|
I guess I'll think about it. |
Aimed to allow an external interactive run experience
|
I added some configuration that would allow the interactive experience to be factored into an external library: I'm a bit concerned that this configuration looks like it's per-call but really it has to lean on As for the interactive run endpoint, I do think it still belongs in the core library. |
Motivation
Expecto is uniquely suitable for interactive environments (like FSI or Polyglot Notebooks) because it treats tests as values. Tests can be defined and executed all in the same code.
However, none of the current runTests methods print output to interactive environments like FSI.
If this PR is merged
This PR adds a new method that collects logs from the test run then returns them as a string.
This allows easily displaying test output in interactive environments.
For example, here's a polyglot notebook using
runTestsWithCLIArgsHere's the same interactive cell using

runTestsReturnLogsThe new

runTestsReturnLogsshould obey options the same as other run methods