Automated Unit Testing with JavaScript?

There are many javascript unit test framework out there (jsUnit, scriptaculous, ...) but jsUnit is the only one I know that may be used with an automated build.

There are many javascript unit test framework out there (jsUnit, scriptaculous, ...) but jsUnit is the only one I know that may be used with an automated build. If you are doing 'true' unit test you should not need AJAX support. For example, if you are using an RPC ajax framework such as DWR, you can easily write a mock function : function mockFunction(someArg, callback) { var result = ...; // some treatments setTimeout( function() { callback(result); }, 300 // some fake latency ); } And yes, JsUnit do handle timeouts : Simulating Time in jsUnit Tests.

I'm just about to start doing Javascript TDD on a new project I am working on. My current plan is to use qunit to do the unit testing. While developing the tests can be run by simply refreshing the test page in a browser.

For continuous integration (and ensuring the tests run in all browsers), I will use Selenium to automatically load the test harness in each browser, and read the result. These tests will be run on every checkin to source control. I am also going to use JSCoverage to get code coverage analysis of the tests.

This will also be automated with Selenium. I'm currently in the middle of setting this up. I'll update this answer with more exact details once I have the setup hammered out.

Testing tools: qunit JSCoverage Selenium.

Yes, please share it. Thanks – melaos Feb 10 '09 at 7:49 Did you ever get this set up? How did it go?

– El Yobo Aug 16 '10 at 4:34 2 I did get this set up, but using slightly different technologies. I used JS Test Driver to run the unit tests in each browser (rather than Selenium), using the QUnit Adapter (code.google.com/p/js-test-driver/wiki/QU...). Another at my current employer I am using the Jasmine test framework, and running the tests in Jasmine Node (github.com/mhevery/jasmine-node) which avoids the delay of using a browser.

I use my own little ruby project (github.com/karl/loris) to run the tests on every change. – Karl Aug 19 '10 at 10:36 pretty much the best use of selenium. Man, I have wasted a lot of time with that thing.

Grumble grumble.... – the0ther Dec 7 '10 at 23:00.

Im a big fan of js-test-driver It works well in a CI environment and is able to capture actual browsers for cross-browser testing.

1 I like it because of the CI integration but think its best plus point is that it works with YUITest and QUnit! – AutomatedTester Nov 3 '09 at 16:18.

I recently read an article by Bruno using JsUnit and creating a JsMock framework on top of that... very interesting. I'm thinking of using his work to start unit testing my Javascript code. Mock Javascript or How to unit test Javascript outside the Browser environment.

I just got Hudson CI to run JasmineBDD (headless), at least for pure javascript unit testing. (Hudson running Java via shell, running Envjs, running JasmineBDD. ) I haven't got it to play nice with a big library yet, though, like prototype.

I am in agreement that jsunit is kind of dying on the vine. We just finished up replacing it with YUI Test. Similar to the example using qUnit, we are running the tests using Selenium.

We are running this test independently from our other selenium tests simply because it does not have the dependencies that the normal UI regression tests have (e.g. Deploying the app to a server). To start out, we have a base javascript file that is included in all of our test html files. This handles setting up the YUI instance, the test runner, the YUI.Test.

Suite object as well as the Test.Case. It has a methods that can be accessed via Selenium to run the test suite, check to see if the test runner is still running (results are not available until after it's done), and get the test results (we chose JSON format) var yui_instance; //the YUI instance var runner; //The YAHOO.Test. Runner var Assert; //an instance of YAHOO.Test.

Assert to save coding var testSuite; //The YAHOO.Test. Suite that will get run. /** * Sets the required value for the name property on the given template, creates * and returns a new YUI Test.

Case object. * * @param template the template object containing all of the tests */ function setupTestCase(template) { template.Name = "jsTestCase"; var test_case = new yui_instance.Test. Case(template); return test_case; } /** * Sets up the test suite with a single test case using the given * template.

* * @param template the template object containing all of the tests */ function setupTestSuite(template) { var test_case = setupTestCase(template); testSuite = new yui_instance.Test. Suite("Bond JS Test Suite"); testSuite. Add(test_case); } /** * Runs the YAHOO.Test.

Suite */ function runTestSuite() { runner = yui_instance.Test. Runner; Assert = yui_instance. Assert; runner.clear(); runner.

Add(testSuite); runner.run(); } /** * Used to see if the YAHOO.Test. Runner is still running. The * test results are not available until it is done running.

*/ function isRunning() { return runner.isRunning(); } /** * Gets the results from the YAHOO.Test. Runner */ function getTestResults() { return runner. GetResults(yui_instance.Test.Format.

JSON); } As for the selenium side of things, we used a parameterized test. We run our tests in both IE and FireFox in the data method, parsing the test results into a list of Object arrays with each array containing the browser name, the test file name, the test name, the result (pass, fail or ignore) and the message. The actual test just asserts the test result.

If it is not equal to "pass" then it fails the test with the message returned from the YUI Test result. @Parameters public static List data() throws Exception { yui_test_codebase = "file:///c://myapppath/yui/tests"; List testResults = new ArrayList(); pageNames = new ArrayList(); pageNames. Add("yuiTest1.

Html"); pageNames. Add("yuiTest2. Html"); testResults.

AddAll(runJSTestsInBrowser(IE_NOPROXY)); testResults. AddAll(runJSTestsInBrowser(FIREFOX)); return testResults; } /** * Creates a selenium instance for the given browser, and runs each * YUI Test page. * * @param aBrowser * @return */ private static List runJSTestsInBrowser(Browser aBrowser) { String yui_test_codebase = "file:///c://myapppath/yui/tests/"; String browser_bot = "this.browserbot.

GetCurrentWindow()" List testResults = new ArrayList(); selenium = new DefaultSelenium(APPLICATION_SERVER, REMOTE_CONTROL_PORT, aBrowser.getCommand(), yui_test_codebase); try { selenium.start(); /* * Run the test here */ for (String page_name : pageNames) { selenium. Open(yui_test_codebase + page_name); //Wait for the YAHOO instance to be available selenium. WaitForCondition(browser_bot + ".

Yui_instance! = undefined", "10000"); selenium. GetEval("dom=runYUITestSuite(" + browser_bot + ")"); //Output from the tests is not available until //the YAHOO.Test.

Runner is done running the suite selenium. WaitForCondition("! " + browser_bot + ".isRunning()", "10000"); String output = selenium.

GetEval("dom=getYUITestResults(" + browser_bot + ")"); JSONObject results = JSONObject. FromObject(output); JSONObject test_case = results. GetJSONObject("jsTestCase"); JSONArray testCasePropertyNames = test_case.names(); Iterator itr = testCasePropertyNames.iterator(); /* * From the output, build an array with the following: * Test file * Test name * status (result) * message */ while(itr.hasNext()) { String name = (String)itr.next(); if(name.

StartsWith("test")) { JSONObject testResult = test_case. GetJSONObject(name); String test_name = testResult. GetString("name"); String test_result = testResult.

GetString("result"); String test_message = testResult. GetString("message"); Object testResultObject = {aBrowser.getCommand(), page_name, test_name, test_result, test_message}; testResults. Add(testResultObject); } } } } finally { //if an exception is thrown, this will guarantee that the selenium instance //is shut down properly selenium.stop(); selenium = null; } return testResults; } /** * Inspects each test result and fails if the testResult was not "pass" */ @Test public void inspectTestResults() { if(!this.testResult.

EqualsIgnoreCase("pass")) { fail(String. Format(MESSAGE_FORMAT, this. Browser, this.

PageName, this. TestName, this. Message)); } } I hope this is helpful.

There's a new project that lets you run qunit tests in a Java environment (like ant) so you can fully integrate your client-side test suite with your other unit tests. qunit-test-runner.googlecode.com I've used it to unit test jQuery plugins, objx code, custom OO JavaScript and it works for everything without modification.

Another JS testing framework that can be run with Ant is CrossCheck. There's an example of running CrossCheck via Ant in the build file for the project. CrossCheck attempts, with limited success, to emulate a browser, including mock-style implementations of XMLHttpRequest and timeout/interval.It does not currently handle loading javascript from a web page, though.

You have to specify the javascript files that you want to load and test. If you keep all of your JS separated from your HTML, it might work for you.

For . Net using NUnit or MbUnit you could use WatiN to run a JSUnit Runner and check the results... like this guy: adamesterline.com/2007/05/15/integrating....

I'm just about to start doing Javascript TDD on a new project I am working on. My current plan is to use qunit to do the unit testing. While developing the tests can be run by simply refreshing the test page in a browser.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions