karma-jspm icon indicating copy to clipboard operation
karma-jspm copied to clipboard

race condition when using AngularJS? .. or in which file should I put my external dependencies?

Open andreasgrimm opened this issue 9 years ago • 9 comments

started to unit test an angular app with karma-jspm, e.g. I included the loading of dependencies ...

import { } from 'angular';
import { } from 'angular-ui-router';
import { } from 'angular-material';
import { } from 'angular-mocks';

... into each separate .spec.js file. but that seems to lead to race conditions, putting karma in the browser kind of into an endless loop / timeout.

thus I'm wondering where we should load our external dependencies and if that has to happen only once for all tests or separately for each test file.

andreasgrimm avatar Oct 20 '14 18:10 andreasgrimm

Unfortunately I don't know why that wouldn't work. Are you using jspm to load angular in your actual app? (not just in testing?) Do you have to do anything special to load angular there?

You could always remove the import statements from your spec and assume they are available globally. To make them available globally, you'll have to add them to the files array option in karma.conf.js. This is not ideal but might solve your problem

maxwellpeterson-wf avatar Oct 20 '14 19:10 maxwellpeterson-wf

yes. I'm using jspm to load angular in my actual app. that work's just fine.

I'm not doing anything special. in the main.js entry file (the one that get's loaded via System.import in the index.html file) I'm es6-importing along the lines of the above mentioned example.

to make them globally available I already tried it with a test-main.js file that gets referenced in the (vanilla karma) files array option. didn't solve the problem. btw: I had to do this by using System.import( ..., import didn't work (for obvious reasons).

for what it's worth: I'm on (L)ubuntu using Chrome 38.0.2125.104 (64-bit)

andreasgrimm avatar Oct 20 '14 19:10 andreasgrimm

I wasn't testing with all the newest versions of each involved component. now I tested with [email protected] (which brings in [email protected] es6-module-loader v0.9.4 [email protected] [email protected]) and with [email protected] (installed manually, because not published to npm yet ;) ) and the above described behavior doesn't occur anymore.

I noticed though, that there still seems to be some kind of race condition present. sometimes some specs just get ignored .. which leads to a non consistent amount of executed tests in the summary of the reporter, e.g. just adding and removing line breaks for a while and saving the file each time leads to the inconsistent output of

SUMMARY:
✔ 6 tests completed

or

SUMMARY:
✔ 5 tests completed

andreasgrimm avatar Oct 21 '14 13:10 andreasgrimm

seems it has something to do with (the way I'm) testing angular directives. If I'm only testing some angular controllers, then the behavior is consistent. I'll try to narrow it down some more .. and I'll see, if I can provide an example for reproducing this behavior.

andreasgrimm avatar Oct 22 '14 09:10 andreasgrimm

further it seems, that it is related to handling globals (in an modular environment). in this case the globas of angular-mocks module.

beforeEach( module( 'some-directive-module' )); produces the inconsistent behavior.

beforeEach( angular.mock.module( 'some-directive-module' )); (so far) seems to be consistent.

I took a look into the regarding override file where it says:

{
  "main": "angular-mocks",
  "shim": {
    "angular-mocks": {
      "deps": ["angular"]
    }
  },
...

and as far as I unterstand, specifying the angular-mocks file in the shim property, should trigger systemjs to provide the containing globals whereever import { } from 'angular-mocks'; is used.

@guybedford maybe you could give us your thoughts on this one?

andreasgrimm avatar Oct 22 '14 13:10 andreasgrimm

@andreasgrimm the thing to separate is if this is Karma-jspm or just the dependencies themselves.

One way to do this would be to create a single file, app.js containing all your dependencies, and load it and see that it is executing correctly.

If not, load a smaller piece of the dependency tree to find which specific modules are causing it.

It sounds like there is probably an undeclared dependency somewhere. Angular-mocks looks correct to me, so maybe one of the others.

guybedford avatar Oct 22 '14 13:10 guybedford

It's definately working all the time if I'm not importing angular-material (and it's dependencies like hammer.js). hammer.js must be made available for angular-material as a global .. but itself is a UMD module. (see https://github.com/andreasgrimm/registry/commit/739fc7adea5c300ee3d578265aa404c9341c79b9) for which if you want to use it, in config.js you have to specify something like:

System.config({
 "meta": {
   "github:hammerjs/[email protected]/hammer": {
     "format": "global"
}}});

(maybe see https://github.com/systemjs/systemjs/issues/146#issuecomment-60177835 as well)

as a sidenote: including angular-material in (angular directive) tests, I guess is questionable anyways.

what still is concerning me is that it seems it's a race condition instead of failing consistently.

I'm still working on this. more updates as soon as I find out more.

andreasgrimm avatar Nov 04 '14 13:11 andreasgrimm

How is this coming? Do you still need me to look into anything here?

guybedford avatar Nov 10 '14 13:11 guybedford

@guybedford not at the moment I guess.

what adds to the problem here is that it seems that when a spec file contains errors, e.g. with the import syntax, then the error won't get logged, karma doesn't report an error .. but instead the spec file just gets ignored.

can someone confirm this behavior?

andreasgrimm avatar Nov 10 '14 22:11 andreasgrimm