I have a pretty big project with lots of modules. When I try to run a simple test like:
it('foo', () => {
console.log('Running test');
});
the command yarn run jest --runTestsByPath src/simple-test.js takes 10 seconds. Babel will use the transformed JavaScript from the cache.
After doing some profiling, I found that roughly 8 seconds of that are spent loading 32'000 files from node_modules/#babel*.
Is there a way to compile all of this into a single (big) JavaScript file once with webpack and then reuse it for all my tests?
Other than that, is it possible to see why each module is loaded (= which module imports the others) so we can maybe trim this?
Related
I am having problems using Jest manual mocks (the one in a parallel __mocks__ directory) in my project.
I think I understand how to use it and it actually works fine if I remove a single line in a file specified in the Jest setupFiles array.
In that file a global helper is installed (into global.createComp) that uses the vuex store.
This is a vue + vuex project but even running the stripped down spec using only jest gives unexpected results.
Can somebody look at my minimal reproducible example repo at https://github.com/thenoseman/jest-manual-mock-not-working, do a npm i and npm run test:unit and help me understand why the mock is not active?
You can find the line that need to be commented out in test/unit/support/helpers.js.
Also the README shows a screenshot and further explains what the problem looks like.
setupFiles are evaluated before test files. As the reference states,
A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself.
JavaScript modules are evaluated once on first import. Importing #/store/modules/internetAtHome in helpers.js results in importing original #/api/DslService.
The mock in test file doesn't affect #/api/DslService because it has already been evaluated earlier:
jest.mock("#/api/DslService");
import DslService from "#/api/DslService";
In case helpers.js needs mocked #/api/DslService, jest.mock needs to be moved there.
In case helpers.js needs original #/api/DslService but tests need mocked one, the module (and any module that depends on it) needs to be re-imported with jest.resetModules or jest.isolatedModules:
jest.mock('#/api/DslService');
let DslService;
jest.isolateModules(() => {
DslService = require("#/api/DslService").default;
});
...
For a module that was imported with original implementation and needs to be re-imported as a mock, jest.requireMock can be used, it doesn't need jest.mock('#/api/DslService'):
let DslService = jest.requireMock("#/api/DslService").default;
...
Today, for some unexplained reason my jest test files started looping, resulting in a flickering terminal.
I am running jest src --watch, src being my source folder.
I followed a number of other discussions but none of them have helped solve my issue.
https://github.com/facebook/jest/issues/4635 is talking about a custom processor, but I am using a default setup.
I have tried ignoring folders.
I have ended up removing all my test files, at which point the looping stops. If I add a test file to __tests__ it matches the file but does not run a test. If I add the test file to my /src folder, it starts looping again, and it doesn't matter if the actual test passes or fails. Even if I add a fake test with a simple
describe('Test Suite', () => {
test('two plus two is four', () => {
expect(2 + 2).toBe(4)
})
})
it loops and flickers.
This is my jest setup
"jest": {
"verbose": false,
"watchPathIgnorePatterns": [
"<rootDir>/dist/",
"<rootDir>/node_modules/"
],
"globalSetup": "./jest-setup.js",
"globalTeardown": "./jest-teardown.js",
"testEnvironment": "./jest-mongo.js"
},
Does anyone know what is causing this to loop? I am not changing any files in any folder to make the --watch think it needs to run again, there are no other apps i.e. dropbox syncing the folder.
I am developing in VSCode, but the same thing happens if I test in a terminal window.
This was running fine just 5 hours ago, what went wrong?
It turns out that the jest.setup file was writing a configuration file to disk, while setting up a temporary mongoDB. If at least one of the tests used the mongoDB the looping stopped, or if I removed the setup files the looping stopped.
So my problem started when out of 30 test files, the one that connected to mongo was edited (starting the looping/flickering). In trying to solve the problem I removed all the rest of the test files, which left me with the most basic tests, but still the looping because I was still not connecting.
Still not 100% sure of the exact mechanism, but when inheriting someone else's codebase which doesn't use the default jest setup, probably best to expand jest knowledge to understand what's going on.
I am trying to set up unit testing for a Nativescript application, run by ng test on a browser. The problem is that whenever there is a tns-core-modules or another plugin import, the module cannot be resolved because of the platform specific files (e.g. "tns-core-modules/application/application.android.js") that never get compiled into the bundle, thus throwing an error like "Module not found: Error: Can't resolve 'tns-core-modules/application'".
I know there is a built-in unit test support in Nativescript. The problem I have with it is that it can't run on CI. I would like to be a ble to have lightweight tests for my business logic, mocking out all platform dependencies.
I have looked for a way to mock the module imports at runtime with no luck. I looked into rewire package but it only runs on node.
I finally managed to get it working. Not a very elegant solution and I have yet to see how much maintenance it requires. Key points here:
Use paths section of the tsconfig.json to add mock import
locations
In the mocks directory create files for any unresolved module
Some nativescript modules are referencing helper functions on global
scope but they're undefined. My solution was to define them in
test.ts like this
window['__decorate'] = () => {};
window['__extends'] = () => {};
window['__metadata'] = () => {};
window['__param'] = () => {};
window['layout_base_1'] = { CSSType: () => {} };
window['Crashlytics'] = {};
window['Fabric'] = {};
You simply can not run NativeScript application on Browser.
In case if you are looking for something like headless mode, Appium has one too, isHeadless in capabilities.
Between, may I know why you think you can not run the {N} unit tests on CI? It should work on CI too, after all it's a machine that runs the same commands based on some trigger.
I am using Karma and Jasmine for my unit tests. However, I am unable to mock or acquire the modules in my unit tests. I keep getting the same error
Error: [$injector:modulerr] Failed to instantiate module ha.module.core due to:
Error: [$injector:nomod] Module 'duScroll' is not available! You either
misspelled the module name or forgot to load it. If registering a module
ensure that you specify the dependencies as the second argument.
However, I am injecting the modules in the beforeEach function on top
angular.mock.module('duScroll');
angular.mock.module('ui.router');
angular.mock.module('ha.module.utility');
angular.mock.module('ha.module.core');
In my karma.config file I am requiring the js files
files: [
'../node_modules/jquery/dist/jquery.js',
'../node_modules/angular/angular.js',
'../node_modules/angular-mocks/angular-mocks.js',
'src/modules/utility/module.utility.built.js',
'src/modules/utility/services/*.js',
'src/modules/core/module.core.built.js',
'src/modules/**/**/*.js',
'src/modules/core/**/*.js',
'../Templates/**/*.html',
'tests2/**/*.js',
],
I have attached a screen shot to show what is showing up when I run karma. I am getting the files to show up in my developer tools.
All I can wonder is if there is something else additional that I must do to get the modules initiated to run the tests? The files are loaded after angular and angular mocks and they are loaded before my testing folder. Not sure why I cannot get the modules though.
You do not need to call angular.mock.module, it is enough to call beforeAll(module('<module-name>')) for each module you want to mock.
Then, to inject your controllers afterwards, you have to use
beforeEach(inject(function(_$controller_){
// The injector unwraps the underscores (_) from around the parameter names when matching
$controller = _$controller_;
}));
Inforation from https://docs.angularjs.org/guide/unit-testing#testing-a-controller. Please visit it for more info.
I am using Robot Framework to automate onboard unit testing of a Linux based device.
The device has a directory /data/tests that contains a series of subdirectories, each subdirectory is a test module with 'run.sh' to be executed to run the unit test. For example :
/data/tests/module1/run.sh
/data/tests/module2/run.sh
I wrote a function that collects the subdirectory names in an array, and this is the list of test modules to be executed. The number of modules can vary daily.
#{modules}= SSHLibrary.List Directories in Directory /data/tests
Then another function (Module Test) that basically runs a FOR loop on the element list and executes the run.sh in each subdirectory, collects log data, and logs it to the log.html file.
The issue I am experiencing is that when the log.html file is created, there is one test case titled Module Test, and under the FOR loop, a 'var' entry for each element (test module). Under each 'var' entry are the results of the module execution.
Is it possible from within the FOR loop, to create a test case for each element and log results against it? Right now, if one of the modules / elements fails, I do not get accurate results, I still get a pass for the Module Test test case. I would like to log test cases Module 1, Module 2, ... , Module N, with logs and pass fail for each one. Given that the number of modules can vary from execution to execution, I cannot create static test cases, I need to be able to dynamically create the test cases once the number of modules has been determined for the test run.
Any input is greatly appreciated.
Thanks,
Dan.
You can write a simple script that dynamically create the robot test file by reading the /data/test/module*, then create one test case for each of the modules. In each test case, simply run the operating system command and check the return code (the run.sh).
This way, you get one single test suite, with many test cases, each representing a module.
Consider writing a bash script that would run robot test for each module, and then merge reports to one report with rebot script. Use a --name parameter in pybot script to differentiate tests in report.