Testing for isomorphic javascript application - javascript

I have a Javascript application that consists of client-side code and server-side (Node/Express) code. Is there a testing solution that covers both client and server, or do you have to run seperate test frameworks for each?
Reason I ask is because I am trying to share code between client and server, e.g. a helper function that generates a unique id. Is this a good idea, or is it better to separate the concerns?

This is a complicated question with multiple answers. tl;dr You can do a lot of testing server side, but usually at some point you end up wanting client side tests.
In many respects, even though javascript applications can be isomorphic, the actual execution environment of client side vs. server side is very different when it comes to globals and language features. To be a completionist on testing-- one would need to have both client side and server side testing.
From a more pragmatic standpoint-- depending on the implementation and modularity of the javascript application one can choose to minimize or eliminate entirely the client side testing with the following methods:
- Use jsdom to replace the DOM api in node
- For isomorphic React applications use jest + react-addons-test-utils and/or enzyme as test harnesses into component instances
- Stub out browser globals as needed and test modules in isolation
At some point though, you almost always want to spin up a browser for "real world" testing. This could come in the form of holistic solutions like karma or rolling your own with mocha + browserify/webpack for units tests or nightwatch for integration / acceptance tests.
Besides the browser globals, the other important distinction between server side and client side tests is that server side tests never have any dynamic behavior. That lives entirely in the client. To the amount your application depends on browser features, rather than isomorphic library features (e.g. pure React) then you will find a greater and greater need for client side testing.

Related

How to test a call to a REST service

I set up a server that provides several endpoints to clients, and I have a client that uses node-rest-client package to post data to the backend.
I would like to write some unit-testing for the client side, making sure the data is properly sent to the endpoint.
I've been thinking of setting a dummy server for the testing, but that doesn't feel right.
How can i acheive such tests?
Please let me know if there's any missing data.
Thanks in advance!
EDIT
I've been looking at supertest package, but it looks like this is used to test the REST API service itself and not to test the REST calls from the client
Setting up a dummmy server is a legitimate approach as part of your "Acceptance Testing" strategy. Unlike Unit Tests, Acceptance Tests test a single component (made up of many Units) in isolation, stubbing out any external factors like databases or back end HTTP services. Having a dummy server can be a good way to go if you want to test how your client side as a whole interacts with the back end HTTP service. Acceptance Tests are generally more wide reaching, fewer in number, and slower than Unit Tests. That's why it's OK to start a dummy HTTP server.
However, if you really want to Unit Test the individual javascript unit that makes calls to the server, then this can actually be a bit tricky. You don't want to start a real HTTP server in Unit Tests because it will make them slow and unable to run in parallel.
The best approach depends on the technology you are using. For example, AngularJS provides a way to Unit Test HTTP calls called $httpBackend. Essentially it is a dummy HTTP server, but it doesn't actually go over HTTP (all requests stay in memory). This is possible because the Angular Team view testability as a priority and designed it this way from the ground up.
I don't think the node-rest-client provides a similar sort of mock HTTP server so it may prove difficult to Unit Test your client. The best approach is probably to wrap all usages of the node-rest-client in a standalone javascript object which itself has no Unit Tests, but is easy to mock out in unit tests for other parts of your client side code. This un-unit tested object can then be tested against a dummy HTTP server as part of a separate test suite, or you could even rely on your Integration Tests to catch any problems with this part.
As always though, it is best to keep your reliance on Integration Tests (which connect to an actual instance of the back end) to a minimum as they are slow and unreliable. These tests should really only be for verifying top level details such as performance, connection details, configuration compatibility etc.
If you take the wrapping approach, it is important to have as little logic in the wrapper as possible, because it will not be Unit Tested!
Note that wrapping all HTTP calls in a javascript service object is probably good practice regardless of your testing strategy, as it will confine all usages of the node-rest-client to one place in your code.

Is server side routing the same as server side rendering / isomorphic javascript?

I'm struggling to see the difference between server side routing and redirecting in it and server side rendering / isomorphic javascript. How are they different, if they are different.
Universal (Isomorphic) Javascript can execute both on the client and the server and share the application state between the two sides. It means that the application uses the same rendering engine on the client and the server. The point of it is that the client should continue from the point where the server finished its job.
Main advantages:
SEO
performance
On the other hand we have the old way of dealing with SPA (single-page applications). It runs entirely in the browser and the server is asked for data only.
This might seem like a clean and nice separation of concerns, While this can lead to a nice, clean separation of concerns, unavoidably some parts of application logic or view logic are being duplicated in both the server and the client (usually in different languages).
In addition application that is running only in client-side is not able to serve HTML to users or crawlers. This decreases the performance of the initial page load and also it's more difficult to deal with SEO.
Sources:
Scaling Isomorphic JavaScript Code
In Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
From AngularJS to React: The Isomorphic Way
Isomorphic JavaScript: The Future of Web Apps
What is Isomorphic JavaScript and When Should it Be Used?

jasmine-jquery vs selenium drivers (like Nightwatch.js) - when to choose each of those?

I would like to add integration tests to an (Backbone.js) application I am maintaining, and considering what strategy is preferable and upsides and downsides for each:
Running tests on the client side, with something like jasmine-jquery. Ideally I would like something like ember test helpers which allows writing simple synchronous looking code (while actually running async).
Running tests on the server side using selenium drivers, for example Nightwatch.js.
It is hard to tell which approach has more community and tooling around it, and which projects are more mature. Additionally, I am getting the feeling that running tests on the client side might allow better isolation of tests, while running on the server side, might create tests which run longer and heavier (also to maintain?) but allow to simulate more complex real-user scenarios
Any thoughts would be appreciated
If you care about browser compatibility, then you'll want to run end-to-end tests on different browsers on different platforms, possibly using a cloud-based cross-browser testing service such as SauceLabs, BrowserStack, TestingBot or CrossBrowserTesting.
Since you're using Backbone and are familiar with JavaScript, you might want to pick a JavaScript client for Selenium WebDriver. There are quite a few choices, with Intern leading the pack by far.

Do I need nodejs or I can rely only on Nginx?

I have an application and I have a debate with my peers on if we need to use node.js or not.
Our decision is to use angular.js for the front-end and to communicate via REST api with the app server. The application server will not be in node.js. It could be in .net or Java
Nginx will be in front as it is better for serving static files, gzip etc..
There are many options to boilerplate your angular application and many of them includes nodejs. My first approach was to use node.js as the primary web server and scale it out for solving performance issues. Although, it wasn't a good approach as node's roles isn't to act as web server. Well, here my question arrives.
By keeping in mind the two aforementioned points are there any reasons to generate the front-end including node.js ?
Is there something that I could benefited by that I haven't think of?
Here's the short answer: If you are set on using nginx in front of a .net or Java back end, and you're just looking for a deployment tool for angular.js, then just choose whatever javascript deployment tool makes sense, which may well be built with node.
What follows is a little more exposition:
I'm not quite sure what you mean by "node's roles isn't to act as web server"... if you mean in general, then that's precisely how it's generally used, if you mean your application server will be .net or java, but not javascript, then fine.
Generally speaking, nginx will perform faster for static files, but the margin of improvement over node.js is likely to be meaningless for pretty much anyone. If you need to (or it makes sense to) include node as part of your stack for angular deployment, then it could make sense to use it as your reverse proxy and just eliminate nginx altogether. The odds that you'll get measurable benefit from using nginx instead is vanishingly small.
That said... if you've already got nginx set up and moving to node instead represents extra work that you've already done once, then it loses its primary appeal.
What node.js has going for it more than any other project I'm aware of is that it's extremely capable at every level of the web stack. But it's not necessarily more capable than individual projects used in their appropriate level of the stack, and if you're not going to use it to reduce the complexity of your stack by homogenizing the technology and applications involved, then it just comes down to preference.
If you are caring about performance especially for static files, you could add caching layer as a proxy in front of your backend nginx or a server of your choice .. Varnish-cache is a good choice.
If you want to serve static files at large scale, there is yet a better solution through which you could host your static files in CDNs that will be much better solutions for your live deployments .. Clouding services are built for ease of use and also cost effective for example fastly.com is a good choice for hosting static files with a very persistent cached layer that is built on top of Varnish-Cache .. Cloud front is also another choice if you are fan of Amazon services.
More resources that might help is a comparison benchmarks having popular servers, also another benchmark existshere

Can I use node to power a web application on a separate server?

I asked this (voted to be too broad) Question while working my way through a starter book on node. Reading this book, I'm sure I'll learn the answer to this later, but I'd be more comfortable if I knew this up front:
My Question: Can I (efficiently) continue using a usual webhost such as iPage or GoDaddy to host my web application, building and hosting the front end in a simple, traditional manner through an Apache web server, and communicate with a separate Node.js server (my application back-end) via AJAX for queries and other things that I can more efficiently process via Node?
More specifically, would this be a bad programming practice in terms of efficiency and organization? In other words, would it be likely that a large scale commercial application would ever be handled via this method?
Yes, you can separate the front-end of your web application and the APIs that power it. In fact, this is a very common configuration, especially for "large scale commercial applications".
Where you draw the separation line between the two specifically depends on what you are doing, how you're doing it, and what your needs are. Also, in terms of hosting, remember that if you're accessing something server-side across the internet, you're adding extra latency to everything. Consider getting off Go Daddy and using another host that gives you more flexibility, such as a VPS provider.
It's ok. Actually, this is how things shoud be done. You have a backend API on a separate server and lots of apps which are using the API. Just go with Nginx server, check this Apache vs Nginx.
Yes you can use node js as a part of some big application. It depends on wich type of interaction you would like to get. Is it comfortable to you to mix technologies? Then node is pretty good thing to work over web. I've finished a part of big nodejs-ruby-php-c-flash application (my part was nodejs) for very large data mounts. This application have different levels of interaction. Sometimes I use 2 languages at one time to create each part of my application the best for task I'm working on. There is applications that initiate, run and destroy mutiple OS instances. So using of multi environmental application not so hard.

Categories

Resources