Mocha: Watch what the tests require?

Created on 11 Dec 2011  Â·  25Comments  Â·  Source: mochajs/mocha

A common mantra for tdd / bdd is: "write some tests that fail, make them pass", aka test-first. The current implementation of --watch just sits idle in this case. It's often hard to get the tests wrong, what's being tested is more in need of watching than the code that's testing it. I think node reloaders have already solved catching this. I haven't checked how, but if I had to guess: it's by checking what's required... For simplicity sake (and to avoid circular requires) just one level deep is all that's needed in most test cases. If what's tested changes, the tests run again.

feature

Most helpful comment

One way to solve this problem is to use the watch-run package.

npm install --save-dev watch-run
Then, add the following to your package.json:

    "test": "/* whatever command you were running tests with*/",
    "test:watch": "watch-run -p 'glob/for/js/**/*.js' npm run test",  /* note: trailing comma */

or, for a slightly more complex case where you want to watch both your tests and your code:

    "test": "/* whatever command you were running tests with*/",
    "test:watch": "watch-run -p 'glob/for/js/**/*.@(js|jsx),glob/for/tests/**/*.@(js|jsx)' npm run test",  /* note: trailing comma */

And you can do npm run watch:test. Note that you need to pass --colors to preserve the coloring of the output.

All 25 comments

yeah that's why I didn't want to add --watch in the first place, it's a dirty solution that inevitably has more requirements. IMO if your test suite is fast, use watch(1), if it's slow you shouldn't rely on it _too_ much anyway and go with CI. I definitely dont want any weird require cache hacks in mocha but adding something to watch ./lib/* files etc would be ok I suppose

Thanks for keeping this open.

Do you mean visionmedia/watch? I noticed it earlier today from @changelogshow. Isn't that more like repeat(1) or recall(1) -- to make a couple of names up? If I run watch mocha I get test reports as often as the period fires (not exactly useful). Am I missing something?

Taking the suggested --watch {what} would be super helpful. More than ok, it's all I need.

Inferring it from the test code would have been ideal. Somewhere in-between ideal and super, perhaps we could add a function to the api - called dependencies / watchlist or something? This way the tests can explicitly tell mocha what to watch when it does watch. I can have this configured externally with a watchlist.json and wrap around the mocha command with my own - it's just that the tests seem a more natural place for it.

the problem with --watch foo.js bar.js is that you would normally maybe do mocha --watch test/*.js to run the tests, but then accepting the arg(s) for --watch becomes kinda ambiguous in this case. I just think over-all it's over-engineering a non-problem. personally i just type make test / up-arrow/enter haha doesn't bug me at all since you're in the term to commit etc anyway. we would have to maybe add a different flag to add watchable files

Imo, a separate --watchables option doesn't make much difference, because if you run mocha test/*.js it could be too much guessing (what to watch) anyway. Something like mocha test/*.js --watch lib/* does the same thing. Just allow for an optional parameter to watch a file or directory besides the test file (what happens with --watch by itself). The least-engineered.

This is good for focused development - work on something specific until it passes. Up-arrow is ok for no watch. I'd rather just edit the code, save it, and hope for good growl news without going to terminal. Next, it's no biggie to do ctrl-c, up-arrow, mocha --watch <whatever> else.

a separate flag might make more sense here, not sure. I would be doing mocha --watch test/*.js just because my brain likes to put the files last for some reason haha so that part definitely becomes ambiguous unless the args are passed like you show there. or alternatively we can assume watching on ./lib as well but that's a bit hacky

of-course test/*.js is optional, being the default -- my point was you could mocha --watch lib/* -G test/lib*.js test/special.js. watch takes just 0 or 1 sub-option (space-separated glob) string (or pass a comma-list?). I prefer files at the end too.

ok, my last comment was silly --watch either takes an argument or it doesn't.

we could reserve a special character to mean _don't watch anything but the test file(s)_ - e.g. mocha --watch - there should be no directory named - (minus)?

Why not just make it watch all the files in the current directory and any sub-directories? i.e. anything in your project changes, rerun the tests.

@xcoderzach it's pretty inefficient on some platforms, we could maybe do it if we ignore node_modules

@visionmedia I think inefficiency on some platforms would be an acceptable tradeoff, since the --watch flag isn't very useful on any platform as is.

i dont find it useful at all personally haha but i'll try it out on a reasonably sized project in a bit and see how it does

Watching a huge number of files works for node-supervisor, on mac and linux, even when all the files are on NFS

https://github.com/isaacs/node-supervisor

later if we need to we can add --ignore and that sort of stuff, hopefully we wont need it

With the actual implementation all my tests are executed, when I change a .coffee file, because I use the watch function of coffeescript to compile changed .coffee files. It would be better to have a parameter for the filetype, which should be watched.

I had a problem with watch and symbolic links:
Error: ENOENT, no such file or directory '/.../work/Foo/xcode/build/Release-iphonesimulator/Foo.app'

Foo.app is a link so the error makes kinda sense. Any chance watch can ignore links?
Otherwise watching everything is really awesome!

gah lol I hate watchers

haha, but it's really awesome because it enables some real TDD.

I'm always in the term, make test doesn't bug me one bit :(

I guess it's a matter of taste. I find it very rewarding to write tests like this.
Especially if you write a test against a function which doesn't exist yet.
Then you start with something in Mocha like:

Model should do xzy:
TypeError: Object function Model() {} has no method 'getFoo'

Then you start implementing getFoo and see the test failing.
After implementing the actual functionality you see the test passing.
I especially like the fact that you start with a failing test.

However, everybody has a different workflow.

to me --watch makes no sense:

  • write a test
  • implemented it
  • run the test
  • (fix shit if it's broken)
  • commit

thus if it passes I'm in the terminal to commit already, if not then I maybe lose 100ms looking at my editor again lol

Just for the record, --watch is awesome. :) (Even if it crashes on syntax errors or doesn't pick newly added sources, etc. — occasional manual restart is totally fine.)

One way to solve this problem is to use the watch-run package.

npm install --save-dev watch-run
Then, add the following to your package.json:

    "test": "/* whatever command you were running tests with*/",
    "test:watch": "watch-run -p 'glob/for/js/**/*.js' npm run test",  /* note: trailing comma */

or, for a slightly more complex case where you want to watch both your tests and your code:

    "test": "/* whatever command you were running tests with*/",
    "test:watch": "watch-run -p 'glob/for/js/**/*.@(js|jsx),glob/for/tests/**/*.@(js|jsx)' npm run test",  /* note: trailing comma */

And you can do npm run watch:test. Note that you need to pass --colors to preserve the coloring of the output.

Thanks @amfarrell this works great.

here's an example with --colors and es6

"test"      : "mocha --colors --compilers js:babel/register ./tests/index.js",
"test:watch": "watch-run -i -p 'src/**/*,tests/**/*' npm run test"

@amfarrell Thanks for that solution!

<HailMary>
Does anyone have a solution for passing params to mocha, via watch-run ... via npm test ...?

e.g. previously i could do npm run test-watch -- --grep "MyTest1"

Thanks

</HailMary>

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wzup picture wzup  Â·  3Comments

robertherber picture robertherber  Â·  3Comments

EdvinOlofsson picture EdvinOlofsson  Â·  3Comments

helloravi picture helloravi  Â·  3Comments

Swivelgames picture Swivelgames  Â·  3Comments