I have implemented a module that should look exactly like a regular ES6 Promise; and I want to test it as such.
The files that test promises in the node tests are here:
https://github.com/nodejs/node/blob/master/deps/v8/test/mjsunit/es6/promises.js
However I cannot work out how to run these files. After putting in the requisite require for my own module the files fail with syntax errors of missing functions. I seem to be missing some kind of testing suite but can't work out which it is.
The syntax errors are for missing function: eg. describe
I have inserted a line at the top of the file like so:
var Promise = require('my-promise-module');
this module should appear no different to:
module.exports = Promise;
I am attempting to run the file like node ./promise.js (where promise.js is the linked test file).
This is obviously not the right way to run it as many of the functions called in the test file are not available (e.g. %abortJS), though I cannot work out what the test file needs to run.
Related
I have two JS files with test methods, File1 and File2. File2.js should be executed only if the File1.js has passed all the execution. I am currently using Javascript with mocha framework and WDIO
Generally dependencies between tests in this fashion aren't desirable for a few reasons:
File2 becomes more complex to debug insolation due to the need of running File1 first.
You can't run your tests in parallel to speed up execution.
Testing File2 functionality is blocked if File1 fails.
In a hypothetical basic example let's say File1 tests user account creation and File2 tests posting a message.
One way to remove the dependency is to have a separate pre-seeded account (perhaps created via apis or database script) that File2 uses to test the posting feature. That means you can still test posting if the user account creation fails (and those can both run at once).
So if possible I'd advise thinking if there are ways you can avoid the dependency.
If there is no way around it could you potentially use a before block check in File2 that asserts things are in the state you expect, otherwise it will fail the before and therefore File2 checks are skipped?
before(`Did File 1 Run Successfully`, () => {
expect(isMyFile1DataInPlace()).toBe(true)
})
I have a Webpack-using codebase with lines like the following:
import Foo from './svg/icons/foo.svg';
and because of svg-react-loader it works.
However, using Webpack in our test environment would slow things down and add some headaches, so we run our tests (in Node) without it. This worked great up until we started importing SVGs like the one above, at which point we started to get errors like:
ReferenceError: React is not defined
at Object.<anonymous> (/Users/me/projects/foo/src/svg/icons/foo.svg:1:1)
(which I'm pretty sure happens because Node thinks the SVG file, which is made up of XML and thus looks like JSX, should be handled by React).
So, I realize one solution would be to run our test environment through Webpack, but my question is, is there any way to make:
import Foo from './svg/icons/foo.svg';
not fail (or at least fail silently and keep going) when my non-Webpack test code runs it? For instance, is there anyway I could "shim" the Node loader so that if it sees a .svg it just moves along without doing anything?
I have two modules.
One of them, "A", is ES5 with no babel. Its unit tests use mocha and chai and they complete successfully. The unit tests require a module, "M", during the testing. At this point, the code in the module is run. If it is not, the test fails. If i debug the execution, the "require('M')" jumps straight into the module.js require(path) and it loads/executes the code at the top module scope.
The other is ES6. It uses jest 19.0.2 and babel-jest 19.0.0, both currently the latest versions. It requires the same module but, unfortunately, the code is not run and the test fails. I've set "automock" to false explicitly. When I debug it, the "require('M')" stack is:
jest-runtime/build/index.js:requireModuleOrMock(from, moduleName)
jest-runtime/build/index.js:requireModule(from, moduleName, options)
jest-runtime/build/index.js:_execModule(localModule, options)
at this point it returns without running the module's code. The block is:
// If the environment was disposed, prevent this module from being executed.
if (!this._environment.global) {
return;
}
Apparently the environment was disposed. Then requireModule() returns moduleRegistry[modulePath].exports. As a result, the top-level, module-scope code does not run and the test fails.
I should add that the failing code is run within a promise so it seems possible that the environment is released before the promise resolves. I have tried using:
let promise = ...
expect(promise).resolves.toBe(true);
but the execution path is unchanged.
If someone knows why this is occurring and how to ensure that the module code runs it would be appreciated.
Let's say I have some tests that require jQuery. Well, we don't have to make believe, I actually have the tests. The test themselves are not important, but the fact they depend on jQuery is important.
Disclaimer: this is node.js so you cannot depend on global variables in your solution. Any dependency must be called into the file with require.
On the server we need this API (to mock the window object required by server-side jquery)
// somefile.js
var jsdom = require("jsdom").jsdom;
var window = jsdom().parentWindow();
var $ = require("jquery")(window);
// my tests that depend on $
// ...
On the client we need a slightly different API
// somefile.js
// jsdom is not required obviously
// window is not needed because we don't have to pass it to jquery explicitly
// assume `require` is available
// requiring jquery is different
var $ = require("jquery");
// my tests that depend on $
// ...
This is a huge problem !
The setup for each environment is different, but duplicating each test just to change setup is completely stupid.
I feel like I'm overlooking something simple.
How can I write a single test file that requires jQuery and run it in multiple environments?
in the terminal via npm test
in the browser
Additional information
These informations shouldn't be necessary to solve the fundamental problem here; a general solution is acceptable. However, the tools I'm using might have components that make it easier to solve this.
I'm using mocha for my tests
I'm using webpack
I'm not married to jsdom, if there's something better, let's use it !
I haven't used phantomjs, but if it makes my life easier, let's do it !
Additional thoughts:
Is this jQuery's fault for not adhering to an actual UMD? Why would there be different APIs available based on which env required it?
I'm using karma to run my unit tests from the command line directly (CI too, with gulp).
Karma uses phantomjs to run the tests inside of a headless browser, you can configure it to run in real browsers too.
Example of karma configuration inside of gulp:
// Run karma tests
gulp.task("unit", function (done) {
var parseConfig = require("karma/lib/config").parseConfig,
server = karma.server,
karmaConfig = path.resolve("karma.conf.js"),
config = parseConfig(karmaConfig, {
singleRun: true,
client: {
specRegexp: ".spec.js$"
}
});
server.start(config, done);
});
In case of my tests it takes approx. 10 seconds to run 750 tests, so it's quite fast.
Sorry for the awkward post title but it's a very weird situation to be in. In my project I have a folder structure like so:
/filters
index.js
[...]
/controllers
index.js
[...]
app.js
app.js is basically the entry point of my application and I thought it would be cool if I could automatically load the contents of those directories by require()ing the directory and having index.js in each of those directories take care of loading whatever it needs to load.
But I'm running into a problem I don't understand. Because I'm being intentionally obtuse (this is a learning/experimentation exercise) I decided to try and keep it as DRY as humanly possible so I tried this big of code to handle the module loading:
'use strict';
var customModules = [
'controllers',
'filters'
];
//require('./controllers');
//require('./filters');
for (var i in customModules) {
if (customModules.hasOwnProperty(i)) {
require('./' + customModules[i]);
}
}
var nativeModules = [
'ngSanitize'
];
angular.module('app', customModules.concat(nativeModules));
I'm planning on extracting that to it's own module but it'll do for demonstration. For some reason this code throws this exception:
Uncaught Error: Cannot find module './controllers'
But when I load it using a static string
require('./controllers');
No problems, everything works and my sample application behaves as expected.
Checkout the Browserify Handbook at how browserify works (emphasis mine):
Browserify starts at the entry point files that you give it and searches for any require() calls it finds using static analysis of the source code's abstract syntax tree.
For every require() call with a string in it, browserify resolves those module strings to file paths and then searches those file paths for require() calls recursively until the entire dependency graph is visited.
Bottom line: the dependencies must be statically declared; your code involving the dynamcally-created require() calls cannot work (although a good idea in principle).
You could achieve a similar result using server-side or build-time techniques.