Non-blocking asynchronous tests using QUnit - javascript

It seems that the QUnit functions stop() and start() allow to wait for asynchronous tests, but during that waiting period the whole test suite hangs. Is there a way to run asynchronous tests in a non-blocking fashion using QUnit?

Looking at the docs for asyncTest and stop, there's two reason's I can see that it's set up like that.
So that you aren't accidentally running two tests at a time which might conflict with something (ie, modifying the DOM and so changing each others' test results).
So that QUnit knows when the tests have finished. If it comes to the end of all the synchronous tests, then it'll write up the results, which you don't really want it to do if there are still async tests happening in the background.
So these are a good thing, and you probably don't actually want the async tests to not block as they run. You could probably do it by calling start immediately after the start of your async tests, but remember, JavaScript is actually single threaded (even though it sometimes gives the appearance of multi-threading), so this might cause unexpected results, as you can't guarantee when your async test will continue running... it might not (probably won't) be until after the other tests have finished and the results have been published.

Related

What is the difference between browser.sleep() and browser.wait() methods?

Facing timing issue with protractor. sometimes my protractor test cases fails due to network or performance issues. I have solved existing issues with browser.sleep(). Later I came to know about browser.wait().
What is the difference between them and which one is better for solving network or performance issues.
When it comes to dealing with timing issue, it is tempting and easy to put a "quick" browser.sleep() and move on.
The problem is, it would some day fail. There is no golden/generic rule on what sleep timeout to set and, hence, at some point due to network or performance or other issues, it might take more time for a page to load or element to become visible etc. Plus, most of the time, you would end up waiting more than you actually should.
browser.wait() on the other hand works differently. You provide an Expected Condition function for Protractor/WebDriverJS to execute and wait for the result of the function to evaluate to true. Protractor would continuously execute the function and stop once the result of the function evaluates to true or a configurable timeout has been reached.
There are multiple built-in Expected Conditions, but you can also create and use a custom one (sample here).
sleep: Schedules a command to make the driver sleep for the given amount of time
wait: Schedules a command to wait for a condition to hold or promise to be resolved.
Reference for detail: http://www.protractortest.org/#/api?view=webdriver.WebDriver.prototype.sleep
browser.sleep()
Schedules a command to make the driver sleep for the given amount of time.
browser.wait()
Schedules a command to wait for a condition to hold or promise to be resolved.
This function blocks WebDriver's control flow, not the javascript runtime. It will only delay future webdriver commands from being executed (e.g. it will cause Protractor to wait before sending future commands to the selenium server), and only when the webdriver control flow is enabled.
Documentation link http://www.protractortest.org/#/api

synchronous vs async nodejs

Say I have a sample code running in NodeJS
function (){
///OPERATION 1
///OPERATION 2
}
Considering none of the operations require any sort of time out, by default would javascript run both at the same time or finish operation 1 then operation 2?
No two lines of JavaScript ever run simultaneously within the same process. Ever.
See concurrency vs parallelism.
Asynchronous code in Node.js - assuming there are no worker processes involved - is always running with concurrency and never parallelism. Concurrency is easier to program and helps us build complex machinery quickly. To "scale up" you may need to bring in worker processes to do work in parallel.
In your example, if both operations are synchronous, they will run in the order they are written (1, 2). In fact, if operation 1 is synchronous it will always run first no matter what. If both are asynchronous, then how you experience it depends on how long they each take to complete! If operation 1 is asynchronous but operation 2 is synchronous, then they will seem to run in reverse order (2, 1). This has to do with the way functions get scheduled on the event loop, so understanding that will help this all make sense.
Take a breath. Time for a deep dive.
To be clear, in reality, lines of code always get executed in order. We don't have GOTO and the JavaScript engine does not mysteriously jump around to different places. The key thing to understand is that when someone says a function is asynchronous it is really also partly synchronous. Something is happening synchronously. Otherwise it would be an empty function. Instead, it just means that only a tiny bit of work is done synchronously, usually that simply consists of scheduling work for later, and then the rest of it happens later.
So above when I said that if they are both asynchronous then "it depends", it's merely the completion or result of that function (which you experience via a callback or Promise) whose order is undefined in relation to the completion of other asynchronous functions. This isn't the case for fully synchronous functions simply because the world stops for synchronous functions.
If you have two functions both trying to retrieve the same data from two different sources, one from your hard disk and one from the internet, which will finish first? If they are both asynchronous, then it's a trick question. Probably the hard disk is faster, but don't bet your life on it. Still, one of them technically gets kicked off first, synchronously.
This paradigm of scheduling things for later and not waiting for the result before continuing (non-blocking) is one of the ways Node.js manages to have such great performance even without worker processes / parallelism. For I/O in particular, such as reading a file from the disk, there are "quiet periods" of inactivity where there is nothing for the process to do. In this case, waiting before continuing is a huge waste of time. It is more appropriate to use that opportunity to interleave other functions in the meantime. This is what asynchronous functions do. They delay work to allow us to interleave other work. Usually they achieve this via process.nextTick() or setImmediate().
All that said, nothing in life is free. Delaying work has a cost and if you misuse timers you will slow down your program. The goal is to make everything that has unavoidable delays (like I/O) asynchronous and almost nothing else. However asynchronous behavior "pollutes the stack". Anything that uses an asynchronous function becomes asynchronous in nature. You could return a value synchronously and pretend like it's not the case (make it invisible to the outside world), but that is usually a bad idea because then you cannot propagate errors or the result at all.
If you are still confused about how to look at a program and figure out when everything runs, have a look at async and await. It is a wonderful way to write asynchronous code that looks like more traditional synchronous code. And it is arriving in Node 7.

setTimeout to achieve asynchronicity in Node

What is the point of doing setTimeout(fx, 0) in node?
This is not asynchronous or even non-blocking, as the async function is really the setTimeout, not your fx, and after setTimeout has run asynchronously, you will end up running fx which will block your code anyway.
Doing the setTimeout with 0 to call a function fx will just wait until the stack is empty to run fx, but then while fx is running you won't be able to accept any requests, right?
So is setTimeout(fx, 0) just a way of telling node 'hey, run this whenever you can'? Is there any way to trully run async functions in Node?
If your question is:
Can node run functions in parallel at the same time?
Then the answer is yes, but you have to use a web worker.
The paradigm of asynchronosity in node is different from traditional definitions. The expectation is that you don't run too many ultra-long running functions in node. This way, effective asynchronosity is achieved.
Node is good for some things, not for others, just like any environment.
For a more detailed answer, refer here
As for setTimeout(...,0) calls; sometimes giving a break during a time consuming task to allow calls in the queue have their share of processing can be required. Dividing tasks in different ways can save you from these; but still, this is not really a hack, it is just the way event queues work. Also, using process.nextTick for this aim is much better since when you use setTimeout, calculation and checks of the time passed will be necessary while process.nextTick is simply what we really want: "Hey task, go back to end of the queue, you have used your share!"
If I understand your question correctly the answer would be the following:
As JavaScript is a single threaded language it is still able to deal with two things separately.
Using setTimeout(fx, 0) allows you to push the function or operation within the setTimeout Function in a "waiting qeue". As soon as the Stack of operations is completed the function gets put onto the execution stack and gets executed.
More detailed information about that can be found in this video

Is the Chai BDD style 'should' async?

I've been having lots of weird issues with my unit tests (see for example here or here) and I wanted to rule out this as a possibility. So, here's my potentially silly question:
Does the should style from Chai block, or is it async? Is it safe to have a done() call after some sort of should chain, or is the ideal solution callbacks of some sort?
I'm pretty sure this isn't the problem. But it seems like I discover a new problem caused by Node's non-blocking IO (or rather, my lack of experience with it) every day and I wanted to check that I wasn't making a mistake here.
I've had weird experience with .should because it needs to attach itself to object you are should-ing. I had better experience with expect(). And sync/async depends on test runner. mocha is sync. And every assertion with expect() is sequentially run, and is atomic, so there is no async operation there. Same goes for should.
i prefer expect over should because something.should will throw an error if something is undefined. no other reason for my preference.
neither should nor expect make the test async. done is what makes the test async and the done should be called in both the promise resolution and reject block (not just one). you may want to tweak the mocha (i assume mocha) timeout period before done fails. hope this helps.

Why is using jasmine's runs and waitFor function necessary?

I'm testing an asynchronous piece of code with something that looks like this:
randomService.doSomething().then(function() {
console.log('I completed the operation!');
});
Surprisingly (to me) I've found that it only succeeds (ie console.log output is shown) when wrapped inside jasmine's runs function, like so:
var isDone = false;
runs(function() {
randomService.doSomething().then(function(data) {
console.log('I completed the operation!');
isDone = true;
});
});
waitsFor(function() {
return isDone;
}, 'Operation should be completed', 1000);
As I understood it, I thought waitsFor was only to delay the code, in other words I would use it if I had more code that I had to delay until after the asynchronous call completed - in other words, I would have thought that there'd be no reason for me to use runs and waitsFor since there's nothing that comes after this bit of code, right? That's the impression I got from reading this question: What do jasmine runs and waitsFor actually do? but obviously I've gotten myself mixed up at some point.
Does anyone have any thoughts on this?
EDIT:
Here is a Plunker with far more detail of the problem:
http://plnkr.co/edit/3qnuj5N9Thb2UdgoxYaD?p=preview
Note how the first test always passes, and the second test fails as it should.
Also, I'm sure I should have mentioned this before, but this is using angularJS, and Jasmine 1.3.
I think I found the issue. Here's the article: http://blogs.lessthandot.com/index.php/webdev/uidevelopment/javascript/testing-asynchronous-javascript-w-jasmine/
Essentially it's necessary because Jasmine doesn't wait for the asynchronous calls to finish before it completes a test. According to the article, if a call takes long enough and there are more tests later, an expect statement in an asynchronous callback in a previous test could finally execute in a different test entirely, after the original test completed.
Using runs and waitsFor solve the problem because they force jasmine to wait for the waitsFor to finish before proceeding to the next test; This is a moot point however because evidently Jasmine 2.0 addresses asynchronous testing in a better way than 1.3, obsoleting runs and waitsFor.
That's just how Jasmine works. The question you linked has an answer with a decent explanation:
Essentially, the runs() and waitFor() functions stuff an array with
their provided functions. The array is then processed by jamine
wherein the functions are invoked sequentially. Those functions
registered by runs() are expected to perform actual work while those
registered by waitFor() are expected to be 'latch' functions and will
be polled (invoked) every 10ms until they return true or the optional
registered timeout period expires. If the timeout period expires an
error is reported using the optional registered error message;
otherwise, the process continues with the next function in the array.
To sum it up, each waitsFor call must have a corresponding runs call. They work together. Calling waitsFor without a runs call somewhere before it does not make sense.
My revised plunker (see comments on this answer): http://plnkr.co/edit/9eL9d9uERre4Q17lWQmw
As you can see, I added $rootScope.$apply(); to the the timeout function you were testing with. This makes the console.log inside the promise callback run. HOWEVER it only runs if you ignore the other test with an xit, AND the expect after the console.log does not seem to be recognized as a Jasmine test (though it certainly must run, because the console.log does).
Very weird - I don't really understand why this is happening, but I think it has something to do with how Jasmine works behind the scenes, how it registers tests and whatnot. My understanding at this point is if you have an expect inside an async callback, Jasmine won't "recognize" it as a part of the test suite unless the initial async call was made inside a runs.
As for why this is, I don't know. I don't think it's worth trying to understand - I would just use runs and waitsFor and not worry about it, but that's just me. You can always dig through the source if you're feeling masochistic. Sorry I couldn't be of more help.

Categories

Resources