The ability to reply to discussions is limited to PRO members. Want to join in the discussion? Click here to subscribe now.

Angular with Webpack - Testing with Karma, Mocha, and Chai

Angular with Webpack - Testing with Karma, Mocha, and Chai

10:22
Testing in Angular applications takes a bit of setup. Webpack simplifies things considerably. In this lesson you'll see how to test an Angular application built with Webpack using karma, mocha, and chai.
Watch this lesson now
Avatar
egghead.io

Testing in Angular applications takes a bit of setup. Webpack simplifies things considerably. In this lesson you'll see how to test an Angular application built with Webpack using karma, mocha, and chai.

Avatar
Tristan

I'm not too sold on the idea of pulling the tests in via the application instead of loading the application into the test, because the use of the ON_TEST switch means that you are forced to use require which feels wrong when you are building within es6 because you should be using import moduleName from 'module' and that is impossible to do within an if statement, as all imports are required to be at the root of the module (i.e. not within any extra scopes or blocks)

Avatar
Kent C.

I agree that it stinks that you can't put an import statement in a block, but because we're building the application with webpack there's no problem with using require and it is worth having the modularity of this approach even if it means having that little inconsistency. But we all have our opinions.

An alternative approach would be to have an index.test.js in the directory (side-by-side with the index.js file). That wouldn't be too bad. I hope everything else was helpful!

In reply to Tristan
Avatar
Kent C.

Of course, with this approach you would have to specify a different entry for your tests. This is no problem because the entry file is normally pretty small. And if it's not, you can create an index.common.js file that the index.js and index.test.js files import.

In reply to Kent C.
Avatar
Telepath

So glad you're doing this series. Really great so far. There is definitely still a bit of awkwardness involved in using webpack but overall I think it will end up being much cleaner than trying to do everything with gulp - anxious to see more!

Avatar
Kent C.

Interested to know what you would consider "awkwardness." I don't feel like it's awkward at all, but I am eager to know what other people feel about it as this will help direct my lessons.

In reply to Telepath
Avatar
Tristan

I'd have to agree that i'd feel happier doing it this way as opposed to having this weird side case for testing in it that only works within the context of require-able modules.

Also another thing to note is that with es6 modules, as opposed to node modules index.js is not a defaultly loaded script, it's better to point to a specific file so instead of import directives from './directives' you'd be better of doing something like import directives from './directives/common' where you'd have directives/common.js thus your files are compatable with the es6 loader without much System configuration

In reply to Kent C.
Avatar
Kent C.

Just a different way to do things. This lesson is how you do stuff with webpack and webpack enables everything that I did. I really like the api and the approach and I feel like it empowers me to build modular scaleable angular (not an easy thing to do).

In reply to Tristan
Avatar
moti zharfati

I am little bit confused, don't we need karma or gulp anymore? this method (of resolving files with webpack) is going to work the same with angular 2?
I saw a places who try to mix between gulp and webpack, is there a good reason to do that?

Avatar
Kent C.

Good question. I don't use grunt/gulp at all in my project at work. I do use grunt in angular-formly for deploying gh-pages (https://github.com/formly-js/angular-formly). Karma is still used for sure, and it uses the karma-webpack plugin to integrate with webpack. But to run it, we're still using karma start. So karma, in this example, is still very much useful. But I have found other build systems to not be totally useful because webpack just does everything for you from your JS to your CSS and even your images. They all go into the bundle.js file and you just deploy that.

There are some things that webpack WONT bundle. Like fonts or big images. For those, you can tell webpack where to put them. Also, you need to copy your index.html, robots.txt, and other non-bundled resources. In my project, I accomplish this as simply as:

cp app/{index.html,.htaccess,favicon.ico,robots.txt} dist/

and boom, I don't need an entire build config or pipeline just to do something I can do in a bash script.

As far as your question with Angular 2. It will absolutely work! Right now I'm trying to make an example, but Angular 2 is still pretty young so it's been a little bit of a struggle, but it's definitely going to work :-)

In reply to moti zharfati
Avatar
moti zharfati

Thank you!

In reply to Kent C.
Avatar
Kent C.

You're very welcome!

In reply to moti zharfati
Avatar
Jim

Great set of episodes. Kent, is it possible to have a future episode on how you can deploy such an app?

Avatar
Kent C.

Awesome idea. I'll add it to my list!

In reply to Jim
Avatar
Yonatan

Hi,
Great tutorial. Thanks.
I've tried to clone your code, but it gave me errors. I've downloaded the project, ran npm install, and then npm start - but it gave me this:
0 info it worked if it ends with ok
1 verbose cli [ 'c:\Program Files\nodejs\\node.exe',
1 verbose cli 'c:\Program Files\nodejs\nodemodules\npm\bin\npm-cli.js',
1 verbose cli 'start' ]
2 info using npm@2.5.1
3 info using node@v0.12.0
4 verbose node symlink c:\Program Files\nodejs\node.exe
5 verbose run-script [ 'prestart', 'start', 'poststart' ]
6 info prestart webpack-angular@1.0.0
7 info start webpack-angular@1.0.0
8 verbose unsafe-perm in lifecycle true
9 info webpack-angular@1.0.0 Failed to exec start script
10 verbose stack Error: webpack-angular@1.0.0 start: `node node
modules/.bin/webpack-dev-server --content-base app
10 verbose stack Exit status 1
10 verbose stack at EventEmitter.<anonymous> (c:\Program Files\nodejs\node_modules\npm\lib\utils\lifecycle.js:213:16)
10 verbose stack at EventEmitter.emit (events.js:110:17)
10 verbose stack at ChildProcess.<anonymous> (c:\Program Files\nodejs\node_modules\npm\lib\utils\spawn.js:14:12)
10 verbose stack at ChildProcess.emit (events.js:110:17)
10 verbose stack at maybeClose (child_process.js:1008:16)
10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1080:5)
11 verbose pkgid webpack-angular@1.0.0
12 verbose cwd C:\Users\Yonk\Documents\webPackApp
13 error Windows_NT 6.1.7601
14 error argv "c:\\Program Files\\nodejs\\\\node.exe" "c:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "start"
15 error node v0.12.0
16 error npm v2.5.1
17 error code ELIFECYCLE
18 error webpack-angular@1.0.0 start:
node nodemodules/.bin/webpack-dev-server --content-base app`
18 error Exit status 1
19 error Failed at the webpack-angular@1.0.0 start script 'node node
modules/.bin/webpack-dev-server --content-base app'.
19 error This is most likely a problem with the webpack-angular package,
19 error not with npm itself.
19 error Tell the author that this fails on your system:
19 error node node_modules/.bin/webpack-dev-server --content-base app
19 error You can get their info via:
19 error npm owner ls webpack-angular
19 error There is likely additional logging output above.
20 verbose exit [ 1, true ]
Any idea why?

Avatar
Yonatan

I do have another question that's more controversial.
We're currently using requirejs as our AMD library.

In your series, you cover almost everything - from requiring files through bundeling to testing. It's great to know something covers (almost) everything before messing around with it (+1 for the deployment tutorial addition :)).
Joel wrote to me that requirejs is a bad practice with angular (even though many claim it's a good one, but I do find requirejs to be a bit... unexpected, especially when it comes to testing). Would you suggest moving from requirejs to webpack as a good practice (or at least a good move)?

Avatar
Kent C.

First off, about your error. I'm not certain what the problem is. Webpack has a strong community though and if you take that question to StackOverflow, you should receive an answer.

As for AMD, webpack actually can consume AMD modules very nicely. So even if you adopt webpack, you don't have to change all of your code immediately.

That said, AMD is dying in popularity. The BEST is to write your code using as much ES6 as possible.

Note: Webpack is a module loader, not a module system. It simply consumes modules. It can consume AMD, CommonJS, ES6 modules, and even globals.

Good luck!

In reply to Yonatan
Avatar
wil

The karma.config watch property does not work for me. Did it work for you?

Any time a file changed the test harness just plain crashed.

And, I cannot think of a less informative or enlightening test than:

expect(true).to.be.true;
Avatar
Kent C.

Hmm... Perhaps you could write-up a stack overflow question or file an issue on Karma's github?

In reply to wil
Avatar
CodeHeaven

Oh boy. Is unfortunate that less than 1 year later almost all courses I try to follow will run into problems that I just can't follow what's in the video, and usually into some specific problems that I just cannot solve.

Things move fast, I know, but this is being frustrating...

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?