Unit testing a modular Javascript web-app - javascript

I am building a web app using BackboneJS and RequireJS and need to implement some form of unit testing for UI interaction and data retrieval via AJAX. I have come across QUnit and Jasmine but don't really know how I can integrate this into my app.
If I am testing things such as:
Is the user logged in alright?
Has the data been received from the server ok?
Does clicking a button trigger the expected response?
Do click events work on dynamically loaded html content?
Does the app respond correctly to changes in hash/push-state urls?
I would imagine the testing has to be directly integrated into my app so as to have access to specific JS objects, work with session specific data and respond to changes in push state URLs.
How can I integrate QUnit or Jasmine (or other suggestions) into my modular app to unit test such features?

Unit testing is really simple.
You make a test HTML page. You include QUnit/NodeUnit/Jasmine/TestLibraryOfChoice
You then use requireJS and load one of your javascript modules,
and you simply test the exported object or function. That means testing the valid inputs of your module and asserting the outputs are correct.
You may have to mock out ajax and write HTML mocks

Dojo Objective Harness (DOH) is a very good unit test framework, which is browser agnostic and supports testing asynchronous functions, see here for a walkthrough guide.
However, from your test cases it looks like you want something more like an integration test?
If so Selenium is a good browser automation tool.
Crucially, neither of these tools will require you to modify your code (unless you find bugs :))

If you want to see an example where requireJS based modules are unit tested with QUnit, download the javascript reference architecture at http://boilerplatejs.org.
Disclaimer: I'm the main author of it.

Related

JavaScript autotesting in browsers without webdriver

I am developing a js library for smart tv embeded apps, and I would like to make some autotests for my code. The problem is, smarttv's do not provide webdriver interface, so it is impossible to use test runners like karma.
I need a solution that can be embedded to a custom HTML page, run tests by my scenario and log results to a div or console. Which test frameworks are capable of that?
Testcafe is most suitable E2E framework for your needs: http://devexpress.github.io/testcafe/
It does not require any additional capabilities from browser, and can be run at least with a stool if it has a browser and connection to the network.
See advanced usage with example and comparation with driver-based E2E tools here: https://60devs.com/functional-testing-of-web-applications-using-testcafe-and-nightwatch.html
So I ended up using https://github.com/substack/tape
Using this lib I bundle tests into a single js via webpack and run them directly inside a specially created smart tv app.
Automated tests is not clear question, so if you want unit tests you can use every unit test framework working in browser but it must be setup and this is not easy to be automated you will still need to run it manually.
But now is great solution called Suitest which is handling mainly TV platforms and write tests is easy even non-programmer guys, there is lot of ways and also CI integration option.
So it is easy to be configured to run automatically with each commit by some CI or whatever you want.

Testing JavaScript in CakePHP

In my CakePHP project, I'd like to run unit-tests of my JavaScript codes for the views. I'm trying to use QUnit for testing JavaScript.
Is CakePHP's testing framework capable of integrating JavaScript tests?
Where should I put the test codes?
Is there any example or information for that?
Should I consider Selenium for this purpose?
It is a php framework, what makes you think you can test another
language with that?
I would not put them into webroot/js/test and disable access to that folder via .htaccess
in the live environment
http://qunitjs.com/cookbook/
Yes, because it sounds you want to test that the whole rendered page works. I'm not sure what you exactly want to test.

How to test my selenium/jquery/AJAX project?

I am working on a tiny webapp project using ruby/sinatra. It is displaying a dashboard which is loading its data periodically using AJAX call to the REST API part of the app. (Basically the json results are transformed to some HTML on the page.)
I was driving the development of the REST API and the HTML using RSPec tests, but when I started with AJAX calls I couldn't use TDD.
So, how can I test the result of my javascript/AJAX calls? I would like to examine the resulting HTML.
I would like to avoid to use Selenium with browser to keep the project as lightweight as possible.
Cheers
Alex
The MockJax library (for example) will allow you to use TDD for your javascript and jQuery code. It will enable you to mock your AJAX calls, hence allowing you to test your client-side components in isolation.
As for testing the result of the AJAX calls, you could use the Capybara test framework; as well as supporting Selenium (which you want to avoid), it also supports a headless webdriver Capybara-webkit which should be "lighter" than Selenium as it does not load the entire browser.

Mixing Client-/Server-Side Tests

How should I structure tests containing a mixture of Selenium code (for setting up the page), and client-side Mocha code (for actually performing the tests on the client-side JS being tested)?
I am testing a client-side javascript library. Unit tests work great with Karma, Mocha, and Grunt. The unit-tests can be run locally, or via SauceLabs. The unit tests are able to test basically everything up to the part where a file is actually submitted. This part requires browser automation, and/or manual interaction, and this is what I'm struggling with.
The library in question is a Javascript file-upload library. It has features like chunking, auto-resuming, and much more. It does not require jQuery, and it works on a variety of browsers (IE7-10, FF, Safari (Mac & iOS), Chrome, Android stock browser). So, there are a lot of cases and exceptions to be covered in these tests.
Basically, I need to use Selenium to set up the page. Since I'm testing a client-side JS file-upload library I need to use Selenium to programmatically submit a file so it can actually be uploaded. Once this file has been submitted (the equivalent of selecting a file from the dialog window that appears when you try to upload a file or files online) then client-side tests can be run to ensure the UI has been drawn properly, the file has been found, etc.
I'm trying to wrap my head around how I can test this properly, and how I can set up my test suite to be extensible for the future, robust, and simple/easy to use.
Should I inject JS code to be run client-side with Selenium?
One idea is to inject the client-side JS code at opportune times with Selenium. Here's some pseudo-code of what I'm thinking:
describe("A Test", function () {
it("injects some JS", function (done) {
// Assume `getClientSideScript` loads some .js file from the filesystem,
// reads its contents, and returns the contents as a string (to be executed).
browser.safeExecute(getClientSideScript('initialize'), function (err, result) {
// At this point, the client-side library is initialized on the page.
// Assume that `uploadFile` will submit a file to the `<input type='file'>`
// element
utils.uploadFile('file.jpg', function (file) {
browser.safeExecute(getClientSideScript('test_file_submission'), function (err, result) {
assert.ok(/* something about the result */);
});
});
});
});
});
This, to me, would work, but seems like a giant PITA. I would have to come up with some convention for storing and loading the client-side scripts that are loaded. Also, two different test would have two different injected scripts so we'd have a huge collection of one-time-use scripts chillin' out in our repo. I'm also afraid of going down this road and finding out that it is a bad decision or impossible.
Anyone have any experience with this?
Mock server...I'm going to need one.
I could use Sinon.js to make mock servers client-side, or nock to have a separate server-side mock server. The server is super simple, but I believe I need to able to assert client-side that the response from the server was what was expected.
Intercepting client-side test results
Similar to the above, how would I be able to intercept asserts within the client-side code when using Selenium to automate the browser. For example, let's say I wanted to test a request-response cycle between my library and a mock server and I wanted to verify that if my library sends request A to the server it will expect response A. Selenium can't test that. I need to be able to have asserts captured client-side and outputted through Selenium.
Been bangin' my head on the wall trying to figure out the best method to do this. If anyone has any experience with anything similar, please, chime in!
I wouldn't mix these two types of tests at all. You have several different concerns here. You can still get full test coverage without having to combine tests like you are describing.
Client side unit tests (using Karma, Mocha, etc.) validate that the JavaScript code is behaving as expected.
Server side unit tests (using JUnit or whatever unit testing framework exists for your back end) validate that the server code is behaving as expected.
Integration or end-to-end tests (using Selenium) validate generally validate that multiple components are working together correctly. You can use a mock back-end for these if necessary.
You can create Karma/Mocha unit tests to verify the details of whatever processing may exist for that file upload action. Here, you should be testing edge cases of the individual JavaScript functions underneath the UI.
You can then create a Selenium test to purely test the upload action and expected result of uploading the file. You can verify that the correct elements exist on the page and have the expected properties after the upload. The JavaScript is a black box in this case. You are testing from the user's perspective. This will exercise some of the code you unit tested already, but the point of it is to test the connection between front and back ends.

Jasmine testing with Backbone and jQuery

I was trying without success for many days, i would like to know how do you test with jasmine on backbone.js... i have an html file where the app is, and an app.js file where all the js is. I use localStorage to simply prototype the app.. the structure is more or less like the todo app, but I have some problems. First of all, how to test event calls? Secondly, how to, for example, add "todos" in the test without affecting the original app? I think that the problem of this kind of conflict reside in the localstorage maybe. how to avoid it? What kind of setup do you suggest? I checked out plenty of tutorials all over the internet but no one is complete for my case and I can't really understand overall how jasmine tests click events.. Thanks for the help.

Categories