FuncUnit  class     

tags: core
download: FuncUnit
test: test.html

FuncUnit is a powerful functional testing framework written in JavaScript with a jQuery-like syntax. It provides an approachable way to write maintainable cross browser tests. It is the first functional testing framework written for JavaScript developers by JavaScript developers.

FuncUnit extends QUnit's API with commands like click, type, and drag. The same tests can be run in browser or automated via Selenium.

Example:

The following tests that an AutoSuggest returns 5 results.
See it in action! (Make sure you turn off your popup blocker!)

module("autosuggest",{
  setup: function() {
    S.open('autosuggest.html')
  }
});

test("JavaScript results",function(){
  S('input').click().type("JavaScript")

  // wait until we have some results
  S('.autocomplete_item').visible(function(){
    equal( S('.autocomplete_item').size(), 5, "there are 5 results")
  })
});

Using FuncUnit

FuncUnit works by loading QUnit, FuncUnit, and your tests into a web page. Your application is opened in a separate browser window. The FuncUnit page then drives your application via clicks, types, and drags, reporting pass/fail in the initial FuncUnit test page.

Loading a Test

To get started with a basic test, run:

./js jquery/generate/controller Company.Widget

Open company/widget/funcunit.html in a browser. You should see a passing test.

The first thing any FuncUnit page does is load its dependencies and a test. A FuncUnit page:

  1. Loads steal.js
  2. Loads funcunit and qunit via steal.plugins
  3. Loads one or more test files

For more details on setting up a FuncUnit test, check out the [FuncUnit.setup Getting Set Up] guide.
For more details on using FuncUnit without Steal or JavaScriptMVC, check out the [FuncUnit.standalone Using Standalone FuncUnit] guide.

Writing a Test

There are four types of commands in any FuncUnit tests:

  1. Actions - simulate a user interaction (clicks, types, drags, etc)
  2. Waits - wait for conditions in the page before continuing the test (width, visible,
    text, etc)
  3. Getters - get page conditions to use in assertions (width, hasClass, text)
  4. QUnit commands - assertions and methods for setting up tests (module, test, ok, equals, etc)

Tests follow a consistent pattern:

  1. Each test sets itself up in QUnit's setup method by opening an application page with S.open.
  2. Tests simulate a user action, like clicking a link.
  3. Then they wait for some page condition to change, like a menu appearing. 3*. Then you assert something about your page, like the right number of links are visible. This step isn't always necessary. You can write an entire test without assertions. If the wait condition fails, the test will fail.

For more information on writing tests, check out the [FuncUnit.writing Writing Tests] guide.

Running a Test

To run this test in browser, open funcunit.html in any browser (and turn off your popup blocker!).

To run the same test automated via Selenium, run:

./funcunit/envjs path/to/funcunit.html

For more information about using Selenium, checkout the [FuncUnit.selenium Automated FuncUnit] guide. Use envjs.bat for Windows users.

What is FuncUnit

Under the hood, FuncUnit is built on several projects:

  • Selenium - used to open browsers and run automated tests
  • QUnit - Unit testing framework provides test running, assertions, and reporting
  • jQuery - used to look up elements, trigger events, and query for page conditions
  • Env.js - Rhino based headless browser used to load pages in the command line
  • Rhino - command line JavaScript environment running in Java
  • Syn - event simulation library

FuncUnit is designed to let JavaScript developers write tests in an easy to learn jQuery-like syntax. The tests will run in browser, so developers can check for regressions as they work. The same tests also run via Selenium, so QA can automate nightly builds or continuous integration.

Why FuncUnit

TESTING IS PAINFUL. Everyone hates testing, and most front end developers simply don't test. There are a few reasons for this:

  1. Barriers to entry - Difficult setup, installation, high cost, or difficult APIs. QTP costs $5K per license.
  2. Completely foreign APIs - Testing frameworks often use other languages (Ruby, C#, Java) and new APIs.
  3. Debugging across platforms - You can't use firebug to debug a test that's driven by PHP.
  4. Low fidelity event simulation - Tests are often brittle or low fidelity because frameworks aren't designed to test heavy JavaScript apps, so browser event simualation accuracy isn't a top priority.
  5. QA and developers can't communicate - If only QA has the ability to run tests, sending bug reports is messy and time consuming.

FuncUnit aims to fix these problems:

  1. FuncUnit is free and has no setup or installation (just requires Java and a browser).
  2. FuncUnit devs know jQuery, and FuncUnit leverages that knowldge with a jQuery-like API.
  3. You can run tests in browser and set Firebug breakpoints.
  4. Syn.js is a low level event simuation library that goes to extra trouble to make sure each browser simulates events exactly as intended.
  5. Since tests are just JS and HTML, they can be checked into a project and any dev can run them easily. QA just needs to send a URL to a broken test case.

There are many testing frameworks out there, but nothing comes close to being a complete solution for front end testing like FuncUnit does.

Constructor

selects something in the other page
new FuncUnit(selector, context) -> funcunit
{String|Function|Object}

FuncUnit behaves differently depending if the selector is a string, a function, or an object.

String
The selector is treated as a css selector.
jQuery/Sizzle is used as the selector so any selector it understands will work with funcUnit. FuncUnit does not perform the selection until a command is called upon this selector. This makes aliasing the selectors to JavaScript variables a great technique.
Function
If a function is provided, it will add that function to the action queue to be run after previous actions and waits.
Object
If you want to reference the window or document, pass S.window or S.window.document to the selector.

{optional:Number}

If provided, the context is the frame number in the document.frames array to use as the context of the selector. For example, if you want to select something in the first iframe of the page:

 S("a.mylink",0)
{funcunit}
© Jupiter IT - JavaScriptMVC Training and Support