-
Notifications
You must be signed in to change notification settings - Fork 357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test runner performance could be improved (Export Runner) #518
Comments
This is probably because we run each test in separate processes and have to spin up a new node process every time. Duplicate of #223 |
@mousetraps, issue #223 appears to have disappeared off the face of the earth. Should this issue be reopened? Are there any plans to fix the test runner performance problems or should we look elsewhere for a solution? As one can see from the image below, each test is taking one second or more to run, while it should in reality complete in 10MS or less. |
Hi all, Would an approach to fixing this be as simple as running the tests with the same instance of node or does it run deeper than that? (I'm assuming the latter...) Any pointers as to where to start/ general issues to take into account would be greatly appreciated. At this point I'm trying to plan an approach and estimate the amount of development time required for a fix. Thanks |
Very exciting to have someone interested in looking into this! You are correct that the core problem is that a new Node process is launched for each test case (see Let me start by explaining some of the high level concepts of the NTVS test pipeline:
The entire flow of running a test therefore looks like this:
There are many ways to fix the problem, and I'd be happy to discuss or review any of your ideas. My initial thought to minimize code change is the following:
This alone would fix many of the perf issues, but would not fix mocha Other things to consider after the initial prototype:
Let me know if that gives you an idea of the problem and some initial direction. Again, none of the ideas I've thrown out are set in stone, and I'd be happy to discuss any ideas you have further. And please let me know if you have any other questions or get blocked by anything. |
Thanks so much for your helpful and detailed response. I'm currently in the process of planning a fix for this. Just to give some context, I'm on a development team and we have integration testing set up using the NTVS plug-in. The tests require a server to be launched/killed during the Currently I'm trying to estimate the amount of development time needed to fix this and weigh it against our other options. From reading your response and looking at the code it seems to me this fix should take a reasonable amount of time (~ 20 days), so I should be able to get started in the coming weeks. Please let me know if you disagree. I do have one question, though. When I start working, which branch should I work from? We are using NTVS 1.1 but this seems like an issue that would be best resolved for all versions of NTVS. If I work from Thanks again! |
I think that sounds reasonable. For the development, feel free to work however you feel would be best, but I would encourage you to submit incremental we can have more discussion during the development and hopefully catch potential issues early on. You could either open a WIP PR against NTVS and update that as you work, or you could create a separate branch on your fork that you submit changes against before submitting the entire branch against NTVS. It sounds like you are proposing that we take this change into 1.1, 1.2, and the next release of NTVS. The test adapter code is fairly static, so you should be able to work from |
I'll have to check with the team, but I'm almost certain we should be able to migrate to a newer release. If it means it will be easier to merge / get builds out then it's in both of our best interests as we are looking for a fix ASAP. I'll get back to you if the story changes. |
Could you elaborate on this a bit? Would this redesign mean abandoning the use of the |
Once we start running multiple tests in a single node session, we can no longer use the exit code of the node process itself to determine whether an individual test succeed or failed. Using stdout and stderr also becomes more complicated, since we have to map any text back to a specific unit test somehow. That's why I suggest making the tests return a structured "Result" object instead. The result object would just map the old process output to a json object with the following fields:
The results could be returned over stdout or a similar IO channel, so we could keep using For the first step, you would only update // Launch node
_nodeProcess = ProcessOutput.Run(...);
...
WaitHandle.WaitAll(new WaitHandle[] { _nodeProcess.WaitHandle });
bool runCancelled = _cancelRequested.WaitOne(0);
// Parse result from stdout
// Should handle case where runCancelled too
var resultObject = ParseTestResult(_nodeProcess.StandardOutputLines);
// Use result object instead of process outputs directly
RecordEnd(frameworkHandle, test, testResult,
resultObject.stdOut,
resultObject.stdError,
!runCancelled && resultObject.passed ? TestOutcome.Passed : TestOutcome.Failed);
... Then you could later change Let me know if that clears things up. Again, there are other approaches here that would work great as well and I'd be happy to discuss any ideas more. |
Oh! I suppose I was overthinking everything. This clears it up quite a bit-- thank you! |
@mjbvz What if we create custom test runner for the Mocha which will produce output in the machine readable way so we could parse stdout/stderr reliable? |
Hi again,
If taking the JSON Array route for this problem, I am particularly interested in the 'communication channel' solution, as it seems it would be much easier in the long run but, full disclosure, I'm not sure I would even know where to start with something like that. If it's not too much trouble, could you elaborate a bit? Please let me know if I'm on the right track with the PR or if there is anything I can improve. Thanks again |
@ozyx If you use the array approach, passing the json using the command line may work, but larger projects may start hitting command line length limits. In this case, it would be better to read the json array from stdin by doing something like this on the Node side: process.stdin.resume();
process.stdin.setEncoding('utf8');
var data = '';
process.stdin.on('data', function(chunk) { data += chunk; });
process.stdin.on('end', function() {
var data = JSON.parse(data);
// process test result array
}); You could then return all the results over stdout in another json array, which would be parsed on the C# side. Using a communications channel, instead of sending all the data to the test adapter in a single array and returning it back in another giant array, the Javascript code would create something like a server that the C# could send requests to and get results back from. The main benefit is that you are able to receive test results back as they are completed, instead of blocking until all tests are run. How this is accomplished is pretty open ended, but here are some thoughts:
Let me know if that provides some good starting points and if you have any other thoughts or ideas here. Thanks. |
Thanks again for your guidance. |
@mjbvz any status on the merge on the remaining pull request ? My understanding is that the merge windows for the next version is closed ? Am I correct ? |
thanks for the info !!!! @billti any info ? |
Thanks for your help to improve the Test Explorer perf @fforjan . At this point, we've heads down trying to meet other requirements to include NTVS components in the next Visual Studio release (e.g. localization, setup changes, etc.), so unfortunately this isn't something we're going to have time to review and merge before that ships. It is definitely high on our priority list to cover once we get that behind us though. Sorry for the delay, and thanks again. |
@billti We've allocated some time to one member of our team last year to participate in this fix and we only want to claim victory when the code will be merge. Any timeline for accepting this merge ? |
We've had someone looking at what it would mean to make the Test Adapter more generally useful across VS (i.e. not just Node.js projects). I'm meeting with the Dev who's been prototyping some stuff early next week, so I'll put this on the agenda and circle back after that. |
Closing as this has been merged and shipped. |
Hi,
Version: VS 2015/ NTVS
We use
ExportRunner
to run TypeScript tests. The time taken to run a single test normally ranges from 250 ms to 1 second.The test itself should run under 5 ms, because they are all unit tests and there is no reason for them to take much longer than that.
It appears that the test launch/preparation code is adding about 200 ms per test.
This is a problem, because for just 100 tests we're looking at 20 seconds plus.
Can this be fixed?
The text was updated successfully, but these errors were encountered: