I have started implementing TDD in my JS project. I've implemented mocha for that purpose. As these are my first steps what I did:
Installed node.js
Installed mocha globally and locally to my project.
Wrote package.json setting dependencies.
Wrote makefile.
Wrote .gitignore to avoid uploading node_modules folder.
Folder structure
project
-- js
----filetotest.js
-- test
---- test.js
What I want to do is to run the command make test in order to run the tests inside test.js that tests the filetotest.js file.
I read about the node.js approach using exports. But is there some way to include the file in the test suite?
I'm stuck here, and I think that my doubt is more about the concept than the tech thing. Will appreciate a lot your help.
To clarify a little bit what I would like to do:
https://nicolas.perriault.net/code/2013/testing-frontend-javascript-code-using-mocha-chai-and-sinon/
I would like to get a similar result through the command line.
Thanks so much,
Guillermo
You are doing it right.
Now export your function from filetotest.js, like this:
var f1 = function(params) {
// ...
}
exports.f1 = f1
In test.js, require this file
var f1 = require("./filetotest.js").f1
// test f1
Btw, if you will put your tests in /test directory, mocha will execute them automatically (given that it will be executed from the root of your project)
Related
I'm somewhat new to JS, very new to Mocha, so I apologize if this is a dumb question...
I recently started working with Mocha as I'm in the early stages of a new side-project. I have mocha installed locally by the way, npm i mocha --save-dev.
I start considering if I should implement portions of my project like mocha, since I'm so happy with how easy it is to get going. Trouble is I can't figure out how they have this set up. I've looked through some of the code on GitHub, but would like a high level summary.
This is my test.js file
const app = require('../src/app');
const assert = require('assert');
describe('my app', function(){
it('does something cool', function(){
assert.strictEqual(app.foo(), true);
})
});
I'm confused because I don't have const mocha = require('mocha'); in there but VS Code still recognizes identifiers like describe before, and it. VS Code even tells me when I hover on describe that it's var describe: Mocha.SuiteFunction.
How is this code working, let alone with IntelliSense? I was expecting to have to do something like mocha.describe().
As mocha loads the test files, it adds it to the global context.
Seen here: suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self) (note the global argument here),
Handled here: suite.on(EVENT_FILE_PRE_REQUIRE, function(context, file, mocha) {}) (note that context is global from suite.emit)
VS Code even tells me when I hover on describe that it's var describe: Mocha.SuiteFunction
Your project probably has #types/mocha package installed. Intellisense didn't come up for me until I ran npm install --save-dev #types/mocha.
Several Node.js packages have the following two steps as their starting point (just using Jasmine as an example):
npm install --save-dev jasmine
./node_modules/.bin/jasmine init
The first statement is straightforward, but I could not for the life of me figure out what the second statement does under the hood. The Jasmine docs only say that it initializes it (I am searching for something more technical).
./node_modules/.bin/jasmine looks like this:
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../jasmine/bin/jasmine.js" "$#"
ret=$?
else
node "$basedir/../jasmine/bin/jasmine.js" "$#"
ret=$?
fi
exit $ret
In case helpful, I did this to clone and install the package locally:
mkdir testProj : Creates new project folder
code testProj --add : Adds folder to workspace
cd testProj
npm init : Creates package.json
npm install [--save-dev] : Installs dependencies
./node_modules/.bin/ init : What does this do, specifically?
Short: npx init
Any pointers/documentation explaining that init would be deeply appreciated.
Edit:
Just to clarify, I know what init does (clear from testing and the Jasmine documentation), I just do not understand how it does it. I am basically trying to find out why init is needed behind the script name when running it from the CLI, and where the init code is located.
I managed to finally solve this myself. If anyone comes across this in the future, the following is the explanation of ./node_modules/.bin/jasmine init.
./node_modules/.bin/jasmine init is executed from the command line
This runs the jasmine Unix script in ./node_modules/.bin/ (init argument is not used yet)
The script resolves path to jasmine.js (./node_modules/jasmine/bin/jasmine.js) and runs it
Jasmine.js contains this code: var Command = require('../lib/command.js')
Jasmine.js creates a new instance of the Command object (command) and executes: command.run(jasmine, process.argv.slice(2));
process.argv is an array of all arguments given when starting the application from command line. Recalling the command, one sees that slice(2) equals init
The run function inside command.js launches initJasmine by having mapped init to initJasmine at the very top
Finally, initJasmine makes the directory spec and all its contents
Hope that helps someone else in the future.
jasmine init initializes a basic folder structure for Jasmine by creating a spec directory and configuration json for you. You can look for more details here https://github.com/jasmine/jasmine-npm
I have a small npm CLI library which fixes errors in changelog.md's sitting at the same directory where CLI is called. I'm trying to write at least one unit test for it's CLI part (its API is a separate library and it's well-tested).
It's easy to trigger CLI's main JS file using execa library, like:
execa.sync('./cli.js')
but how do you trigger cli.js sitting in a root and meant to be looking for a ./changelog.md in a root, to execute on a different test file in a subfolder (/test/changelog.md)?
Mind you, there's real changelog.md file in the root which has nothing to do with unit test.
(Worst case scenario, we could copy cli.js into /test/, call it there via execa and delete later, but this looks not DRY solution)
My current AVA unit test is below. seed is incorrect changelog.md file. intended is correct changelog.md against which we'll compare later. I write seed contents into /test/changelog.md and want to run a CLI on it. Problem: how do I run ./cli.js against /test/package.json? Mind you, I still want my CLI API to be simple, not accept any arguments with paths (what could be a last resort solution — to accept custom path arguments).
My current test is nearly there, but it runs against root, ./package.json contents, not /test/package.json (which is how API would behave for end-user):
import path from 'path'
import fs from 'fs'
import test from 'ava'
import execa from 'execa'
test('01.01 - reads and writes correctly', t => {
var seed = fs.readFileSync(path.join('test', 'seed.md'), 'utf8')
var intended = fs.readFileSync(path.join('test', 'intended.md'), 'utf8')
fs.writeFileSync(path.join('test', 'changelog.md'), seed, 'utf8')
execa.sync('./cli.js') // <<< PROBLEM, this runs on root, not on ./test/changelog.md!
t.deepEqual(
fs.readFileSync(path.join('test', 'changelog.md'), 'utf8'),
intended,
'01.01'
)
})
How do you execute an npm CLI package on a different directory when unit testing, if it's meant to be ran on file present at the same level as CLI's JS file?
Thank you.
I have a folder Test/Automation contains many test cases, e.g. a.js, b.js, c.js, etc.
I am using WebdriverJs Selenium. I use this command to execute all the tests in this folder:
node Test/**/*.js
But only a.js was executed and then it's done. Anyone knows the reason why? Is there something wrong with this? Thanks
You have to declare that js in server.js.
For example:
var express = require('express'),
bodyParser = require('body-parser'),
modulea = require('./modules/a'),
moduleb = require('./modules/b')
If you have multiple *.js (javascript) files in same directory as well. node wont run multiple files in same command line. eg if you had a.js,b.js,c.js within test and then,
node test/*.js
will return output of a.js only.
Another proposal,
Assuming you doing some form of automation with different scenarios,
try creating a batch executable (or bash script in case of linux) with something like this,
node test/l1/a.js
node test/l1/a1.js
node test/l2/b.js
this will give you additional option to control test/js to execute.
Thanks guys, I have found a solution, I wrapped Js in mocha format, then I can them all with this command :
mocha Test/Automation/*.js
It works as I want.
I'm completely new to sails, node and js in general so I might be missing something obvious.
I'm using sails 0.10.5 and node 0.10.33.
In the sails.js documentation there's a page about tests http://sailsjs.org/#/documentation/concepts/Testing, but it doesn't tell me how to actually run them.
I've set up the directories according to that documentation, added a test called test/unit/controllers/RoomController.test.js and now I'd like it to run.
There's no 'sails test' command or anything similar. I also didn't find any signs on how to add a task so tests are always run before a 'sails lift'.
UPDATE-2: After struggling a lil bit with how much it takes to run unit test this way, i decided to create a module to load the models and turn them into globals just as sails does, but without taking so much. Even when you strip out every hook, but the orm-loader depending on the machine, it can easily take a couple seconds WITHOUT ANY TESTS!, and as you add models it gets slower, so i created this module called waterline-loader so you can load just the basics (Its about 10x faster), the module is not stable and needs test, but you are welcome to use it or modify it to suit your needs, or help me out to improve it here -> https://github.com/Zaggen/waterline-loader
UPDATE-1:
I've added the info related to running your tests with mocha to the docs under Running tests section.
Just to expand on what others have said (specially what Alberto Souza said).
You need two steps in order to make mocha work with sails as you want. First, as stated in the sails.js Docs you need to lift the server before running your test, and to do that, you create a file called bootstrap.test.js (It can be called anything you like) in the root path (optional) of your tests (test/bootstrap.test.js) that will be called first by mocha, and then it'll call your test files.
var Sails = require('sails'),
sails;
before(function(done) {
Sails.lift({
// configuration for testing purposes
}, function(err, server) {
sails = server;
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function(done) {
// here you can clear fixtures, etc.
sails.lower(done);
});
Now in your package.json, on the scripts key, add this line(Ignore the comments)
// package.json ....
scripts": {
// Some config
"test": "mocha test/bootstrap.test.js test/**/*.test.js"
},
// More config
This will load the bootstrap.test.js file, lift your sails server, and then runs all your test that use the format 'testname.test.js', you can change it to '.spec.js' if you prefer.
Now you can use npm test to run your test.
Note that you could do the same thing without modifying your package.json, and typying mocha test/bootstrap.test.js test/**/*.test.js in your command line
PST: For a more detailed configuration of the bootstrap.test.js check Alberto Souza answer or directly check this file in hist github repo
See my test structure in we.js: https://github.com/wejs/we-example/tree/master/test
You can copy and paste in you sails.js app and remove we.js plugin feature in bootstrap.js
And change you package.json to use set correct mocha command in npm test: https://github.com/wejs/we-example/blob/master/package.json#L10
-- edit --
I created a simple sails.js 0.10.x test example, see in: https://github.com/albertosouza/sails-test-example
Given that they don't give special instructions and that they use Mocha, I'd expect that running mocha from the command line while you are in the parent directory of test would work.
Sails uses mocha as a default testing framework.
But Sails do not handle test execution by itself.
So you have to run it manually using mocha command.
But there is an article how to make all Sails stuff included into tests.
http://sailsjs.org/#/documentation/concepts/Testing