Running init first in NodeUnit - separate file - javascript

Currently I am developing nodeunit tests and I stumbled upon a problem.
I have a folder named "Unit_tests"
In this folder I have a file "testInitializer.js" which contains 2 methods:
init and term.
These methods should be run just once and only at the beginning and the end of all the other tests. Other tests are in separate folders under the root "Unit_tests".
How can I make sure this file is run first.
As of now, it does mostly but in some cases it doesn't.
Is there a way in webstorm to make sure it runs first?
Many thanks in advance!

As far as I know, this is not possible with only NodeUnit, since it uses an asynchronous approach where the callbacks don't execute in a predictable order. This behavior is by desing, and is supposed to provide a more realistic testing routines and prevent dependencies between tests.
You can however use Grunt JS with the NodeUnit plugin to take full control of your testing process.
You can find a great article on this topic here:
http://markdalgleish.com/2012/09/test-driven-node-js-development-with-grunt/

Related

How can I multi-thread in Electron with compatibility for Node.JS and JQuery functions?

I'm programming an Electron application, and a few pages are meant to update a table real-time by fetching Json strings from my web API. The part that matters from this is that my table first has to be loaded into the document (HTML), before or after (it doesn't matter) I start a new JavaScript thread. I already need to use the main process for handling button and table events.
The thread is used for continuously fetching the data, and if it detects differences from the currently loaded document, it'll put those changes back onto the server. Right now, I'm having trouble starting a new thread that has full access to preloaded JS functions that are used in Node, Electron, and JQuery.
Here's a list of what I tried and why it went wrong, so maybe you can help me find a solution to these or suggest a new direction (another NPM module maybe?):
Vanilla WebWorkers | Couldn't use any predefined functions from Node, Electron, JQuery because it starts an entirely new process.
Node child_process | This builtin function forks a new thread. However, it works in an entirely different environment, meaning that I'm not able to see output if it has any to the console/document.
Electron WebWorkers | I found these on the Docs and enabled NodeIntegrationInWorker. However, it had an error that it couldn't find files from workers/api/etc, and I couldn't locate those files either. It's important to note that this wasn't a module that I had to install, so IDK where those files even are on my system after 30mins of searching.
There are also a few different NPM modules that I installed to no avail, mostly because they were isolated (like extended WebWorkers similar to Electron WebWorkers) or they were isolated (Extending the child_process().fork function that didn't work either, from Node).
node-process
workerjs
threads
webworker-ng
webworker-threads
Finally, in an attempt to fix the third option that I mentioned, I tried to focus on the ASAR path, mentioned here. That fixed this error:
Uncaught Error: ENOENT, worker\api\exports\electron.js not found
But now I'm at the point where the thread probably starts once I load the page but doesn't log even a simple "Hello" to the console, probably due to that wonderful thread isolation.
TLDR; I need a way to run a second thread in Electron that has full access to predefined objects. This option should hopefully run behind the main process, not stopping the page from loading once it goes into its infinite while(True) loop.
As answered by Darkrum in the comments:
setTimeOut or setInterval is your friend.
After some additional research (comment if I'm wrong here):
These two functions allow for code to be executed "simultaneously". Because Javascript is technically only a single-threaded language, true multithreading doesn't exist. Instead, the JS engine, when processing setTimeout, will constantly check for updates in the main thread.

How do I build and validate a plain JavaScript-based code base?

My front end is an Angular 1.x project with tons of files. I basically need to validate it and find any errors that are there in any of the files. Specifically, errors that can break the page. In compiled/static type languages like Java, this is very easy, as the compiler will tell you exactly what's wrong. However, since JS is interpreted/dynamically typed, I can't figure out a way to "build" these files and find errors like I would for compiled languages. Going to every single page in the browser after I make any change is neither practical nor scalable.
I am also not using TypeScript or ES6 and it's not possible at the moment to migrate to any of them. Tools like ESLint and JSHint have also not been very successful, since they only bring out minor errors within that file. However, a lot of major code is spread over several files. Although my code is already all ES5, I thought about concatenating all JS files together in one file and running babel on it. But have it been sure how to manage dependencies during the concatenation (such as in what order to concatenate files).
This cant be the only project that uses vanilla JS and needs to be validated for errors. Anyone has any ideas on how I should go about accomplishing the task?
I highly recommend writing tests using jasmine and karma. I've found the two of these integrate really well with Angular and test driven development is highly regarded as one of the best development styles.
With all of this being said, I understand that's not what you're looking for directly because you want more of a "compiler" like solution. The closest thing that you can get to this in JS in my opinion is a linter and when combined with tests, this solution is rather good at finding errors in JS code.

Can Protractor and Karma be used together?

If Protractor is replacing Angular Scenario Runner for E2E testing, does that mean I will still be able to use it with Karma as my E2E testing framework ?
Not recommended by the current maintainer of Protractor:
https://github.com/angular/protractor/issues/9#issuecomment-19927049
Protractor and Karma should not be used together; instead they provide separate systems for running tests. Protractor and Karma cover different aspects of testing - Karma is intended mostly for unit tests, while Protractor should be used for end to end testing.
Protractor is built on top of WebDriverJS, which uses a Selenium/WebDriver server to provision browsers and drive test execution. Examples of pure WebDriverJS can be found here: http://code.google.com/p/selenium/wiki/WebDriverJs
And
https://github.com/angular/protractor/issues/9#issuecomment-19931154
Georgios - I think it makes sense to keep Protractor and Karma separate - for end to end tests, you want the native event driving and flexibility of webdriver, while for unit tests you want fast execution and autowatching of files.
UPDATE. Here is a simple package I've created to add minimal Karma setup to any project with one single command npm install min-karma.
I'd like to clarify some possible misconceptions about Karma and Protractor. Karma FAQ actually does refer to Adapter for Angular's Scenario Runner, which, however, seems to be abandoned, with Protractor being recommended instead.
Karma
Karma is a test runner that will run the JavaScript files specified in you configuration file explicitly or using node-globs. (For non-JavaScript external templates, Angular's Unit Testing Guide recommends using Karma html preprocessor to compile them into JavaScript first.)
These can be all your source files, some of them, some of them plus some additional files or files irrelevant to your project, only providing some extra configuration - you name it!
You can have multiple karma config files for different purposes, which you can run in parallel or one-by-one. Each karma process launches its own set of browsers (these are currently available).
This feature of Karma to run only a set of files is what makes it perfect for fast tests running in background upon each source file edit, and get immediate feedback, which is brilliant! The only negative is the "noisy" error reporting that will hopefully improve!
Karma is not only for unit tests
Unit test is for a single unit of your source code. In Angular's case a typical unit is Angular Component (Service, Factory, Provider, Controller, Filter, Directive etc). Remember to keep your Controllers thin, so too many unit tests for latters is a red flag.
In a unit test, every other units of code, on which this unit depends (so-called unit's dependencies) should not be tested at the same time. Instead they should be "mocked", e.g. replaced by something simple like dummy instances. Angular provides great mock environment support. Ideally you want to see all those mocks directly inside your tests, so you never need to wonder where all those dependencies come from.
Karma is just as useful for Integration Tests, where a group of source code units is tested together, with only some of their dependencies being mocked. It is important to remember that any dependency is by default provided from your source code modules (as long as those modules either injected directly in your tests, or they are dependencies of other modules injected (in which case you don't need to inject them, but no harm to do so). The mocked dependencies will override the provided ones.
Running Fast and Frequent is the main feature of Karma. This means you want to avoid any server requests, any database queries, anything that can take longer than fractions of seconds. (Otherwise it will NOT be fast!) Those long processes are ones you want to mock. This also explains why it is a bad practice to put raw low level services like $http directly inside your controllers or any complicated business logic units. By wrapping those low level outside communication services into smaller dedicated services, you make it much easier to "mock them away".
What Karma does not do is running your site as it is, which is what End-to-End (E2E) testing is. In principle, you could use Angular's internal methods to recreate the site or its pieces. Which, for small pieces, can be useful, and a fast way e.g. to test directives.
It is, however, not recommended way to throw complicated code inside your tests. The more you do it, the more chance is that you make errors in that code instead of what you are actually testing.
That is why I personally dislike the often mentioned complicated way of testing methods using low level methods like $http. It works cleaner to isolate any reference to low level methods into dedicated methods of your own, whose single responsibility is to make http requests. These dedicated methods should be able to work with real backend, not a fake one! Which you can easily test - manually or even perfectly fine with Karma running with another special config, as long as you don't mix that config with the one usually used to run Karma regular and fast.
Now, having your dedicated small services tested, you can safely and easily mock them to test your other logic and put these tests into your regular Karma setup.
To summarize. Use Karma to run any set of JavaScript files. It is (should be) fast. You don't see your complete app, so can't test the final result effectively and reliably. Would I run it with Protractor? Why would I? Running Protractor would slow down my tests, defeating the purpose of Karma. It is easy to run Protractor separately.
Protractor
Protractor is:
an end-to-end test framework for AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.
So Protractor does exactly what Karma doesn't - run your real final application. This reveals its both power and limitations:
Running complete application is the only reliable final test that your application works as expected. You can write up complete user story scenarios and put them into your tests!
But it is harder to track errors without isolating individual units of your source code. This is why you still need Karma to test your JavaScript code first.
Now would I want to run Protractor with Karma? I surely can run them in separate terminal windows, in parallel. I could, in principle, have them share test files if I need to, but normally I'd rather not. Why? Because I want to keep my tests small with single dedicated purpose.
The only exception would be a file defining testing macros useful for both runners. This, however, would not be a test file but a macro definition file.
Other than that, I like a clear separation between my tests. Those to be run frequently and fast, and those for the complete app. That makes a clear separation between when using Karma and when Protractor.
Karma is a test runner provided by the Angular team, Karma will execute your tests in multiple browsers which shall ensure that our application is compatible in all browsers.
Unit Test for angular js can be used karma + jasmine
Jasmine is a javascript unit testing framework and will provide us with utilities to test our application. This works best on the Angular framework and thus, our choice of “automated unit testing tool”.
https://github.com/shahing/testingangularjs
And Protractor is an end-to-end test framework for Angular and AngularJS applications.
Protractor runs tests against your application running in a real browser, headless browsers , cross browser testing and can be hosted on saucelabs.
https://github.com/shahing/Protractor-Web-Automation
Yes, you can use karma and protractor together. Karma is used for unit testing the component you created using angular command you can test those components using karma.
Protractor is used for end to end test. It is mainly used for UI testing.

JavaScript Unit Test. What to mock?

I'm trying to introduce Unit Test in my development process and I'm not sure how to do it.
I have a big application with a lot of modules ( separated js files ). For example:
videoInfo.js
availableVideos.js
availableChannels.js
networkSettings.js
.......
There are also a few modules that provide services for the rest:
eventHandler.js
i18n.js
ajax.js
configuration.js
auth.js
baseModule.js
........
The question is: how do I test a module like videoInfo.js that uses all the services modules? I see two approaches:
I load only videoInfo.js and mock all the internal interfaces. The problem with this is that I won't catch errors if any of the internal interfaces change.
I load all modules (the whole app) and test the videoInfo with the real app environment ( except the external AJAX calls that will be simulated)
What is the good approach to do this when you have a lot of internal dependencies?
Ideally, you want both of your approaches in your test suite.
You want to mock all of the dependencies (in your example for videoInfo.js) so that you can isolate its code from anything else and be sure that it is working correctly. Depending on the design of the code that you have, this can be difficult. As the code may not have been written with testing in mind and so won't lend itself to mocking.
You would also want to have an entire app level series of tests that make sure that all the interactions between the parts will work correctly. Depending on the app, these tests can be very brittle due to dependence on data that you have no control over.
These tests would likely be in separate suites so that they can be run independently of each of other.
If you are just getting started in writing tests for code, write the best test that you can. Tests are code and should be refactored as you go along. Write the easiest test that you can. Writing tests for legacy code is extremely difficult. The current design may be difficult to test properly. So when you are making your changes do what you can.

How do I configure paths to my javascript files in the Jasmine / Maven autogenerated ManualSpecRunner.html?

I think the question says most of it. I have an autogenerated ManualSpecRunner.html file as created by maven / jasmine plug-in and I've got it to put itself into the deployable .war by using:
<jasmineTargetDir>${basedir}/pathForMyWebapp</jasmineTargetDir>
However, all the links to js files within the ManualSpecRunner.html are hard coded file:/// references - this is a bit mental, I want them to just be the relative paths to the files that are also in the webapp i.e.
Currently it gives me this path:
file:///home/username/code/HEAD/pathForMyWebapp/js/yui.js
whereas I need it to have the far more simple
/pathForMyWebapp/js/yui.js
I have tried changing two other variables in the maven script, but neither seems to have the desired effect, neither of these configuration options do what I need, the second having seemingly no effect:
<jsSrcDir>/pathForMyWebapp</jsSrcDir>
nor
<jsTestSrcDir>/pathForMyWebapp</jsTestSrcDir>
I've looked through the documentation but think I must be missing something (also, more notes on various config params listed in https://github.com/searls/jasmine-maven-plugin/blob/master/src/main/java/com/github/searls/jasmine/AbstractJasmineMojo.java are meant to do would be helpful so I can work out if I'm doing it wrong or if it's not possible!)
Any suggestions?
[p.s. I've changed some of the path names as they've got sensitive info in them, so please ignore their oddness!]
I think I understand the source of your confusion. It looks like you're trying to direct the target of the jasmine-maven-plugin to a directory inside your project's packaged *.war file so that you can run your specs against the code after it's deployed to a server, is that correct?
Unfortunately, the plugin wasn't designed with that use in mind. The jasmineTargetDir directory is usually left at its default value of target/jasmine and wasn't intended to be bundled with your application (it's analogous to the target/surefire-reports generated by maven-surefire-plugin for Java unit tests). So the reason that the script tags in ManualSpecRunner.html point to invalid locations is because that file is generated in order to be run from the local filesystem in a browser from the workstation that's building the project (to facilitate TDD).
All of that to say, if I'm reading your intention right, I think it'd be a cool feature to build a third spec runner that could be deployed with the app and executed remotely. (Especially if the project's Jasmine specs are functional/integration as opposed to isolated unit tests.) Unfortunately that's not something the project does yet.
I'm afraid that for now, if you needed to bundle the jasmine tests and execute them on the deployed server, you would need to copy ManualSpecRunner.html and jasmine into your src/main/webapp, fix the script tag references, and then manually maintain it as files are added and removed.
Make sense?

Categories

Resources