-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed as not planned
Closed as not planned
Copy link
Labels
area: repository toolingconcerning ease of contributionconcerning ease of contributioncore-teamissues which must be handled by Mocha's core teamissues which must be handled by Mocha's core teamstatus: in discussionLet's talk about it!Let's talk about it!type: choregenerally involving deps, tooling, configuration, etc.generally involving deps, tooling, configuration, etc.
Description
As part of PR #4241, I was tweaking a few things in our test helper module, which helps Mocha call itself in a child process for end-to-end testing. It got me thinking a bit...
This is the current situation. I think we can do better:
runMocha/runMochaAsyncspawnslib/cli/cli.jsand gathers some basic information about the run. Attempts to parse some information from the output. Because of this, usually not safe to captureSTDERRor make assertions about error-related behavior. No access to child process handle.runMochaJSON/runMochaJSONAsyncspawnslib/cli/cli.js --reporter=jsonand gathers more detailed information, but an error coming out of Mocha (or capturing ofSTDERR) will cause theJSON.parse()call to error out, so best used for "happy path" tests. No access to child process handle.invokeMocha/invokeMochaAsyncspawnsbin/mocha(which may, in turn, spawn a child process) and provides raw output. The raw output can be subsequently parsed a larunMocha/runMochaAsyncif Mocha doesn't output something interfering with the regex-based parsing code (getSummary()). This is best used for testing errors, exceptions, etc, or interacting (non-IPC) with the subprocess.invokeMochareturns the child process handleinvokeMochaAsyncreturns a tuple of the child process handle and thePromise
Some observations:
invokeMochaAsyncis awkward to work with because of its return value.- most of the time we don't need to send signals to the child process (only possible with
invoke*) - we do often need to check the output when Mocha has thrown an exception or errored out, and the best way to do that is with
invoke* - when dealing with errors, we almost always need to capture
STDERR - nearly all of the time, we don't need to pass flags to
node, which onlyinvoke*supports. - when we capture
STDERR, we weave it in withSTDOUTinto a single string in the result (output), which causes parsing issues inrunMocha* - it's not clear when to use any of these from the function names.
- "smart" fixtures names--where you don't need to provide a full fixture path--are not possible with
invoke* - only
invoke*supports not passing a list of files to test
none of this is super-high-priority, but more obvious, consistent methods would absolutely make things easier for contributors.
if there was a proposal, I think it should be something like:
- Make a single method for general-purpose use:
- It should accept an option which would contain node flags. If these are present, use
bin/mocha, otherwise uselib/cli/cli.js - It should use execa under the hood, which does an excellent job of managing
STDERR,STDOUT, & the like; it will return a result which contains each, and a third property which contains the "woven" output. we won't have to concern ourselves with passingstdioorpipeor whatever - It should attempt to parse the output (
failed,passing,pending,total, etc) . If it cannot parse the output, it should not throw an exception, but it should add a property to the result containing an exception - It should always return a
Promiseunless a callback is supplied. - Another option flag, e.g.,
detailed, will attempt extra parsing; it will force use of--reporter=json. If this fails, again, an exception should not be thrown but it should be returned in the result object - It would contain the "smart" fixture behavior, but would skip this if no fixture was provided.
- We should be able to use
--watch, and--bailwhen running a test file using this function w/o breaking the tests. - We should be able to choose whether or not to "echo" the
STDERRof a child process to the terminal (inherit, I think?). This should not interfere with capturing ofSTDERR, which should always happen. - The
DEBUGenv var should not reach a child process. - Like the current situation, we should not invoke child processes in parallel mode unless it was explicitly requested
- It should accept an option which would contain node flags. If these are present, use
- Maybe a sugar method or two for common configurations of the above function (e.g.,
detailed: true). - Another function for the case in which we need to communicate with the child process:
- If a callback was supplied, return the child process
- If a callback was not supplied, return a tuple a la
invokeMochaAsync - Otherwise should work identically to the main function in 1.
- Hopefully, this wouldn't get used very often--especially since the tuple-returning one will still be awkward to use (but, I concede, there's really no good way around it)
- Alternatively, we look for commonalities in the tests that talk to the child process. Are we just killing the process after n ms? If so, maybe we can just get away with a "timeout" option which would do this for us. What about sending signals?
- Finally, the custom assertions (
test/assertions.js) would need to be updated to support this new result object. Ideally, this will simplify them quite a bit, because we will only have a single object (a "type" in unexpected parlance) to match; currently we have three (3), corresponding to the return values ofrunMocha/runMochaJSON/invokeMocha, respectively
Metadata
Metadata
Assignees
Labels
area: repository toolingconcerning ease of contributionconcerning ease of contributioncore-teamissues which must be handled by Mocha's core teamissues which must be handled by Mocha's core teamstatus: in discussionLet's talk about it!Let's talk about it!type: choregenerally involving deps, tooling, configuration, etc.generally involving deps, tooling, configuration, etc.