Cannot run Mocha tests with phantomjs-node - node.js

I'm trying to use phantomjs-node with mocha to run some tests
var phantom = require('phantom');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open('http://localhost:8900').then(function(status) {
console.log(status);
if ( status === "success" ) {
page.injectJs("../node_modules/mocha/mocha.js");
page.injectJs("../node_modules/chai/chai.js");
//inject your test reporter
page.injectJs("testMocha/reporter.js");
//inject your tests
tests.forEach(function(test) {
page.injectJs(test);
})
page.property('evaluate').then(function() {
window.mocha.run();
});
}else{
ph.exit();
}
});
});
});
I run the file with
node myFile.js
But when I run the file nothing shows up in the console, none of my tests are run, and the script hangs.
If I do it without phantomjs-node I'm able to run and display my tests, launching the file with
phantomjs myFile.js
but I need phantomjs-node to do other things needed for my tests. How can I mocha with phantomjs-node?

The solution to my problem was that first i needed to start the evaluate this way :
page.evaluate(function() {
I thought i had to do page.property('evaluate').then(function() { cause i was using phantomjs-node but that's not the case
And second the reason i couldn't see my tests results from mocha is because in my reporter file i was displaying the result with callPhantom :
window.callPhantom({ message: args.join(" ") });
But with phantomjs-node this doesn't seem to work so instead just do a simple console.log
console.log( args.join(" ") );
An exemple of the reporter i use and a great tutorial on how to use phantomJS and mocha together can be found there :
http://doublenegative.com/phantomjs-mocha-and-chai-for-functional-testing/

Related

How to see output of `console.log` when running Jasmine tests

I've developed a Node.js module and I'm using Jasmine to write unit tests for it. The module uses console.log to print out some information as it executes when called with a verbose argument set to true.
Let's say the module looks like this:
foo.js
function foo(arg1, verbose){
var output = "Hello " + arg1;
if(verbose)console.log("Returning %s", output);
return output;
}
module.exports = foo;
Let's say my test looks like this:
foo-spec.js
const foo = require("path/to/foo")
describe("Foo suite", () => {
it( "Expect foo to greet", () => {
expect(foo("World", true)).toBe("Hello World");
});
});
I run my tests by typing jasmine in the terminal:
$ jasmine
Everything works well except I'd like to see the verbose output.
$ jasmine
Returning Hello World
Is there a way to make Jasmine do this?
Ok, I've sort of found a workaround for this. Spying on console.log somehow patched it.
foo-spec.js
const foo = require("path/to/foo")
describe("Foo suite", () => {
it( "Expect foo to greet", () => {
//This makes the log visible again from the command line.
spyOn(console, 'log').and.callThrough();
expect(foo("World", true)).toBe("Hello World");
});
});
Not sure why, but spyOn is making the logs visible again. Even though I'm not really doing anything with it, except invoking callThrough. My best guess is that by doing this, console.log is actually being called from the Jasmine process.

Run only one mocha test file on change with gulp

I have a standard gulp test watcher and runner for my Node.js/mocha setup;
gulp.task('mocha', function() {
process.env.NODE_ENV = 'test';
return gulp.src(['./test/**/*.js'], {read: false})
.pipe(mocha({
recursive: true,
reporter: 'list',
ui: 'bdd'
})).on('error', gutil.log);
});
gulp.task('tests', function() {
gulp.watch(sources.concat(tests), ['mocha']);
});
I'm wondering how to adapt my watch task (and the other) to only send to mocha the test that has changed - so that I don't have to wait 20 seconds for a hundred tests to run.
I've tried this with fgulp-newer and gulp-cached, but no luck.
I'm looking here for an answer or for a pseudo-algorithm for a gulp plugin I could then write for this purpose :)
You can use in your mocha test it.only() to run only one test
describe.only() is available too

Why can't I see console log output when testing node apps with jest

I am new to testing with jest and I cannot seem to be able to see the console output from modules I want to test.
my-module.js:
var _ = require('underscore');
exports.filter = function(data) {
if(_.isArray(data)) {
console.log("Data is: " + data);
data = data[0];
}
return data;
}
my-module-test.js:
jest.dontMock('../my-module');
var testdata = [{label: "test"}, {id: 5}];
describe('test my module', function(){
it('changes some data' , function(){
var transformedData = require('../my-module').filter(testdata);
expect(transformedData).toBe(testdata[0]);
});
});
Why is jest swallowing my console.log output in "my-module.js"?
Jest seems to mock everything by default. Which is the issue I encountered.
Underscore "_" was mocked and there was no visible error, so the execution never got to the console.log in the first place.
There are three possibilities (as far as I know) to prevent such a situation:
In your package.json file, prevent mocking of node modules (which includes underscore)
"jest": {
"unmockedModulePathPatterns": ["/node_modules/"]
}
Explicitly prevent auto mocking in your test file using:
jest.autoMockOff();
Explicitly exclude underscore from mocking:
jest.unmock('underscore');

Is there a way to know that nodeunit has finished all tests?

I need to run some code after nodeunit successfully passed all tests.
I'm testing some Firebase wrappers and Firebase reference blocks exiting nodeunit after all test are run.
I am looking for some hook or callback to run after all unit tests are passed. So I can terminate Firebase process in order nodeunit to be able to exit.
Didn't found a right way to do it.
There is my temporary solution:
//Put a *LAST* test to clear all if needed:
exports.last_test = function(test){
//do_clear_all_things_if_needed();
setTimeout(process.exit, 500); // exit in 500 milli-seconds
test.done();
}
In my case, this is used to make sure DB connection or some network connect get killed any way. The reason it works is because nodeunit run tests in series.
It's not the best, even not the good way, just to let the test exit.
For nodeunit 0.9.0
For a recent project, we counted the tests by iterating exports, then called tearDown to count the completions. After the last test exits, we called process.exit().
See the spec for full details. Note that this went at the end of the file (after all the tests were added onto exports)
(function(exports) {
// firebase is holding open a socket connection
// this just ends the process to terminate it
var total = 0, expectCount = countTests(exports);
exports.tearDown = function(done) {
if( ++total === expectCount ) {
setTimeout(function() {
process.exit();
}, 500);
}
done();
};
function countTests(exports) {
var count = 0;
for(var key in exports) {
if( key.match(/^test/) ) {
count++;
}
}
return count;
}
})(exports);
As per nodeunit docs I can't seem to find a way to provide a callback after all tests have ran.
I suggest that you use Grunt so you can create a test workflow with tasks, for example:
Install the command line tool: npm install -g grunt-cli
Install grunt to your project npm install grunt --save-dev
Install the nodeunit grunt plugin: npm install grunt-contrib-nodeunit --save-dev
Create a Gruntfile.js like the following:
module.exports = function(grunt) {
grunt.initConfig({
nodeunit : {
all : ['tests/*.js'] //point to where your tests are
}
});
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.registerTask('test', [
'nodeunit'
]);
};
Create your custom task that will be run after the tests by changing your grunt file to the following:
module.exports = function(grunt) {
grunt.initConfig({
nodeunit : {
all : ['tests/*.js'] //point to where your tests are
}
});
grunt.loadNpmTasks('grunt-contrib-nodeunit');
//this is just an example you can do whatever you want
grunt.registerTask('generate-build-json', 'Generates a build.json file containing date and time info of the build', function() {
fs.writeFileSync('build.json', JSON.stringify({
platform: os.platform(),
arch: os.arch(),
timestamp: new Date().toISOString()
}, null, 4));
grunt.log.writeln('File build.json created.');
});
grunt.registerTask('test', [
'nodeunit',
'generate-build-json'
]);
};
Run your test tasks with grunt test
I came across another solution how to deal with this solution. I have to say the all answers here are correct. However when inspecting grunt I found out that Grunt is running nodeunit tests via reporter and the reporter offers a callback option when all tests are finished. It could be done something like this:
in folder
test_scripts/
some_test.js
test.js can contain something like this:
//loads default reporter, but any other can be used
var reporter = require('nodeunit').reporters.default;
// safer exit, but process.exit(0) will do the same in most cases
var exit = require('exit');
reporter.run(['test/basic.js'], null, function(){
console.log(' now the tests are finished');
exit(0);
});
the script can be added to let's say package.json in script object
"scripts": {
"nodeunit": "node scripts/some_test.js",
},
now it can be done as
npm run nodeunit
the tests in some_tests.js can be chained or it can be run one by one using npm

Mocha and ZombieJS

I'm starting a nodejs project and would like to do BDD with Mocha and Zombiejs. Unfortunately I'm new to just about every buzzword in that sentence. I can get Mocha and Zombiejs running tests fine, but I can't seem to integrate the two - is it possible to use Mocha to run Zombiejs tests, and if so, how would that look?
Just looking for "hello world" to get me started, but a tutorial/example would be even better.
Thanks!
Assuming you already have installed mocha, zombie and expect.js according to instructions, this should work for you:
// Put below in a file in your *test* folder, ie: test/sampletest.js:
var expect = require('expect.js'),
Browser = require('zombie'),
browser = new Browser();
describe('Loads pages', function(){
it('Google.com', function(done){
browser.visit("http://www.google.com", function () {
expect(browser.text("title")).to.equal('Google');
done();
});
});
});
Then you should be able to run the mocha command from your root application folder:
# mocha -R spec
Loads pages
✓ Google.com (873ms)
✔ 1 tests complete (876ms)
Note: If your tests keep failing due to timeouts, it helps to increase mocha's timeout setting a bit by using the -t argument. Check out mocha's documentation for complete details.
I wrote a lengthy reply to this question explaining important gotchas about asynchronous tests, good practices ('before()', 'after()', TDD, ...), and illustrated by a real world example.
http://redotheweb.com/2013/01/15/functional-testing-for-nodejs-using-mocha-and-zombie-js.html
if you want to use cucumber-js for your acceptance tests and mocha for your "unit" tests for a page, you can use cuked-zombie (sorry for the advertising).
Install it like described in the readme on github, but place your world config in a file called world-config.js
`/* globals __dirname */
var os = require('os');
var path = require('path');
module.exports = {
cli: null,
domain: 'addorange-macbook': 'my-testing-domain.com',
debug: false
};
Then use mocha with zombie in your unit tests like this:
var chai = require('chai'), expect = chai.expect;
var cukedZombie = require('cuked-zombie');
describe('Apopintments', function() {
describe('ArrangeFormModel', function() {
before(function(done) { // execute once
var that = this;
cukedZombie.infectWorld(this, require('../world-config'));
this.world = new this.World(done);
// this inherits the whole world api to your test
_.merge(this, this.world);
});
describe("display", function() {
before(function(done) { // executed once before all tests are run in the discribe display block
var test = this;
this.browser.authenticate().basic('maxmustermann', 'Ux394Ki');
this.visitPage('/someurl', function() {
test.helper = function() {
};
done();
});
});
it("something on the /someurl page is returned", function() {
expect(this.browser.html()).not.to.be.empty;
});

Resources