Autotests with webpack-dev-server - javascript

I'm quite confused with topic.
I develop a some kind of lazy module assembler using webpack-dev-server. It finally works but sometimes we need more assurance. That's why I need some tests. The task is to make them a kind of autotests.
For now the code of server start looks like this (I omit excessive params).
import webpack from "webpack";
import webpackConfig from "../webpack.config.js";
import webpackCompileConfig from "../webpack-compiler.config.mjs";
import WebpackDevServer from "webpack-dev-server";
webpack(webpackConfig(mode, dirname, masterPath)).run(function(err) {
if (err) throw err;
const compileOpt = {
// pack of compiler options
};
const compiler = webpack(webpackCompileConfig(compileOpt));
const server = new WebpackDevServer(compiler, {
// pack of server options
});
server.listen(port, "0.0.0.0", err => {
if (err) throw err;
console.log(`Starting root server on 0.0.0.0:${port}`);
});
});
It starts and works properly: gets some file requests, bundles necessary modules with webpack and sends them to requester.Simple test I want to start with are to check are there files after assembling or not.
Supposed logic is:
Run some command inside this project, e.g. npm run test
It starts server and sends a pack of requests with different logic I want to test (parallel, simultaneous requests etc.)
It tests file existence and send me results in console or smth. of that sort
The problem is my very little expirience in any kind of testing so I'll appreciate your help.
===The way I use it now (spoiler: manually)
The only thing the Internet helps me about.
Server starts as usual
There is another fully off-site test module (code below)
Run mocha
See listed test results
test-server.js
var chai = require("chai");
var chaiHttp = require("chai-http");
const should = chai.should();
chai.use(chaiHttp);
describe("Test file existence", function() {
it("units", done => {
chai
.request("http://localhost:9000")
.get("/units/awesome-project/index.js")
.end((err, res) => {
res.should.have.status(200);
done();
});
});
// another 'it()'s to test other files
});
Yes, it works. But I want more automatisation. Just
Run server
Send requests
Get test results
I'm ready for dialog.

Well.. just sad that nobody ask.
Anyway I've found the answer by myself. And I even wonder how it was freaking easy. It seems that all I need is written here: https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically
So the final result is similar to this:
import fs from "fs";
import path from "path";
import Mocha from "mocha";
const mocha = new Mocha();
const testDir = `${config.dirname}/test/tests`;
fs.readdirSync(testDir)
.filter(file => file.match(/\.js$/))
.forEach(file => {
mocha.addFile(path.join(testDir, file));
});
// somewhere before the devserver start
const runner = mocha.timeout(30000).run();
runner.on("end", () => {
process.exit();
});
I found it at the day I posted this question but there was a hope for someone else to answer (to compare solutions).
Best regards,
Nick Rimer

Related

NodeJs Testrunner freezes / stops when setting up Express server

I'm using Node v18 with the experimental testrunner. I use express as a dev dependency for http integration tests which works fine but there is one test freezing or stopping the testrunner ( it doesn't continue )
I'm using TS but can also reproduce it with JS, the test file HttpTests.js contains
import assert from 'assert/strict';
import express from 'express';
import test from 'node:test';
test('Http', async () => {
const server = express();
server.listen(3000);
assert.ok(false);
});
Running this with the npm script "test": "node --test $(find . -name '*Tests.js')" breaks the test runner.
Any ideas what is wrong or missing?
Why am I not using the default execution model?
Since I'm using TS I had to find a way to use ts-node with the testrunner. You can find more information here
https://github.com/nodejs/node/issues/43675
So currently my TS project is using this npm script, which works fine
Reproduction
I created a minimal reproduction repository with and without TypeScript
https://github.com/matthiashermsen/reproduce-broken-test-ts
https://github.com/matthiashermsen/reproduce-broken-test-js
For reproduction purposes run mkdir reproduction && cd reproduction && npm init -y && npm install express. After that create a test directory with a file HttpTests.js containing the content as shown above. Change the package.json to
{
"name": "reproduction",
"type": "module",
"scripts": {
"test": "node --test $(find . -name '*Tests.js')"
}
}
and run the script, the testrunner should not finish.
The testrunner is still experimental
Yes I know. But there are many tests in the project that work perfectly fine. Some sample code
await t.test('subtest - saves data.', async () => {
const expectedResult = {};
const api = express();
const port = await getRandomPort();
const server = api
.use(express.json())
.post('/save', (request, response) => {
response.json(expectedResult);
})
.listen(port);
const httpDataProvider = new HttpDataProvider({ url: `http://localhost:${port}` });
const actualResult = await httpDataProvider.saveSomething();
assert.deepEqual(actualResult, expectedResult);
server.close();
});
The issue is the async activity that you start (server.listen()) but don't stop before the test errors out (by an exception thrown by assert.ok(false)).
Your second test case will probably also stall if actualResult doesn't deep-equal expectedResult because of the same issue (server.close() won't be called).
A workaround would be to always make sure the server gets closed in the end:
test('Http', async () => {
const app = express();
const server = app.listen(3000);
try {
assert.ok(false);
} finally {
server.close();
}
});
Most test frameworks provide "before/after" functionality that can be used to set up or tear down auxiliary objects before and after a test.

My Javascript file won't run because of bigint error

I am trying to use #metaplex/js to do some NFT minting. Usually my .js files work properly but when I run the file this error comes up.
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
I don't really get what that means. So, I tried to run npm run rebuild but rebuild is said to be a missing script and I couldn't find a way to install it.
Here is my code:
import { Connection, programs} from "#metaplex/js";
import { Loader } from "#solana/web3.js";
const { metadata: {Metadata}} = programs;
const connection = new Connection("devnet");
const tokenPublicKey = 'my_adress';
const run = async() => {
try{
const ownedMetadata = await Metadata.Loader(connection,tokenPublicKey)
console.log(ownedMetadata)
}
catch{
console.log('Failed to fetch')
}
};
run();
If you have any idea, or simply an explanation of what my error means, I'd be grateful.
You are getting this error because a nested dependency has a compilation step that might not succeed in your platform. This issue provides a good explanation.
[...] This happens because one of our dependencies (bigint-buffer) runs a compilation step on installation and this can step may fail for a couple of reasons. One of the reasons is that your system might not have the build-tools the library is looking for. You can install these build tools on Windows (see https://www.npmjs.com/package/windows-build-tools), but you don't actually need to as it automatically falls back to a pure JS solution instead. Though I agree... that warning is very annoying.
However, this should give you a warning and still allow you to compile your code.
It is worth noting that the current JS SDK from Metaplex is going to be deprecated in favour of the new one: https://github.com/metaplex-foundation/js-next
With the new JS SDK, you can fetch an NFT using the following piece of code.
import { Metaplex } from "#metaplex-foundation/js";
import { Connection, clusterApiUrl } from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("mainnet-beta"));
const metaplex = new Metaplex(connection);
const mintAddress = new PublicKey("ATe3DymKZadrUoqAMn7HSpraxE4gB88uo1L9zLGmzJeL");
const nft = await metaplex.nfts().findByMint({ mintAddress });

"fetch is not found globally and no fetcher passed" when using spacejam in meteor

I'm writing unit tests to check my api. Before I merged my git test branch with my dev branch everything was fine, but then I started to get this error:
App running at: http://localhost:4096/
spacejam: meteor is ready
spacejam: spawning phantomjs
phantomjs: Running tests at http://localhost:4096/local using test-in-console
phantomjs: Error: fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/unfetch.
For example:
import fetch from 'unfetch';
import { createHttpLink } from 'apollo-link-http';
const link = createHttpLink({ uri: '/graphql', fetch: fetch });
Here's a part of my api.test.js file:
describe('GraphQL API for users', () => {
before(() => {
StubCollections.add([Meteor.users]);
StubCollections.stub();
});
after(() => {
StubCollections.restore();
});
it('should do the work', () => {
const x = 'hello';
expect(x).to.be.a('string');
});
});
The funniest thing is that I don't even have graphql in my tests (although, I use it in my meteor package)
Unfortunately, I didn't to find enough information (apart from apollo-link-http docs that has examples, but still puzzles me). I did try to use that example, but it didn't help and I still get the same error
I got the same error importing a npm module doing graphql queries into my React application. The app was compiling but tests were failing since window.fetch is not available in the Node.js runtime.
I solved the problem by installing node-fetch https://www.npmjs.com/package/node-fetch and adding the following declarations to jest.config.js:
const fetch = require('node-fetch')
global.fetch = fetch
global.window = global
global.Headers = fetch.Headers
global.Request = fetch.Request
global.Response = fetch.Response
global.location = { hostname: '' }
Doing so we instruct Jest on how to handle window.fetch when it executes frontend code in the Node.js runtime.
If you're using nodejs do the following:
Install node-fetch
npm install --save node-fetch
Add the line below to index.js:
global.fetch = require('node-fetch');
The problem is this: fetch is defined when you are in the browser, and is available as fetch, or even window.fetch
In the server it is not defined, and either needs to be imported explicity, or a polyfill like https://www.npmjs.com/package/unfetch (as suggested in the error message) needs to be imported by your test code to make the problem go away.

Execute a JS file (with logs, etc...) inside another NodeJS process

Here is my problem, I want to create a CLI that automatically runs a test. Without the CLI, I'm able to run everything perfectly with the node command:
node test.js
Basically, I want to do the exact same thing as the command before, so I googled for a technique that does this. I found this:
#!/usr/bin/env node
'use strict';
const options = process.argv;
const { execFile } = require('child_process');
const child = execFile('node', ['../dist/test.js'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
This method doesn't work for me because, in the test.js file, I'm using the ora package. And because this package is making real-time animations, it doesn't come in stdout.
Is there any way of executing in real time (without subprocess) my test.js using Node? I'm open to other methods, but I want to publish the CLI on NPM, so keep in mind that it has to be in JavaScript 😊.
You can find every file that I've talked here on GitHub. Normally, you wouldn't need this link, but I'm giving it to you if you need to have a closer look.
You should simply call your test() function from your CLI code, after requiring the module that defines it. Have a look at mocha and jasmine: you will see that while both tools provide a CLI, they also provide instructions for invoking the test frameworks from arbitrary JS code.
I can't think of a way without a sub-process. but this may help.
The child process exec will not work with the continuous output commands as it buffers the output the process will halt when that buffer is full.
The suitable solution is spwan :
var spwan = require('child_process').spwan
var child = spwan('node', ['../dist/test.js'])
child.stdout.on('data', function(data) {
console.log(data)
})
child.stderr.on('data', function(data) {
console.log(data)
})
Here is my solution, you can use the fs library to get the code of the file, and then, you simply use eval to execute in the same process.
const fs = require("fs");
function run(file) {
fs.readFile(file, (err, data) => {
eval(data.toString('utf8'))
})
}

How to unit test an node js express application [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to begin doing unit testing on my node express project. what would be the simplest and easiest way to do this ?
Here are a following links.
Mocha
Mocha is a feature-rich JavaScript test framework running on Node.js
and the browser, making asynchronous testing simple and fun. Mocha
tests run serially, allowing for flexible and accurate reporting,
while mapping uncaught exceptions to the correct test cases.
Karma
The main goal for Karma is to bring a productive testing environment
to developers. The environment being one where they don't have to
set up loads of configurations, but rather a place where developers
can just write the code and get instant feedback from their tests.
Chai
Chai is a BDD / TDD assertion library for node and the browser that
can be delightfully paired with any javascript testing framework.
Jasmine
Jasmine is a Behavior Driven Development testing framework for
JavaScript. It does not rely on browsers, DOM, or any JavaScript
framework. Thus it's suited for websites, Node.js projects, or
anywhere that JavaScript can run.
Blanket
Blanket.js is an easy to install, easy to configure, and easy to use
JavaScript code coverage library that works both in-browser and with
nodejs.
You may also follow the following tutorials
Getting started with Mocha and Chai
Introduction to Jasmine JS
Setting up a project using karma with mocha and chai
Node.js Testing Strategies
Unit Testing with Node.js
Mocha is a pretty solid solution for Node/Express. Their website has a getting started page. A simple example:
var assert = require("assert");
var request = require('supertest');
var express = require('express');
// Module under test
var version = require('version');
describe('server.routes.version', function() {
var app;
beforeEach(function(done) {
app = express();
app.use('/version', version);
done();
});
it('gets the product version', function (done) {
var expected = {
'version': '1.2.3'
}
request(app)
.get('/version')
.expect('Content-Type', /json/)
.expect(200, expected)
.end(function(err, res) {
if (err) throw err;
done();
});
});
});
If you need to mock out a Node module dependency (and eventually you probably will) things get a little more fiddly; I've had some success with a combination of sandboxed-module and sinon:
var assert = require("assert");
var sinon = require('sinon');
var request = require('supertest');
var express = require('express');
describe('server.routes.version', function() {
var app, version, mockConfig;
beforeEach(function(done) {
var mockConfig = sinon.mock({
getVersion: function() {}
});
// Load the tested module within a sandbox
var sandbox = require('sandboxed-module');
version = sandbox.require('../server/routes/version', {
requires: {
'../config': mockConfig
}
});
app = express();
app.use('/version', version);
done();
});
it('gets the product version', function (done) {
mockConfig.expects('getVersion').once().returns('1.2.3');
var expected = {
'version': '1.2.3'
}
request(app)
.get('/version')
.expect('Content-Type', /json/)
.expect(200, expected)
.end(function(err, res) {
mockConfig.verify();
if (err) throw err;
done();
});
});
});

Categories