In mocha testing framework is there any possibility to store the test reports in local file - node.js

Im using mocha framework in my node application.If i run my test file using mocha means i'm getting error reports in terminal but i want to store the reports in local file.How can i do that.Is there any builtin method for this in mocha.
describe('Test with mocha', function(){
it ('result should be true',function(done){
var finalResult=false;
expect(finalResult).to.be(true);
done();
});
});

no there no built-in feature for mocha to do this, but you can do some other stuff by working with pipes which are standard in OSes.
open up a terminal, and give the command
mocha TEST.js > report.txt
the command above simply pipes all output to report.txt file.
You can also try working with child_process module from node, where you pretty much do the same thing as the command line, but in pure js.
*code is from node.js docs
var fs = require('fs'),
spawn = require('child_process').spawn,
out = fs.openSync('./out.log', 'a'),
err = fs.openSync('./out.log', 'a');
var child = spawn('prg', [], {
stdio: [ 'ignore', out, err ]
});
child.unref();

Ideally you can use mocha-junit-reporter and write output to XML file.
mocha tests --recursive --reporter mocha-junit-reporter --reporter-options mochaFile=./myJUnitfile.xml
If by local file you mean simple txt file then I have a sample code for you on which you can extend your own implementation. Please note that following code is only for knowledge sake. It doesn't handle many of the reporter events such as test suite start, and end etc., and exceptions that may be thrown by file operations.
For complete list of reporter events refer to https://github.com/mochajs/mocha/wiki/Third-party-reporters.
Also the following code is extended from the sample code present in above link.
// This code is extended on the orginal source present
// at https://github.com/mochajs/mocha/wiki/Third-party-reporters
// my-file-reporter.js
const mocha = require('mocha');
const fs = require('fs');
const os = require("os");
module.exports = MyFileReporter;
function MyFileReporter(runner, options) {
this._mochaFile = options.reporterOptions.mochaFile || process.env.MOCHA_FILE || 'test-results.txt';
mocha.reporters.Base.call(this, runner);
var passes = 0;
var failures = 0;
runner.on('start', function() {
if (fs.existsSync(this._mochaFile)) {
console.log('Removing existing test result file!');
fs.unlinkSync(this._mochaFile);
}
}.bind(this));
runner.on('pass', function(test){
passes++;
console.log('Pass: %s', test.fullTitle()); // Remove console.log statements if you dont need it (also below in code)
fs.appendFileSync(this._mochaFile, 'Pass: ' + test.fullTitle() + os.EOL); // Note: Exception not handled
}.bind(this));
runner.on('fail', function(test, err){
failures++;
console.log('Fail: %s -- error: %s', test.fullTitle(), err.message);
fs.appendFileSync(this._mochaFile, 'Fail: ' + test.fullTitle() + 'Error: ' + err.message + os.EOL); // Note: Exception not handled
}.bind(this));
runner.on('end', function(){
console.log('Test Summary: %d/%d', passes, passes + failures);
fs.appendFileSync(this._mochaFile, os.EOL + 'Test Summary: ' + passes + '/' + (passes + failures) + os.EOL); // Note: Exception not handled
}.bind(this));
}
Use the following command line (it assumes that my-file-reporter.js is present in the same folder where this command is executed)
mocha tests --recursive --reporter my-file-reporter --reporter-options mochaFile=./myfile.txt

Related

How do I access mocha's json report from a script?

Mocha can be invoked from a script and it has a useful JSON reporter, but how can one access that reported structure from the invoking script? Redirecting stdout worked:
var Mocha = require('mocha');
var stats = {};
var oldWrite = process.stdout.write;
process.stdout.write = function(txt) {
stats = JSON.parse(txt).stats; // write invoked in one gulp.
};
new Mocha().
addFile("test/toyTest").
reporter("json", {stats: stats}).
run(function (failures) {
process.on('exit', function () {
process.stdout.write = oldWrite;
console.log("percentage: " + stats.passes/(stats.passes+stats.failures));
process.exit(failures > 0 ? 1 : 0);
});
});
but I'd have expected a more direct solution.
According to the code, the answer was "you can't":
process.stdout.write(JSON.stringify(obj, null, 2));
Since the my solution above is somewhat less than obvious, I created a pull request to add a reporter option to pass in a target object:
var Mocha = require('mocha');
var report = {};
new Mocha().
addFile("test/toyTest").
reporter("json", {"output-object": report}).
run(function (failures) {
process.on('exit', function () {
var s = report.stats;
console.log("percentage: " + s.passes/(s.passes+s.failures));
process.exit(failures > 0 ? 1 : 0);
});
});
which saves capturing process.stdout.write as well as the needless serialization and deserialization of the report structure. I also added a command line to set the output file so you can run:
mocha -R json --reporter-options output-file=rpt.json
An alternative solution is to create your own reporter like it has been suggested in the documentation. I simply copied the json reporter in node_modules/mocha/lib/reporters/json.js to new file in my project folder companyReporter.js and replaced this line
Ln 69: process.stdout.write(JSON.stringify(obj, null, 2));
With
Ln 69: process.send(obj);
It was also necessary to update the paths to the requires on line 9 and 10 of myReporter.js. I prefer this way because I'm not messing with process.stdout.write.
The last change to the code was updating the reporter path:
var Mocha = require('mocha');
process.on('message', function (message) {
const test = message.toString('utf8').replace(/\n$/,'');
new Mocha().
addFile(test).
reporter(__dirname + '/path/to/myReporter.js').
run(function(failures) {
process.exit(failures > 0 ? 1 : 0);
});
});

nodejs: nedb filename path causing problems; how to fix?

I'm an experienced programmer, but relatively new to nodejs, nedb, Mocha.
nedb is a nodejs npm module for small data usages, that replicates some of the interface used in Mongodb. I chose it because I'm building an app to run on a Beaglebone Black or Raspberry Pi and didn't want the overhead for Mongodb for my small data needs.
However, I'm having a problem with the path portion of the filename for nedb. It works fine if the myapp.js I'm working on is invoked local to the current path, but if I invoke it from a different directory, like my Mocha test directory, then nedb won't work with the same path. It won't work with relative path either; I have to specify the full path, starting with /home before I can get it to work from the Mocha test directory. Needless to say, this is both inconvenient, and prohibitave for production, as it's not running with a base of /home in production.
In the code that follows, myapp.js is the application I'm developing and testing. useMyapp.js is a utility test to use myapp.js for simplicity. These are all in the same directory, and work properly when I invoke useMyapp.js.
myapp.js is located in /home/geek/project/public/javascripts/
Here is the code for myapp.js:
var Datastore = require("nedb");
var db = new Datastore({filename: "./calEvents.db", autoload: true});
function Myapp(year, month) {
console.log('myapp: year: ' + year + ', month: ' + month);
this.year = year;
this.month = month;
}
Myapp.prototype.getAllData = function() {
db.find({}, function(err, docs) {
if(err) {
console.error('error: ', err);
} else {
console.log(" docs found: ", docs);
}
});
};
module.exports = Myapp;
useMyapp.js is located in the same directory at /home/geek/project/public/javascripts/
Here is the code for useMyapp.js, which works correctly, outputing the expected nedb records.
var Myapp = require("./myapp");
var myapp = new Myapp(2016, "Mar");
myapp.getAllData();
I copied useMyapp.js to my Mocha test directory, renamed it to be TestUseMyapp.js, into /home/geek/project/test/
I adjusted the require statment for relative path to myapp.js
Here's the contents of TestUseMyapp.js in /home/geek/project/test/
var Myapp = require("../public/javascripts/myapp");
var myapp = new Myapp(2016, "Mar");
myapp.getAllData();
The output from running this via nodejs is an empty data set:
docs found: []
THE PROBLEM:
TestUseMyapp.js is able to find and load myapp.js per the 'require' statement, but the filename parameter for nedb is not working when myapp.js is invoked from a different directory. This is causing me problems between development, Mocha testing, and running in production, as the file path are all different.
I created a duplicate of myapp.js, named it myapp2.js, and kept it in the same directory as myapp.js at /home/geek/project/public/javascripts. In this, I changed the path for the nedb filename parameter.
Here's the code in myapp2.js PLEASE NOTE THE ONLY CHANGE IS TO THE filename PARAMATER PATH:
var Datastore = require("nedb");
var db = new Datastore({filename: "/home/geek/project/public/javascripts/calEvents.db", autoload: true});
function Myapp(year, month) {
console.log('myapp: year: ' + year + ', month: ' + month);
this.year = year;
this.month = month;
}
Myapp.prototype.getAllData = function() {
db.find({}, function(err, docs) {
if(err) {
console.error('error: ', err);
} else {
console.log(" docs found: ", docs);
}
});
};
module.exports = Myapp;
This works as expected when I invoked the test against myapp2.js with the full path.
THE QUESTION:
How do I resolve the filename path issue with nedb so that I don't have to change it between development, Mocha testing, and deployment to production?
Thanks!
I was able to solve this problem by inserting __dirname as part of the filename parameter.

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');

Mocha does not rerun my tests after changes

Using a test environment with
chokidar (to trigger test files on changes with a watcher chokidar variable),
node.js (to output tests result in browser),
mocha+chai (test suite),
using a custom reporter (as described in Using Mocha programmatically)
As the test file is changed, watcher catch the event, and should rerun the test.
Problem: My test is executed only once !
When trying to run my test for a second time (when the file has changed on disk the second time), mocha do not reprocess the test as in the first time. I suspect that I should reset some internal runner properties, but looking in the mocha github repository, I do not seem to find the correct method to call. Note that my reporter "class" only received 1 event from mocha runner.on("end", ...) on the second watcher wakup.
watcher.on('change', function(path, stats) {
// ...
console.log('-----File ' + path + ' has been changed ' + "[" + stats.size + "b]" );
Mocha = require('mocha');
Mocha.prototype.printFiles = function(){
console.log("Existing files = ");
console.log( this.files );
return this;
};
var mocha = new Mocha({
bail: false
});
mocha.reporter("/dirs/MyReporter.js");
mocha.addFile("/dirs/my-test.js");
mocha.run(function(failures){
});
// ...
});
How can I ask (method call) Mocha to reset its assumptions of my precedent run to rerun my test as the first time ?
//add mocha -w to your test script
"scripts": {
"test": "mocha -w"
}

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