Testing breeze application - javascript

I am doing an application with durandal, breeze, and knockout. I have started to implement some test. The first problem that I have had is to decide what I should test and what not. I know that I should test everything, but it is not always possible in a little company.
My second problem is how I can test my calls to the server. I have seen some information in the breeze page about testing. Also I have seen the DocCode example. But I would like to know more opinions about how I can do that.
My questions are:
What do I should test in the breeze calls?
I would like to test this, emulating the backend. Is it possible? Any example?
Any advice or comment would be great

Wow ... that's a big question!
There's is a little on this subject in the documentation. Not nearly enough to be sure.
I'm guessing that you are fairly new to JavaScript testing. If you've seen DocCode, you know that we use QUnit around here. Many prefer Jasmine, Mocha or something else; I can only speak to QUnit.
First step is learn QUnit. It's not hard. QUnit's own intro is good. I like Ben Alhman's slide deck.
Next I'd practice with small tests of your business logic that does NOT go over the wire. Could be any interesting logic in a ViewModel or perhaps some calculated property in a model (entity) object.
You can test a VM's interaction with a "DataContext" quite easily without going over the wire. Create a "FakeDataContext" and inject that into your tests instead of the real one. Alternatively you could "monkey patch" the real "DataContext" in strategic places that turn it into a fake.
When faking the DataContext, I find it useful to leverage Breeze's ability to confine queries to the local cache. The local cache serves as an in-memory surrogate for data that would otherwise have been retrieved from the server.
This can be as simple as setting the FetchStrategy of the manager's default QueryOptions ... perhaps like this
var queryOptions = new QueryOptions({
mergeStrategy: MergeStrategy.PreserveChanges,
fetchStrategy: FetchStrategy.FromCache
});
var entityManager = new EntityManager({
serviceName: "yourEndpoint",
queryOptions: queryOptions
});
Now your queries will all be directed to the cache (unless they have an explicit QueryStrategy of their own).
Now make it useful by populating the cache with test data. There are numerous examples of faked entities in DocCode. Here's an example of a faked Customer:
var testCustomer = manager.createEntity('Customer', {
// test values
CustomerID: testCustomerID,
CompanyName: testCustomerName,
...
}, breeze.EntityState.Unchanged); // as if fetched from the database
If I need the same test data repeatedly, I write a "Data Mother" that populates an EntityManager with test data for me.
I can do a lot of testing this way without ever hitting the server. The whole time I'm working with the Breeze entities in JavaScript ... much as I do in production code. I don't have to learn a mocking library or inject another tool.
Another approach - harder, lower level, but more powerful - is to replace the Breeze default AJAX adapter with a fake that returns test JSON values as if they had come from the server. You can use a tool like Fiddler to make fake JSON from actual payload snapshots. You can also use this trick for simulating server-side save behavior.
Update 3 May 2013
The DocCode Sample includes a new TestAjaxAdapter for simulating server responses as I just described. Check out the testAjaxAdapter.js and see how to use it in testAjaxAdapterTests.js. This particular version of DocCode is only on GitHub right now but it will be published officially in the release immediately after v.1.3.2.
... end of update; back to original post ...
Does faking the JSON stream within your fake AJAX adapter seem like too much of a PITA?
Break out your mad Breeze skills and write a custom JsonResultsAdapter to create those fakes. Have your fake AJAX adapter return an empty array for every query request. Then you can do anything you want in the extractData and visitNode methods of your JsonResultsAdapter.
I trust it is obvious that you can fake your server-side controller too. Of course your tests will still make trips "over the wire" to reach that controller.
Hope these clues are sufficient to get you headed in a satisfactory direction.
Update 30 April 2013
Breeze will need metadata to do its thing. Your metadata comes from the server. Calling the server for metadata would seem to defeat the purpose of running tests entirely disconnected.
So true. Now I'm not a stickler on this point. I don't mind hitting the server for metadata at the top of a test module ... exactly once ... and then running the rest of my tests without going to the server for metadata. But if you're a purist or you just don't want to do that, you can write the server-side metadata to a JavaScript file on the server and load that script statically on your test runner's HTML page just like any other script.
For an example of this technique, look at App_Data/WriteMetadataScriptFiles.cs which generates a JavaScript file for the Northwind model in the forthcoming (later this week) v.1.3.2 DocCode sample. The DocCode tests load JavaScript files dynamically with require.js. The metadataTests.js test file shows how to load the generated northwindMetadata.js with require. You don't have to be that clever if you're not using require.js.
Note to self: write some samples illustrating these techniques.

Related

NestJs: Is there a way to generate a resource, already wired to a TypeOrm entity?

I'm playing around with NestJs, for the purpose of automating REST API creation as much as possible. So far, I do not see any quick way to create a fully functional resource.
For example, if I use the Nest CLI like this:
nest g resource
And call my resource "posts", I get a module, a controller, a service, dto's and an empty entity
In order to make it functional, I would need to manually go through every method of the PostsService, remove the placeholder, and wire it to the corresponding entity method. For example, this needs to be altered:
findAll() {
return `This action returns all posts`;
}
to:
findAll(){
return this.postsRepository.find()
}
Not to mention, that I need to add various decorators and imports. In my opinion, this undermines the whole idea of CRUD generator. A lot of files are created for me, but they need to be altered.
Is there any way in Nest to create a fully functioning resource(of course i would still need to manually set the fields of the entity), with all parts wired to each other correctly?
I also tried to find something similar. And this is the best what I found https://github.com/ashinzekene/generator-nestjs-app
I think if such a thing existed, then it should have been mentioned in this repository. https://github.com/nestjs/awesome-nestjs
But it's not. Maybe I'm wrong 😑
The purpose of nest isnt to get up and running asap -> You would probably want to use something a little bit more user friendly / or one with a more guided workflow.
in terms of what the generator is giving you...
Controller Only deals with the request / response being recieved and sent... it doesnt have any other type of functionality...
DTO think of it like an interface but with more functionality , as you can add data-validation / etc to make sure the request object is formated properly...
Service Exposes the methods that contain all of our business logic. for a crud app, this would be where your actual get post put patch delete would be ... and how the data us modified in your db. Then once this finishes it would return the response if any to the controller which sends the info out.
this is helpful for many reasons... one if our project has 200 endpoints and 40 people working in different teams you dont want each team to have a different way of doing things, also you want it to be clear where each thing is... if you endpoints need to be changed , you simply go to your controller... if the logic needs to change, you go to that service etc...
The Purpose of nest is to give you a framework for extremely modular apps / essentially everything decoupled..
think of it in terms of an express... you could have a single page express app that just has everything in one place... or you could have every single thing on it's own area...
esentially nest doesnt do anything crazy that express cant, it's just the underlying inversion of control (the .main file which calls the app.module which builds all the different pieces that are needed for that endpoint / app / service / or etc.)
If you just want to use nest because it seems shiny , id consider looking up something like fastify or / even appsmith / or something else like that...

Can I get performance testing in node.js like a unit testing

I need performance testing/tuning in nodejs.
In CI/CLI, like a unit test.(target to function call. not networking.)
I use mocha timeout() now.
var dictionary_handle;
it ("Dictionary.init_dictionary timeout", function(done) {
dictionary_handle = Dictionary.init_dictionary(dictionary_data);
done();
}).timeout(1000);
it ("Linad.initialize timeout", function(done) {
Linad.initialize(function(err){
done();
});
}).timeout(6000);
But it is not enough.
I need that function.
able using in CI.
execute multiple time
output performance metric information
I believe you're looking for a some form of microbenchmark module. There is a number of options and your requirements match them all so I cannot come up with the best candidate, you will need to perform your own investigation.
However given you have performance-testing tag added I can give you a generic piece of advice: when it comes to any form of performance testing - you need to make sure that your load test exactly mimics your application under test real life usage.
If your application under test would be a NodeJS-based web application - there are a lot of factors which need to be considered apart from single functions performance so if this is the case I would recommend considering a protocol-level based load testing tool, if you want to stick to JavaScript you can use something like k6 or consider another standalone free/open-source load testing solution which can simulate real users close enough with minimal efforts from your side.
Dmitri T is correct, you need to be careful with what and how you test. That being said, https://github.com/anywhichway/benchtest require almost no work to instrument existing unit tests, so it may be worth using.

Breeze js - how to create an entity from a JSON string and import it into the breeze cache

I am working on a mobile single page site that uses breeze js, angular js, web API, entity framework, etc.
To optimize the site, I included the breeze metadata in a bundled JavaScript that contains all the other JavaScript the site needs. Ideally, all I would like the browser to request is index.html, which should contain everything the app needs to run including bundled and minified inline styles and JavaScript.
However, just as the breeze metadata is very important for the site to function and is therefore embedded in the bundled JavaScript, there is also a required complex entity (with some deep navigation properties to some other entities) that must also be present for the site to be fully functional. I would like to embed this entity and all the entities it references in the bundled JavaScript as well. How can I do this?
I can always create a JSON string that represents this entity and all the entities it references. Then embed that JSON string in the bundled JavaScript along with the rest. However, how can I easily import this complex entity into the breeze entity system using the entity JSON string I have embedded in JavaScript? Or is there a better solution to preload the breeze entity system with a complex entity without having to make a request for that entity from the server?
I would also like to avoid writing server code to spit out JavaScript that creates the entity on the client.
Simplest approach would be to use the "initializer" argument to the EntityManager.createEntity call.
See
http://www.breezejs.com/documentation/creating-entities and http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html#method_createEntity
This call looks this.
myEntityManager.createEntity("Employee", { lastName: Smith", firstName: "John" });
So in your case you could try:
var initialValues = JSON.parse(json);
myEntityManager.createEntity("Employee", initialValues);
Depending on your use case you may want to also set the 'entityState' of this newly created entity as well.
Here's a technique I often use to create entity data for automated tests:
Preparation
prime an EntityManager with the entities (and entity graphs) that you want available at launch.
export as a string with var exported = manager.exportEntities();. The exported string has the metadata embedded in it so you won't have to bring that down separately. Two-for-one!
capture the contents of exported to a JavaScript file that you load as script in index.html. My "capture" process is usually just to display in the console and scrape it.
Usage
Now when you need it:
load that JavaScript metadata+data file.
create a new EntityManager (remember to target the same dataservice endpoint).
import the entities you captured in your script: manager.importEntities(launchData);.
And you are good to go.
Read up on the EntityManager exportEntities and importEntities methods.
Example
One place you can see a variation on this technique is in the test directory of the "Zza-Node-Mongo".
I personally do not combine the data with the metadata so I export using the "no metadata" option. I put the metadata in one script and the data-to-load-on-launch (lookups usually) in a separate script and load both in index.html.
Caution
You say
to optimize the site, I included the breeze metadata in a bundled JavaScript that contains all the other JavaScript the site needs. Ideally, all I would like the browser to request is index.html, which should contain everything the app needs to run including bundled and minified inline styles and JavaScript.
Beware of premature optimization
I rather doubt that you will measurably improve the launch time of the app by embedding metadata and launch date in script files. Maybe some of the time if the browser caches these scripts. But that comes with its own risks and isn't a reliable strategy.
The data you want has to come over the wire to the client one way or another. It isn't self-evident that loading a script file - even a minimized script file - is any faster than pulling the metadata and launch data (both gzipped) down from the server via a web api AJAX call.
The techniques I described do speed up testing because I have to recreate metadata and the launch data before each test. I can measure the performance gain from avoiding repeated trips to the server. I gain nothing for the first trip ... which is the equivalent of your application launch.
Be mentally prepared to discover that your hard earned optimization efforts did not improve launch times ... and might even make them worse for some users.

Testing Javascript on Client end

I wrote a real time js app that has the following stack:
Node.js for server
Socket.io as a communication layer
JQuery on the front end to manipulate dom etc.
For #1, I have absolutely no problem testing. I am currently using nodeunit which is doing a fantastic job.
For #3, I am having a little trouble trying to figure out my approach to testing.
My browser side code is generally something like that:
var user = {
// Rendered by html
id: null,
roomId: null,
foo: null,
// Set by node server.
socket: null,
clientId: null,
...
}
$('button#ready').click(function() {
socket.emit('READY');
});
socket.on('INIT', function(clientId, userIds, serverName) {
user.clientId = clientId;
user.foo = (serverName == 'bar') ? 'bar' : 'baz';
});
The main part which I would like to test involves checking if the js on the browser side will react accordingly when the server fires a certain packet with specified arguments:
i.e.
user.foo = (serverName == 'bar') ? 'bar' : 'baz';
Any good recommendations on how to approach this?
Check out Mocha. It has a very nice support to run both in node and in the browser. I found it vastly more preferable to other options (Jasmine, Vows).
Also, instead of running a heavy-weight integration setup like Selenium, I'm running both server tests and browser tests in one process using Zombie. It allows for some beautiful integration workflows (like triggering something on the browser and then verifying effects on the server).
YMMV however as Zombie is relying on JSDOM (DOM re-implementation in Javascript). There are rough edges on yet patched/fixed, stuff breaks. If that's a problem, run Mocha in the browser using real browsers (harnessed through Selenium perhaps).
As much as Pivotal's support for jasmine is a bit hit and miss (minimal new development, lots of unanswered issues/pull-requests on their github), Jasmine is a really good tool for testing client-side code, mainly because of jasmine-jquery.
Jasmine's general approach is pretty solid and Jasmine-Jquery has a lot of great matchers for testing the DOM, as well as great DOM sandboxing.
I found testing on the client-side a challenge, mainly because I had to stop being so rigid and prescriptive in my tests.
Generally, you should approach client-side testing in a kind of 'fuzzy' way, testing the DOM hierarchy too specifically is a road to hell. Test things like, "Does the page contain these words" over "Does div id#my-div contain a ul with 3 li's with content that matches this regex"
The latter is how I started doing tests but I found it incredibly time consuming and fragile; if the designer (me) want to mess with the structure, it'd could unnecessarily break many tests. The only way to get around it is to create 'widgets' for each component, which would be ideal but as I said, very time consuming, it actually became a running joke at my office: "how many tests you done this week Tim? 2? 3? Wow 3 tests. Good work."
Anyway…
You can get 90% of the benefit of doing client-side testing by testing loosely, and focusing on what's important, such as workflow and data 'presence' over specific content in a specific location in the hierarchy on the page.
edit: Also, ensure you break the business logic into units that are independent of the DOM, as much as humanly possible. That makes your life a lot easier, and generally leads to better architecture, which is a plus.
edit 2: You might want to look into how the Rails world does this using Capybara/Cucumber or Selenium.

Test-driven development of JavaScript web frontends

This might sound a little dumb, but I'm actually a bit confused how to approach JavaScript testing for web frontends. As far as I'm concerned, the typical 3-tier architecture looks like this:
Database tier
Application tier
Client tier
1 is of no concern in this question. 2 contains all the program logic ("business logic") 3 the frontend.
I do test-driven development for most projects, but only for the application logic, not the frontend. That is because testing the UI is difficult and unusual in TDD, and normally not done. Instead, all application logic is separated from UI, so that it is simple to test that logic.
The three tier architecture supports this: I can design my backend as a REST API which is called by my frontend. How does JS testing fit in? For the typical three-tier-architecture, JS (i.e. JS on the client) testing doesn't make much sense, does it?
Update:
I've changed the question's wording from "Testing JavaScript in web frontends" to "Test-driven development of JavaScript web frontends" to clarify my question.
Remember what the point of unit-testing is: to ensure a particular module of code reacts to some stimuli in an expected manner. In JS, a significant portion of your code, (unless you have some lifecycle framework like Sencha or YUI) will either be directly manipulating the DOM or making remote calls. To test these things, you simply apply traditional unit-testing techniques of dependency injection and mocking/stubbing. That means you must write each function, or class, that you want to unit-test to accept mocks of the dependent structures.
jQuery supports this by allowing you to pass an XML document into all traversal functions. Whereas you might normally write
$(function() { $('.bright').css('color','yellow'); }
you'll instead want to write
function processBright(scope) {
// jQuery will do the following line automatically, but for sake of clarity:
scope = scope || window.document;
$('.bright',scope).css('color','yellow');
}
$(processBright);
Notice we not only pull the logic out of the anonymous function and give it a name, we also make that function accept a scope parameter. When that value is null, the jQuery calls will still function as normal. However, we now have a vector for injecting a mock document that we can inspect after the function is invoked. The unit-test could look like
function shouldSetColorYellowIfClassBright() {
// arrange
var testDoc =
$('<html><body><span id="a" class="bright">test</span></body></html>');
// act
processBright(testDoc);
// assert
if (testDoc.find('#a').css('color') != 'bright')
throw TestFailed("Color property was not changed correctly.");
}
TestFailed could look like this:
function TestFailed(message) {
this.message = message;
this.name = "TestFailed";
}
The situation is similar with remote calls, though rather than actually injecting some facility, you could get away with a masking stub. Say you have this function:
function makeRemoteCall(data, callback) {
if (data.property == 'ok')
$.getJSON({url:'/someResource.json',callback:callback});
}
You would test it as such:
// test suite setup
var getJSON = $.getJSON;
var stubCalls = [];
$.getJSON = function(args) {
stubCalls[stubCalls.length] = args.url;
}
// unit test 1
function shouldMakeRemoteCallWithOkProperty() {
// arrange
var arg = { property: 'ok' };
// act
makeRemoteCall(arg);
// assert
if (stubCalls.length != 1 || stubCalls[0] != '/someResource.json')
throw TestFailed("someResource.json was not requested once and only once.");
}
// unit test 2
function shouldNotMakeRemoteCallWithoutOkProperty() {
// arrange
var arg = { property: 'foobar' };
// act
makeRemoteCall(arg);
// assert
if (stubCalls.length != 0)
throw TestFailed(stubCalls[0] + " was called unexpectedly.");
}
// test suite teardown
$.getJSON = getJSON;
(You can wrap that whole thing in the module pattern to not litter the global namespace.)
To apply all of this in a test-driven manner, you would simply write these tests first. This is a straightforward, no frills, and most importantly, effective way of unit-testing JS.
Frameworks like qUnit can be used to drive your unit-tests, but that is only a small part of the problem. Your code must be written in a test-friendly way. Also, frameworks like Selenium, HtmlUnit, jsTestDriver or Watir/N are for integration testing, not for unit-testing per se. Lastly, by no means must your code be object-oriented. The principles of unit-testing are easily confused with the practical application of unit-testing in object-oriented systems. They are separate but compatible ideas.
Testing Styles
I should note that two different testing styles are demonstrated here. The first assumes complete ignorance of the implementation of processBright. It could be using jQuery to add the color style, or it could be doing native DOM manipulation. I'm merely testing that the external behavior of the function is as expected. In the second, I assume knowledge of an internal dependency of the function (namely $.getJSON), and those tests cover the correct interaction with that dependency.
The approach you take depends on your testing philosophy and overall priorities and cost-benefit profile of your situation. The first test is relatively pure. The second test is simple but relatively fragile; if I change the implementation of makeRemoteCall, the test will break. Preferably, the assumption that makeRemoteCall uses $.getJSON is at least justified by the documentation of makeRemoteCall. There are a couple more disciplined approaches, but one cost-effective approach is to wrap dependencies in wrapper functions. The codebase would depend only on these wrappers, whose implementations can be easily replaced with test stubs at test-time.
There is a book titled Test-Driven JavaScript Development by Christian Johansen that might help you. I have only looked at some of the samples in the book (just downloaded a sample to Kindle the other day) but it looks like a great book that addresses this very issue. You might check it out.
(Note: I have no connection with Christian Johansen and no investment in sales of the book. Just looks like a good thing that addresses this problem.)
I have a similary architected application with JS client tier. In my case i use our company's own JS-framework to implement client tier.
This JS framework is created in OOP-style thus i can implement unit-testing for core classes and components. Also, to cover all user interactions (which can't be covered using unit-testing) i am using Selenium WebDriver to do an integration testing of framework visual components and test them under different browsers.
So, TDD can be applied to JavaScript development if code under test is written in OOP-manner. Also integration test is also possible (and can be used to do some kind of TDD).
Have a look at QUnit, as well, for unit tests of JavaScript methods and functions.
You can test your application from a user perspective with tools such as Rational Functional Tester, the HP tools or other equivalent software.
These tools test the application as if a user was sitting in front of it, but in an automated fashion. This means that you can test all three tiers at the same time, and especially the Javascript which may be difficult to test otherwise. Functional testing like this may help to find UI bugs and quirks with how the UI is using the data pushed out by your middle tier.
Unfortunately these tools are very expensive, so there may be other equivalents (and I'd be interested to know of such tools).
In our company we use jsTestDriver. It's a feature rich environment for testing frontend.
Take a look at it.

Categories

Resources