Full stack testing Ember.js and Laravel app - node.js

I am working out how best to test an application we are developing using Laravel as backend (REST API) and Ember.js as front end.
I am currently using Behat to run acceptance tests for the API. I would like to use Cucumber.js to also create and test features for the Ember side of the project.
I already have an "acceptance" environment dedicated to running the Behat features in the API.
The issue I can see with "full stack" testing from the JS side is how to clean and reseed the database?
My thoughts are to add a route for testing purposes only, e.g.:
if ( App::environment() == 'acceptance' ) {
Route::get('/test/reseed', function() {
// delete db if exists
Artisan::call('migrate');
// call other migrations...
Artisan::call('db:seed');
return "ok";
});
}
This way only the acceptance environment has access to that call, and it should be all thats needed to set up the API side of things ready for Cucumber.js & Ember to run the tests (probably via Node.js)
I'm asking here to see if there is anything glaring I might have missed, if there is another way to do this.
The reason I want to be able to test purely from the JS side is so that we can test the systems independently of each other. I am aware I can test the full application with Behat, Mink and PhantomJS for example.

Related

vite rebuilds dev server on every http request, causing graphql schema duplicates instantly crashing server -- build and production works, repo inside

I'm trying to build a graphql server using nestjs and using vite + swc as the compiler/builder for performance reasons, webpack would take 50-60+ seconds on each rebuild on a big project, SWC/vite seems to cut that down by a factor of 5 at least.
Here's a repository that reproduces the issue with a basic 'health check' endpoint and graphql query.
The main tools concerning this:
"#nestjs/graphql": "10.0.9",
"#nestjs/apollo": "10.0.9",
"typescript": "4.7.4",
"vite-plugin-node": "1.0.0",
"vite": "2.9.13",
"#swc/core": "1.2.207",
"vite-tsconfig-paths": "3.5.0"
Now, I have played around with these fixed versions trying out various combinations of older versions. But I've narrowed down the flaw to be a problem with vite specifically.
There's this github issue opened over a month ago that's probably directly related, with this being merely a symptom of that issue.
If you build the app and serve it, everything works fine, because the production version calls the bootstrap() function which is not handled by the vite development server.
This is also a nestjs-specific problem due to nestjs doing the code-first approach.
I'm trying to patch this issue somehow by attempting three things:
stop the development server from rebuilding on every request
configure the development server to cleanup after itself on every request
configure nestjs's graphql in a way that only builds the schema 1 time, something as simple as:
let built = false;
if(!built) { buildSchema(); built = true; }
I'm counting on that built variable not changing between requests, but if it does, I might find a way to tie it to the start command via a file outside of vite's scope.
Thank you.

How to prevent Mocha from preserving require cache between test files?

I am running my integration test cases in separate files for each API.
Before it begins I start the server along with all services, like databases. When it ends, I close all connections. I use Before and After hooks for that purpose. It is important to know that my application depends on an enterprise framework where most "core work" is written and I install it as a dependency of my application.
I run the tests with Mocha.
When the first file runs, I see no problems. When the second file runs I get a lot of errors related to database connections. I tried to fix it in many different ways, most of them failed because of the limitations the Framework imposed me.
Debugging I found out that Mocha actually loads all files first, that means that all code written before the hooks and the describe calls is executed. So when the second file is loaded, the require.cache is already full of modules. Only after that the suite executes the tests sequentially.
That has a huge impact in this Framework because many objects are actually Singletons, so if in a after hook it closes a connection with a database, it closes the connection inside the Singleton. The way the Framework was built makes it very hard to give a workaround to this problem, like reconnecting to all services in the before hook.
I wrote a very ugly code that helps me before I can refactor the Framework. This goes in each test file I want to invalidate the cache.
function clearRequireCache() {
Object.keys(require.cache).forEach(function (key) {
delete require.cache[key];
});
}
before(() => {
clearRequireCache();
})
It is working, but seems to be very bad practice. And I don`t want this in the code.
As a second idea I was thinking about running Mocha multiple times, one for each "module" (as of my Framework) or file.
"scripts": {
"test-integration" : "./node_modules/mocha/bin/mocha ./api/modules/module1/test/integration/*.integration.js && ./node_modules/mocha/bin/mocha ./api/modules/module2/test/integration/file1.integration.js && ./node_modules/mocha/bin/mocha ./api/modules/module2/test/integration/file2.integration.js"
}
I was wondering if Mocha provides a solution for this problem so I can get rid of that code and delay the code refacting a bit.

Using command line arguments with ReactJS

I'm wondering if it's possible to use command line arguments with ReactJS (not react-native). For example, is it possible to input a simple string and have it be saved as a variable so it can be displayed? The npm yargs module is the kind of thing I'm looking for, but I couldn't get that to work because the child process it spawns apparently doesn't work in a browser.
Edit: I've also tried something like including {process.argv[0]} in say an h1 tag, but nothing shows up.
React doesn't have anything special for command line arguments. In fact, it is primarily designed as a DOM library. You could use yargs and then pass the values to a React component.
For example you run this command in terminal or cmd
npm start -- foo
foo is your argument.
You can print your like this
// print process.argv
process.argv.forEach(function (val, index, array) {
console.log(index + ': ' + val);
});
in your script.
React runs is client-side
React is a client-side library. It runs in a web page, on a browser. The end-user doesn't use the command-line to "run" React, therefore command-line arguments are not available to the end-user.
For developers
As a developer, you do use tools to start a development server and launch a browser that is running React. Most likely, you're using Create React App. You can use environment variables to pass variables/arguments to React. Specifically, the documentation offers these examples:
# on Linux and macOS
REACT_APP_NOT_SECRET_CODE=abcdef npm start
# on Windows (cmd.exe)
set "REACT_APP_NOT_SECRET_CODE=abcdef" && npm start
Note that these variables are embedded into React at build time, when Create React App bundles and builds your app (kind of like compiling). This means that if you build your React project and then transfer the output files to another server and try to pass new variables, nothing will change.
For servers
If your React build files are on a server and you want to be able to pass command-line arguments to the server and have React change, this is also possible, but largely depends on what software you are using to serve. Broadly, the server would take the runtime argument and pass it into the template which renders your React app. Then any Javascript that runs on that page can access the arguments.

Gruntfile to run app and mock test from single grunt command

I have a Node.js Express REST API app that works. Good.
I have a Mocha/Chai/Supertest mock that tests the API app above. Good.
But I have to start the app and then independently run the mock test.
How can I run a single grunt command that starts the API app, let's it get up and going, and then runs the mock test?
Or do I need to run the API app in some kind of test mode (via env var) and have test-only logic somehow invoke the mock test?
I can try some things and get something to work, but what is the good way? (Avoiding overused phrase 'best practice'.)
You can do that with grunt-express-server and grunt-mocha-test, you will juste have to setup your task like below :
grunt.registerTask('test', ['express:test', 'mochaTest']);
This will run your express server with the config you have set for the test environement then run mocha when you run grunt test.
Since you are using supertest I suppose you are doing functionnal testing which means that you will be using the same database for developement and testing (if you are not mocking something). That can be time loosing and make your test fail because of bad data. Using two different environement makes sure of the state of your data when you are running the test.
You can still use grunt watch plugins to relaunch your test on file change if you don't want to have to do it manually.
Hope this helps

Correct configuration with Gulp, Mocha, Browserify to execute client side test with server side tests

I'm working on a node application utilizing gulp for our build processes and the gulp-mocha plugin for our test-runner.
gulp.task('test', function () {
return gulp.src(TESTJS)
.pipe(mocha({reporter: 'spec'}))
.on("error", function (err) {
// handle the mocha errors so that they don't cloud the test results,
// or end the watch
console.log(err.toString());
this.emit('end');
});
});
Currently TESTJS is only my server-side tests. I am wanting to use this same process to execute my client tests as well. I looked into gulp-blanket-mocha and gave it a shot but I keep running into the same issue. When trying to test my backbone code, it fails because the other client components necessary (namely jquery) are not found by the test runner and it fails. I get that I need to use some sort of headless webkit like phantomJS. But I am having real trouble figuring out how to incorporate that into this gulp process with browserify.
Anyone tried getting a setup like this going or have any ideas what I am missing here in terms of having my gulp "test" task execute my client side mocha tests as well as my server side?
A potential setup is :
Test runner - this is the glue between gulp and karma and provides option to set the karma options.files with the gulp.src() stream. Frankly if you have no steps before your karma tests, then use karma directly within gulp task, without gulp plugin.
Use associated karma plugins, to run on phantom/chrome/firefox
Use associated karma plugins for coverage, alt-js compilation
More plugins & configuring karma options for reporting of tests and coverage.
Using browserify will change the whole setup above.
Since it needs to resolve requires, it must run on all the "entry point" files. Typically your tests should require sources, and must be entry points.
Use karma-bro - it solves the problems in karma-browserify (ATM this doesnt even work - it cant work with bfy 5.0 api) & karma-browserifast.
Coverage becomes tricky since sources/vendor-sources/tests are all bundled. So I had created a custom coverage transform, that marks which code whould be instrumented while bfy is bundling
browserify should be a "preprocessor" in karma.
A bunch of "transform: []" should be configured in browserfy options
The transforms can be configured by taking an existing transform module and wrapping with a custom module like what I did above for browserify-istanbul

Resources