jest - error with watch mode - javascript

I am using Jest 21.2.1 to run my tests for a react application. Strangely when I run jest --watch (as mentioned here) to watch test cases for any change, I get an error as below
Determining test suites to run...Error: This promise must be present when running with -o.
I tried to check the Jest-CLI and found that the function is expecting two parameters and one of them is promise which is not passed in this case (Not sure how can I pass that). Maybe some missing config?
Any suggestion will be helpful to fix this.
getTestPaths(
globalConfig,
changedFilesPromise)
{var _this2 = this;return _asyncToGenerator(function* () {
const paths = globalConfig.nonFlagArgs;
if (globalConfig.onlyChanged) {
if (!changedFilesPromise) {
throw new Error('This promise must be present when running with -o.');
}
return _this2.findTestRelatedToChangedFiles(changedFilesPromise);
}
Note: It might be related to issue reported here.

Make sure you're running it in a Git repo (initialised with git init). Otherwise it doesn't know how to get only the changed files.
If you don't want to run tests only on changed files, you can use --watchAll, which runs all the tests.

Related

What's the JS syntax to call a native module that has a single Promise parameter?

The Java signature is declared as:
#ReactMethod
public void someMethod(#NonNull String aString, #NonNull final Promise promise);
In that case, the Javascript calls it like this:
async someMethod() {
try {
var result = await MyModule.someMethod("Hello",)
...
} catch (e) {
console.error(e);
}
}
This works.
Now I have another method that looks like:
#ReactMethod
public void someOtherMethod(#NonNull final Promise promise);
And I cannot call it from JS because it complains (the errors are very cryptic for an inexperienced JS developer like me). I'm not looking forwards becoming a proficient JS developer, this is a small project I need to help with, but I cannot figure out how to call that.
I've tried variations of:
var result = await MyModule.someOtherMethod()
var result = await MyModule.someOtherMethod(,)
var result = await MyModule.someOtherMethod({})
...
Most examples I see either use Callback (not a Promise) or always and conveniently have more than one parameter, where the promise is (by design) the last parameter. But I couldn't find a single example with a method that only takes a Promise.
It could be I don't know how to search... (?)
Thank you for enlightening me.
I'm vote-closing this, but for future reference in case it doesn't pass, the expected syntax:
await module.someMethod()
Worked when calling a #ReactMethod method whose signature looks like
void someMethod(#NonNull Promise p);
I have no idea what black magic(*) I did but now it works.
(*)
For the most part, I noticed what when using react-native, it's more often than not, useful to kill the "metro" server and restart it with react-native start --reset-cache and then run the app again. This has made my otherwise non-compiling/running project to finally compile/run ok many times when other solutions didn't work.
I also executed this command a few times during my time with react-native, as it did fix many compile errors that appeared when I did certain things (not sure which).
mkdir -p android/app/src/main/assets && rm -rf android/app/build && react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
After that a normal react-native run-android usually worked (or a run from Android Studio).
From there (and while using a real device with Vysor), I got the menu to "reload" and other things by issuing in the command line:
adb shell input keyevent 82
Thanks for the help and hope this points other people in the right direction.

mocha global `before` that executes only 1 time

I'm using mocha for node.js functional testing.
There are several files in my test.
How can I run a piece of code for only one time before all tests start?
For example, I may have to set up a docker container before all tests start.
Is it possible to do this with mocha?
The before hook runs 1 time for every test file. This doesn't meet my needs.
You can have 'root' level hooks, if you put them outside of any describe blocks. So you can put your relevant code in any files inside of the test folder.
before(function() {
console.log('before any tests started');
});
See the docs: http://mochajs.org/#root-level-hooks
Mocha 8 introduces the concept of root hook plugins. In your case, the relevant ones are beforeAll and afterAll, which will run once before/after all tests, so long you tests run in serial.
You can write:
exports.mochaHooks = {
beforeAll(done) {
// do something before all tests run
done();
},
};
And you'll have to add this file using the --require flag.
See docs for more info.
There is a very clean solution for this. Use --file as parameter in your mocha command. It works like a global hook for your tests.
xargs mocha -R spec --file <path-to-setup-file>
A setup file can look like this:
'use strict';
const mongoHelper = require('./mongoHelper.js');
console.log("[INFO]: Starting tests ...");
// connect to database
mongoHelper.connect()
.then(function(connection){
console.log("[INFO]: Connected to database ...");
console.log(connection);
})
.catch(function(err){
console.error("[WARN]: Connection to database failed ...");
console.log(err);
});
Unfortunately I have not found a way to use async/await in this setup files. So I think you may have to be conent with using "old" promise and callback code.

How Mocha knows which file to load first in the test suite

I'm trying to learn the A Test Driven Approach with MongodB. The folder structure
A user.js to test in the src folder
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
const Schema = mongoose.Schema;
const UserSchema = new Schema ({
name: String
});
const User = mongoose.model('user', UserSchema);
module.exports = User;
Content of test_helper.js
const mongoose = require('mongoose');;
mongoose.connect('mongodb://localhost/users_test');
mongoose.connection
.once('open', () => {
console.log('Connected to Mongo!');
done()})
.on('error', (error) => {
console.warn('Warning', error);
});
create_test.js content
const assert = require('assert');
const User = require('../src/user');
describe('Creating records', () => {
it('Saves a user', (done) => {
const user = new User({ name: 'Ankur' });
user.save()
.then(() => {
assert(!user.isNew);
done();
});
Now when i run npm test the test are getting passed.
Connected to Mongo!
Creating records
√ Saves a user (779ms)
But My doubt is how does Mocha knows to run the test_helper.js file first, Everytime. (Also naming this file to any other name doesn't change the behavior).
Also i'm not using any root-level hook.
i know mocha loads files recursively in each directory, starting with the root directory, and since everything here is one directory only so its not making any difference here.
Can someone please suggest or help, how does Mocha exactly know that test_helper.js (or any filename with the same content) should be running first.
There is no default set order to how Mocha loads the test files.
When Mocha scans a directory to find files it it, it uses fs.readdirSync. This call is a wrapper around readdir(3), which itself does not guarantee order. Now, due to an implementation quirk the output of fs.readdir and fs.readdirSync is sorted on Linux (and probably POSIX systems in general) but not on Windows. Moreover, it is possible that the sorted behavior on Linux could eventually be removed because the documentation says fs.readdir is just readdir(3) and the latter does not guarantee order. There's a good argument to be made that the behavior observed on Linux is a bug (see the issue I linked to above).
Note that there is a --sort option that will sort files after Mocha finds them. But this is off by default.
The behavior you observe is explainable not merely by loading order but by execution order. Here is what happens:
Mocha loads the test files and executes them. So anything that is at the top level of your file executes right away. This means that the code in test_helper.js executes right away. Every call to describe immediately executes its callback. However, calls to it record the test for later execution. Mocha is discovering your tests while doing this but not executing them right away.
Once all files are executed, Mocha starts running the tests. By this time, the code in test_helper.js has already run and your test benefits from the connection it has created.
Major warning Connecting to a database is an asynchronous operation, and currently there is nothing that guarantees that the asynchronous operation in test_helper.js will have completed before the tests starts. That it works fine right now is just luck.
If this were me, I'd either put the connection creation in a global asynchronous before hook. (A global before hook appearing in any test file will be executed before any test whatsoever, even tests that appear in other files.) Or I'd use --delay and explicitly call run() to start the suite after the connection is guaranteed to be made.
It doesn't
Tests should not have a specific order.
All test suites should be working as standalone agnostic to other suites. Inside the suite you can use "before" and "beforeEach" (or "after", "afterEach") in-order to create setup and teardown steps.
But if the order of the tests matters, something is broken in the design.
There is a very easy way to load tests sequentially.
Step 1 : Set up a test script in package.json:
e.g.
"scripts": {
"test": "mocha ./tests.js"
}
Let us assume that tests.js is a file which defines the order to execute tests.
require("./test/general/test_login.js");
require("./test/Company/addCompany.js");
...
...
So here test_login will run first and then others one by one.
Step 2: Then run tests with:
$ npm test

Sails.js: How to actually run tests

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

Cleaning up after gruntjs encounters a fail code

I have a grunt task like so:
grunt.registerTask 'test', ['clean:test',
'coffee:test',
'mochaTest',
'clean:test']
If mochaTest returns with a fail code, the last clean won't run and will leave unwanted transpiled files.
It doesn't throw an error so I can't try/catch/finally and google/reading source code doesn't provide me with a solution except for manually running grunt clean:test after each fail.
Am I going about this the wrong way, or is there a nifty way to do something similar to a finally-block?
(I know I can run mocha using coffee-files, this is a simplified example problem)
The reason the final 'clean:test' doesn't run is that Grunt is designed to stop on failures. If you used the --force option (grunt test --force) you could cause it to continue after the failure of mochaTest. This is not a good habit to get into, or would not make sense in cases where your chain of tasks was longer, more interdependent, or more complex.
What I did to solve this was in my Makefile to add
test: grunt test && grunt clean:test
to ensure a proper cleanup even after a failed test.
$make test
to run it.

Categories