I have code that is embedded in html as follows:
<script type="text/javascript">
function add(a, b) {
return a+b;
}
</script>
And I was wondering if anyone knew if this was possible to test using Jasmine and the JQuery fixtures? I am new to Jasmine and don't understand how to test this kind of code.
Thanks.
I think #pawlik is suggesting it is better belonging in it's own .js file. The only option I considered to answer your question is to source this file as a fixture (using the loadFixtures('file') method) but you normally do this with fragments (nothing that contains html, head or body tags) and if there are any on DOM ready events which are fired in script tags or includes they may not place nicely with jasmine.
Saying you can't change the file may not mean you cannot change the structure (ie. push it out to a separate script file and refer to that in the main HTML page.) In many cases you should refactor the structure of your code to facilitate testing.
Since you are new to jasmine, when writing tests you tend to test javascript functions/methods on their own, or with fragments of HTML (if you are doing DOM-based testing) as fixtures. You wouldn't normally use a complete HTML page and write tests for it, this is more of an end-to-end / functional test and is not the primary goal of jasmine.
BTW you are missing the end double-quote of "text/javascript <--
Related
I have a website that's build using JS for the client-side and PHP for the backend with a MySQL backing DB. I started unit testing everything, and the back-end was fairly straightforward using PHPUnit.
In the same spirit, I wanted to start testing the client-side and opted for QUnit. However, we're using Kendo UI and I'm a little lost as to how I could automate my tests without practically reinventing the wheel.
Say I have a modify.js file, where after I define everything I have the following jQuery:
$(document).ready(function() {
$("#user-menu").kendoMenu();
var modify = $('#modify');
kendo.bind(modify, modifyViewModel);
kendo.bind($('#numTagWindow'), numTagWindow);
modifyViewModel.initForm();
$(window).on("resize", function() {
kendo.resize($("#trip"));
});
});
Here, modify.php is an html file with some PHP and corresponds to the view that users get when they go to modify some corresponding setting. In a separate jsTest.js file which is incuded in modify.php, I have all my QUnit tests pertaining to modify.js.
My question is the following: What would be the standard approach for unit testing here, automated or otherwise? As it stands, since the same HTML page is being used for numerous tests my only current option is manually trying out every single option to see if the assertions pass.
In the case where a said function depends on the type of pre-selected input, this gets even worse. I'm forced to put a different number of expected assertions based on input (admittedly, this may be a design flaw).
How should I approach this? Would it be possible to just 'reset' the page using multiple $(document).ready's and run the tests in that manner? In that case, what would be the easiest way to provide the user input to the client-side code?
I haven't ever tested an app with KendoUI before, but I assume it's similar to any other front-end library... that is, you can either use whatever built in tools they have, mock out the library, or do more "integration" testing rather than unit testing. For your minimal example above mocking isn't so bad, but you can imagine it getting out of hand. As such, I'd say integration testing is best, and you can use QUnit for that (along with jQuery), you just have to "write" all of the actions you're testing.
Of course, you also need to have some strategy for making the tests atomic by resetting the HTML blocks, or separating the various blocks into different test files, or something else...
Here is an uber basic example of a QUnit test file with an html fixture that gets reset after each test. Note that by using the document.ready() call in your source code you basically negate the ability to do any of this. If you strip that out and an init() method of some sort things will work much better.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="lib/qunit-1.14.0.css" />
</head>
<body>
<div id="qunit"></div> <!-- required! -->
<div id="qunit-fixture">
<!-- HTML to be reset for each test -->
<div id="user-menu"> <!-- whatever you need in here --> </div>
<!-- whatever other HTML you need for these tests -->
</div>
<script src="lib/qunit-1.14.0.js"></script>
<script src="path/to/source-code.js"></script>
<script>
QUnit.test("Test some trigger", function(assert) {
myCode.init(); // used to be in your document.ready()
$("#someTriggerButton").click();
assert.ok($("#someElement").hasClass("foobar"), "Ensure the element has the correct class after clicking trigger");
});
// Note that after this test runs, before the next test runs,
// the HTML inside of #qunit-fixture will be reset to its value when freshly loaded
QUnit.test("Another test", function(assert) {
// ...
});
</script>
</body>
</html>
So there's something to start with... This is intended to be used with HTML fragments, not entire pages. Of course, there are lots of other ways to do things. Unfortunately, your question is a bit too vague to really give you a specific "solution". If you try something out and have issues, please post another question on here and we'll try to help.
We have a single page application created using AngularJS. We'd like to validate markup of that application. The problem is that markup is mostly generated with script, so that if we pass source code to validator, the result is only partial.
Currently we're looking into testing the page in the following way.
Open the page with Selenium web automation library.
Do some actions.
Dump current HTML to file.
Process it with standalone validator.
It's quite time consuming to implement this flow, as we would need to hardcode all the ways to use an application, so I'd like to ask: is there any other ways to do it?
With AngularJS Your should NOT have to do validate every variation of your page as DOM changes with script in your Single Page Application as long as you stick with AngularJS programming model and stick to the following:-
Validate every HTML file/fragment.
These are Angular templates/partials OR any HTML files you may have (index.html).
Use grunt based html validator plugins like this so that grunt workflow can ensure that the HTML is valid even before it is committed in to your source code repository. Such plugins can validate HTML fragments.
Use built-in AngularJS directives to manipulate the DOM.
e.g. ngSwitch, ngView, ngIf etc. instead of any custom stuff using jQuery or other mechanism.
AngularJS already ensures a valid HTML DOM. That means your resulting HTML is always going to be valid.
Have you consider using Angular e2e:
http://docs.angularjs.org/guide/dev_guide.e2e-testing
This allows you access to get/validate elements from html like:
expect(element('#email').html()).toBe('something');
From Angular Documentation using jazmine:
describe('Buzz Client', function() {
it('should filter results', function() {
input('user').enter('jacksparrow');
element(':button').click();
expect(repeater('ul li').count()).toEqual(10);
input('filterText').enter('Bees');
expect(repeater('ul li').count()).toEqual(1);
});
});
Update 1
Then you can try something like:
https://github.com/peterjwest/html_validator/blob/master/demo.js
I call this GUI level Testing. Visual Studio has an excellent browser recording and playback tool, which allow a tester to create Automated tests which validate anything the tester wants.
Here's a video: https://onedrive.live.com/?cid=ae5cd7309cccc43c&id=AE5CD7309CCCC43C%21183&sff=1&authkey=%21ANqaLtCZbtJrImU&v=3
You'll need to have the Premium edition to do this. In addition, I've heard good reports about Selenium, in fact, MSFT themselves have endorsed it.
I'm trying to write some simple tests on JS code that can be run from the command line to test code that has nothing to do with HTML, documents or user interface. To do this I need to include one file within another to pull the code being tested into the test script.
What I've found involved HTML or DOM to do the job; for example, something like
document.write( ) or some such.
Is there a simple way to do this? I'm imaging something like
include( "code2test.js" );
I'd appreciate any help in solving this. Can JQuery help or does it have to be used in a HTML/browser context?
Thanks in advance.j
It sounds like you just need two script tags:
<script type="text/javascript" src="code2test.js"></script>
<script type="text/javascript" src="testscript.js"></script>
If that doesn't work, try reversing the order.
Sounds like what you need is Require.js. It's designed to allow inclusion of javascript in the web page using javascript rather than script tags. For example, instead of:
<script scr="foo.js"></script>
<script>
use_foo_here();
</script>
using Require.js you can write:
require(["foo.js"],function(foo){
use_foo_here();
})
The cool thing about Require.js is that it can even be used on Node.js. So for command line invocation you can use Node to run your scripts and the require() statements would work just like it does on the web page.
If you just want access to a javascript engine (eg Webkit) without using a browser, you can use something like nodeJS or PhantomJS
We are using Chutzpah as our test runner, and are very satisfied with it. We write the tests using Jasmine. Jasmine does not require a DOM.
At the start of the test file, the references to the JavaScript files under test are added, like this:
/// <reference path="dependantModule.js" />
/// <reference path="code2test.js" />
and then the test code follows:
describe("code2test test suite", function () {
it("should do something"", function () {
var result;
// Assuming code2test.js exposes a global called 'code2test'
result = code2test.doSomething();
expect(result).toEqual("the expected result");
});
});
Chutzpah uses the PhantomJS headless browser. So you can write tests that interact with the DOM if required.
We run the tests through Chutzpah from the command line for continuous integration, but also run them inside Visual Studio 2010 using the Chutzpah Visual Studio Extension. I believe integration of Chutzpah in VS2012 is even easier, but haven't tried it myself.
The tests can also be ran inside a 'real' browser, which is great for debugging. My browser of choice for debugging the test code is Chrome - the developer tools are great.
I'd like to build my own, but I'm not sure about the best way to do it. A partial is a template that is only a part of another bigger template and which can be inserted into multiple other templates at will.
Templating itself is fairly basic, just string exctraction and concatenation, but clientside partials have me a little stumped.
Here are a few methods I thought about:
1,
I could write a javascript helper function that loads partials through ajax into some form of local storage I suppose, and all subsequent templates that require that particular partial would first look inside local storage. I think this method isn't very safe because local storage isn't always guaranteed. And if I can't save them into local storage, partials would result in too many ajax calls.
2, I could put them all into script tags inside my main html file. This would work reasonably well, especially with head.js (to enable parallel loading of script tags), but still - I think each script tag is a separate call to the server right? That doesn't exactly improve the situation.
3, I could put all templates into a single script tag (or html I guess) and manually filter through some kind of delimiter...like: "#template1(blabla template1 string) #template2(blablabla template2 string) and put those strings into globals.
This would result only into a single call to the server, all the rest is done on the client.
Suggestions? I have looked at existing templating engines, but I can't really determine how they do it. The code is pretty complicated
The approach I took to spec out template calls and on-demand loads for the spec/rewrite of jQuery templates is to pipeline it.
See section 9 of the (early) draft spec, and see the conformance suite tests at the bottom for an example of custom on-demand template loading (Testcase "Main calls and Loaded just in time!" is the relevant one).
The basic gist is that plugin loaders (written in JS) get to hook in between-parsing and compiling to inspect the parse tree. A plugin pass gets an object mapping template names to parse trees. If they see any partial template selectors (to use your parlance) they can try and load any unresolved templates using AJAX calls or file I/O on Node.js, and add the partials to the input object to cause the compiler to compile the just loaded partials along with the public templates.
Efficiency-wise, see the benchmarks. I'm in the process of migrating the code to github : https://github.com/mikesamuel/jquery-jquery-tmpl-proposal in case you want to collaborate.
When building webapps with MVC web framworks like Django, Kohana, Rails and the like, I put together the application without JS-driven components initially, and then add them afterwards as "improvements" to the UI.
This approach leads to non-intrusive JS, but I don't have a good "standard" way of how to go about organizing the JS work. Most of the JS I write in apps like these are 10-30 line JQuery snippets that hook into some very specific part of the UI.
So far I often end up inlining these things together with the part of the UI they manage. This makes me feel dirty, I'd like to keep the JS code as organized as the python / php / ruby code, I'd like for it to be testable and I'd like for it to be reusable.
What is the best way to go about organizing JS code in a setup like this, where we're not building a full-blown JS client app, and the main meat is still server side?
I am also very interested in what other people have to say about this. The approach I've taken is to use object literal notation to store the bulk of the function, and store these in one file included on all pages (the library)
uiHelper = {
inputDefault:function(defaulttext){
// function to swap default text into input elements
},
loadSubSection:function(url){
// loads new page using ajax instead of refreshing page
},
makeSortable:function(){
// apply jQuery UI sortable properties to list and remove non javascript controls
}
}
Then I include a .js file on any page that needs to use the library that ties the elements on that page to the function in the library. I've tried to make each function as reuseable as possible and sometimes the event binding function on the page calls several of my library functions.
$(document).ready(function(){
$('#mybutton').live('click',uiHelper.loadSubSection);
//more complicated helper
$('#myotherbutton').live('click',function(){
uiHelper.doThisThing;
uiHelper.andThisThing;
});
});
edit: using jsDoc http://jsdoc.sourceforge.net/ notation for commenting for these functions can produce documentation for the 'library' and helps keep your code easy to read (functions split by comments).
The following question is along similar lines to your own - you should check it out...
Commonly accepted best practices around code organization in JavaScript
When dealing with JS code, you should first analyze whether it will be used right away when the page loads. If it's not used right away (meaning the user must do something to invoke it) you should package this into a JS file and include it later so the load time is perceived faster for the user. This means that anything that the user will sees should go first and JS related to the functionality should be imported near the end of the file.
Download this tool to analyze your website: http://getfirebug.com/
If the JS code is small enough, it should just be inline with the HTML.
Hope that helps a bit.
For quick little user interface things like that I put everything into a single javascript file that I include on every page. Then in the javascript file I check what exists on the page and run code accordingly. I might have this in UIMagic.js for example. I have jQuery, so excuse those jQuery-isms if they aren't familiar to you.
function setupMenuHover() {
if ($("li.menu").length) { // The page has a menu
$("li.menu").hover(function() { ... }, function() { ... });
}
}
$(setupMenuHover);
function setupFacebookWizbang() {
if (typeof FB != "undefined") { // The page has Facebook's Javascript API
...
}
}
$(setupFacebookWizbang);
I've found this to be a sane enough approach.
My preferred method is to store inline javascript in it's own file (so that I can edit it easily with syntax highlighting etc.), and then include it on the page by loading the contents directly:
'<script type="text/javascript">'+open('~/js/page-inline.js').read()+'</script>'
This may not perform well though, unless your templating library can cache this sort of thing.
With Django you might be able to just include the js file:
<script type="text/javascript">
{% include "js/page-inline.js" %}
</script>
Not sure if that caches the output.
If you are still worried about being 'dirty', then you could check out the following projects, which try to bridge the server/client side language mismatch:
http://pyjs.org/ (Python generating JavaScript)
http://code.google.com/webtoolkit/ (Java generating JavaScript)
http://nodejs.org/ (JavaScript all the way!)