Qunit series-4. qunit introduction (II)

Source: Internet
Author: User
Test user operation problems

Code dependent on user operations cannot be tested by executing functions. The events of elements usually use Asynchronous functions, such as click, which need to be simulated.

Solution

You can use jquery'sTrigger () method to trigger the event and then test the expected behavior. If you do not want the browser event to be triggered, you can use triggerhandler () to execute the Event-related method. This is helpful for the Click Event of the test link, because trigger () may cause the browser to change the address bar information, which may not happen during the test. Suppose we have a simpleKeylogger needs to be tested:

function KeyLogger( target ) {  if ( !(this instanceof KeyLogger) ) {    return new KeyLogger( target );  }  this.target = target;  this.log = [];   var self = this;   this.target.off( "keydown" ).on( "keydown", function( event ) {    self.log.push( event.keyCode );  });}

We can manually trigger the keypress event and then observe whether the logger is working:

test( "keylogger api behavior", function() {   var event,      $doc = $( document ),      keys = KeyLogger( $doc );   // trigger event  event = $.Event( "keydown" );  event.keyCode = 9;  $doc.trigger( event );   // verify expected behavior  equal( keys.log.length, 1, "a key was logged" );  equal( keys.log[ 0 ], 9, "correct key was logged" ); });

 

Discussion

If your event processing does not depend on any specific event attribute, you can call trigger (eventtype ). However, if your event processing depends on special event attributes, you need to use $. event to create an event object and set necessary attributes. It is very important to trigger events related to complex behaviors, such as dragging, which consists of mousedown, mousemove, and mouseup. Even simple events may consist of many events. For example, click is composed of mousedown, mouseup, and click. Whether you need to trigger all three events depends on your test code and trigger only click. In most cases, the requirements are met.

If those are not enough, you need a framework to simulate user events:

  • SYN "is a synthesis of event class libraries, used to handle most of the typing, clicking, moving and dragging, can accurately simulate the user's actual operations ". Qunit-based funcunit uses SYN to test the functions of web sites.
  • Jsrobot-"a web application testing tool that can generate real percussion keyboards instead of simply simulating JavaScript event triggering. Allows you to trigger the actual events of the browser by hitting, which cannot be done by other frameworks ".
  • DOH robot "provides an API that allows testers to automatically run the UI test using real, cross-platform, and system-level input events ". It provides events close to real browsers for you, but it must be implemented using Java applets.

 

Test atomicity

When the test is centralized, the test that should have passed will fail, and the test that should have failed will pass, because the side effects of the previous test will invalidate the test result.

test( "2 asserts", function() {  var $fixture = $( "#qunit-fixture" );   $fixture.append( "<div>hello!</div>" );  equal( $( "div", $fixture ).length, 1, "div added successfully!" );   $fixture.append( "<span>hello!</span>" );  equal( $( "span", $fixture ).length, 1, "span added successfully!" );});

The first append () adds a DIV, and the second Equal () does not take it into consideration.

Solution

Use the test () method to maintain the atomicity of the test, so that each asserted is clean without any side effects. You should only rely on# Qunit-FixtureThe fixture label, modification and dependency on other things will have side effects.

test( "Appends a div", function() {  var $fixture = $( "#qunit-fixture" );   $fixture.append( "<div>hello!</div>" );  equal( $( "div", $fixture ).length, 1, "div added successfully!" );}); test( "Appends a span", function() {  var $fixture = $( "#qunit-fixture" );   $fixture.append("<span>hello!</span>" );  equal( $( "span", $fixture ).length, 1, "span added successfully!" );});

Qunit is reset after each test# Remove an existing event from the element in qunit-fixture. If you only use the internal elements of fixture, you do not need to perform manual operations to keep it atomic after each test.

Apart from # Qunit-fixture and filtering ("In addition, qunit also provides the noglobals mark. Let's take a look at the test below:
test( "global pollution", function() {  window.pollute = true;  ok( pollute, "nasty pollution" );});

In general, the test will get a successful result. However, after noglobals is selected, OK () returns the failed result because qunit considers that it has contaminated the window object. There is no need to use that flag at any time, but when integrating third-party class libraries, it is helpful to determine whether it will cause global naming pollution. In addition, he can also help find Bugs caused by side effects.

 

Group Test Problems

You have split all your tests to keep them atomic without side effects, but you want to ensure that their logic is organized and that they can run in groups.

Solution

You can use module () to group A test:

module( "group a" );test( "a basic test example", function() {  ok( true, "this test is fine" );});test( "a basic test example 2", function() {  ok( true, "this test is fine" );}); module( "group b" );test( "a basic test example 3", function() {  ok( true, "this test is fine" );});test( "a basic test example 4", function() {  ok( true, "this test is fine" );});

The tests after module () will be divided into one group, and the names of each test will be added with the module name in the test results. You can also run a specific test by selecting the module name.

Discussion

In addition to grouping, Module () can also be used to extract common code. It accepts an optional second parameter and defines the starting and ending behavior of each module running the test.

module( "module", {  setup: function() {    ok( true, "one extra assert per test" );  }, teardown: function() {    ok( true, "and one extra assert after each test" );  }});test( "test with setup and teardown", function() {  expect( 2 );});

You can define the setup and teardown attributes together, or define only one of them. When the modile () method is called again, the setup/teardown method defined in the previous method is reset.

 

Efficient Devlopment

When your test takes a long time (for example, several seconds), you do not need to waste time waiting for the results.

Solution

Qunit has a series of methods to solve this problem. The most interesting one is to click the "Hide passed tests" option in the header, so that qunit will only display the failed test, which will not affect the test time, but only focus on the failed test.

Another interesting feature is that qunit stores the name of the failed test in sessionstorage (your browser must support it). By default, this feature is enabled, but we didn't notice his existence. The next time you run the test again, the previous failed test will be executed first, but it will not affect the sequence of output results, only the execution order will be affected. With "Hide passed tests", you can immediately get a failed test.

Discussion

Automatic Sorting will happen by default. You think that your test requires atomicity. If it cannot be guaranteed, a random exception will occur. Fixing the problem is a correct solution or is difficult. You can set qunit. config. reorder = false.

In addition to automatic sorting, there are also some manual options. You can click the "Rerun" link after the test to run a single test. It will add the "testnumber = N" string parameter to the URL, and N represents the test number you clicked. You can refresh the page, run only that test, or run all tests in the return button area of the browser.

Run all tests in the module and work in almost the same way. Unless you select the module in the upper-right corner of the header, the "module = N" string will be added to the URL, and N represents the module number, for example :"? Module = testenvironment % 20 with % 20 object ".

 

Source: http://qunitjs.com/cookbook/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.