How to Use qunit to test JavaScript code

Source: Internet
Author: User

Qunit is a framework developed by the jquery team for unit testing on JavaScript. This article describes what qunit is and why you need to care about code testing.

What is qunit?

Qunit is a powerful JavaScript unit testing framework that helps code debugging. Qunit is written by jquery team members and is the official test suite of jquery. In addition, qunit can also test any common JavaScript code, or even use JavaScript engines like rhino or V8, test the JavaScript code on the server.

Don't worry if you are not familiar with the concept of unit testing. Not hard to understand:

In computer programming, unit testing (also called Module Testing) is a test of the correctness of program modules (the smallest unit of software design. A Program unit is the smallest testable part of an application. In procedural programming, a unit is a single program, function, process, etc. For object-oriented programming, the minimum unit is the method, including the base class (superclass), Abstract class, or derived class (subclass). "-- Reference from Wikipedia.

To put it simply, you write test cases for every function of the Code. If all the tests pass, you can ensure that the Code has no bugs (normally, it depends on how thorough the test is ).

Why test code?

If you have never written any unit tests before, you may directly apply your code to your website and click here to see if any problem occurs, and try to solve the problems you have found. There are many problems when using this method.

First, this is very boring. Clicking is actually not a simple task, because you need to ensure that everything is clicked and it is very likely to miss one or two. Second, everything for testing is not reusable, which means it is difficult to return back. What is regression? Imagine that you have written some code and tested them, fixed all the defects you found, and then released them. At this time, a user sends some feedback about new bugs and has some new requirements. You go back to the Code to handle these new bugs and add new features. What may happen next is the reproduction of some old defects, which is called "regression ". In this way, you have to click again, and you may not be able to find these old defects; even if you do, it takes some time to figure out that your problem is caused by regression. With unit testing, you write test cases to discover defects. Once the code is modified, you can filter the code again after testing. Once a regression occurs, some test cases will fail. You can easily recognize them and know which part of the Code contains errors. Now that you know what you modified, you can easily solve the problem.

Another advantage of unit testing, especially for web development: making cross-browser compatibility testing easier. Run your test cases only in different browsers. Once a browser encounters a problem, fix it and re-run these test cases to ensure that regression is not caused in other browsers. Once all the tests pass, all target browsers are supported.

I like to mention a John resig project: testswarm. Through distribution, testswarm brings JavaScript unit testing to a new level. This is a website that contains many test cases. Anyone can go there to run some test cases and then return the results to the server. In this way, the code can be quickly tested in different browsers, and even run on different platforms.

How to Use qunit to write Test Cases

How to correctly write unit tests with qunit? First, you need to build a test environment:

<! Doctype HTML> <br/> <pead> <br/> <title> qunit test suite </title> <br/> <LINK rel =" stylesheet "href =" http://github.com/jquery/qunit/raw/master/qunit/qunit.css "mce_href =" http://github.com/jquery/qunit/raw/master/qunit/qunit.css "type =" text/CSS "Media =" screen "> <br/> <MCE: script Type = "text/JavaScript" src = "http://github.com/jquery/qunit/raw/master/qunit/qunit.js" mce_src = "http://github.com /Jquery/qunit/raw/master/qunit. js "> </MCE: SCRIPT> <br/> <! -- Your project file goes here --> <br/> <MCE: Script Type = "text/JavaScript" src = "myproject. JS "mce_src =" myproject. JS "> </MCE: SCRIPT> <br/> <! -- Your tests file goes here --> <br/> <MCE: Script Type = "text/JavaScript" src = "mytests. JS "mce_src =" mytests. JS "> </MCE: SCRIPT> <br/> </pead> <br/> <body> <br/> <H1 id = "qunit-header"> qunit test suite </p> <br /> <H2 id = "qunit-Banner"> </H2> <br/> <Div id = "qunit-testrunner-toolbar"> </div> <br/> <H2 id = "qunit-useragent"> </H2> <br/> <ol id = "qunit-tests"> </OL> <br/> </body> <br/> </ptml>

As you can see, a managed qunit Framework version is used here.

The code to be tested needs to be added to myproject. JS, and your test case should be inserted into mytest. js. To run these tests, open the HTML file in a browser. Now you need to write some test cases.

The cornerstone of unit testing is assertions.

"Assertions are a proposition that predicts the returned results of your code. If the prediction is false and the assertions fail, you will know that the problem has occurred ."

To run assertions, you need to put them in the test case:

// Let's test this function <br/> function iseven (VAL) {<br/> return Val % 2 = 0; <br/>}< br/> test ('iseven () ', function () {<br/> OK (iseven (0 ), 'Zero is an even number '); <br/> OK (iseven (2), 'so is two'); <br/> OK (iseven (-4 ), 'So is negative four'); <br/> OK (! Iseven (1), 'one is not an even number '); <br/> OK (! Iseven (-7), 'Neither is negative Seven'); <br/> })

Here, we define a function: iseven, which is used to check whether a number is an odd number and we want to test this function to ensure that it does not return an incorrect answer.
We first call test (), which creates a test case. The first parameter is a string that will be displayed in the result, and the second parameter is a callback function that includes our master disconnected.
We wrote five assertions, all of which are Boolean. A boolean assertion, expecting its first parameter to be true. The second parameter is the message to be displayed in the result.
Below is what you want, as long as you run the test case:

Since all the assertions have been successfully passed, we are happy to think that iseven () works normally.
Let's see what will happen if an asserted fails. // Let's test this function <br/> function iseven (VAL) {<br/> return Val % 2 = 0; <br/>}< br/> test ('iseven () ', function () {<br/> OK (iseven (0 ), 'Zero is an even number '); <br/> OK (iseven (2), 'so is two'); <br/> OK (iseven (-4 ), 'So is negative four'); <br/> OK (! Iseven (1), 'one is not an even number '); <br/> OK (! Iseven (-7), 'Neither does negative Seven'); <br/> // fails <br/> OK (iseven (3 ), 'Three is an even number '); <br/> })The following is the result: This asserted fails because we intentionally wrote an error. But in your project, if the test fails and all the assertions are correct, you will find a bug. More assertionsOK () is not only the only assertion provided by qunit, but also some very useful assertion types when testing your project: Comparison assertions

Compare assertion, equals (), expect its first parameter (actual value) to be equal to its second parameter (expected value ). It is similar to OK (), but all input implementations and expectations make the height simpler. Like OK (), it can contain an optional third parameter as the displayed message.

So it can be replaced:

Test ('assertions ', function () {<br/> OK (1 = 1, 'one equals one'); <br/> })

You can write as follows: Test ('assertions ', function () {<br/> equals (1, 1, 'one equals one'); <br/> })

Note that the last "1" is a comparison value.

If the two values are not equal:

Test ('assertions ', function () {<br/> equals (2, 1, 'one equals one'); <br/> })

Provide more information to make life easier.

Comparison assertions use "=" to compare its parameters, so it cannot process the comparison of arrays or objects:

Test ('test', function () {<br/> equals ({},{}, 'fails, these are different objects '); <br/> equals ({A: 1 },{ A: 1}, 'fails '); <br/> equals ([], [], 'fails, there are different arrays '); <br/> equals ([1], [1], 'fails'); <br/> })To test the equality, qunit provides another asserted: Hengyi assertions
. Hengyi assertions
Constant assertions, same (), expect the same parameters to be equal, but it uses recursive comparison assertions deeper, not only acting on the original type, but also includes arrays and objects. Assertions: In the previous example, if you change them to the permanent state, all assertions will pass. Test ('test', function () {<br/> same ({},{}, 'passes, objects have the same content '); <br/> same ({A: 1 },{ A: 1}, 'passes '); <br/> same ([], [], 'passes, arrays have the same content '); <br/> same ([1], [1], 'passes'); <br/> })Note that same () uses "=" for comparison. If necessary, same () can be used when special values are compared. Test ('test', function () {<br/> equals (0, false, 'true'); <br/> same (0, false, 'false '); <br/> equals (null, undefined, 'true'); <br/> same (null, undefined, 'false'); <br/> }) Structured your assertions

Putting all assertions in a single test case is rather difficult because it is difficult to maintain and cannot return a pure result. What you need to do is to structure them and put them in different test cases. Each goal is a separate function.

You can even call module functions to organize test cases to different modules:

Module ('module A'); <br/> test ('a test', function () {}); <br/> test ('an another test ', function () {}); <br/> module ('module B '); <br/> test ('a test', function (){}); <br/> test ('an another test ', function (){}); Asynchronous Test
In the previous example, all assertions are synchronously called, which means they run one after another. In this real world, there are also many asynchronous functions, such as Ajax requests or methods called through setTimeout () or sestinterval. How can we test these methods? Qunit provides a special test case called "Asynchronous test" and provides it to asynchronous test:
Let's first try to write in the conventional method: Test ('asynchronous test', function () {<br/> setTimeout (function () {<br/> OK (true); <br/>}, 100) <br/> })

See? This is like we did not write any assertions. This is because the assertion is asynchronously executed. By the time it is called, this test has been completed.

This is the correct version:

Test ('asynchronous test', function () {<br/> // pause the test first <br/> stop (); </P> <p> setTimeout (function () {<br/> OK (true); </P> <p> // After the assertion has been called, <br/> // continue the test <br/> Start (); <br/>}, 100) <br/> })

Here, we use stop () to pause this test case, and after the assertions are called, we use start () to continue.

It is common to call stop () immediately after test () is called. Therefore, qunit provides a shortcut: asynctest (). You can rewrite the previous example as follows:

Asynctest ('asynchronous test', function () {<br/> // The test is automatically paused </P> <p> setTimeout (function () {<br/> OK (true); </P> <p> // After the assertion has been called, <br/> // continue the test <br/> Start (); <br/>}, 100) <br/> })Note that setTimeout () usually calls its own callback function, but if it is a custom function (for example, an Ajax call ). How do you confirm that the callback function has been called? And if the callback function is not called, start () will not be executed, and the entire unit test will be suspended: So this is what you need to do: // A custom function <br/> function Ajax (successcallback) {<br/> $. ajax ({<br/> URL: 'server. php', <br/> success: successcallback <br/>}); <br/>}</P> <p> test ('asynchronous test', function () {<br/> // pause the test, and fail it if start () isn' t called after one second <br/> stop (1000 ); </P> <p> Ajax (function () {<br/> //... asynchronous assertions </P> <p> Start (); <br/>}) <br/> })

You can use the delay to stop (), which tells qunit that "If start () is not called after the delay, you should not pass the test ". You can check that the entire test is not suspended and you can notice the problem if any.

So what about multiple asynchronous functions? Where do you place start ()? You can put it in setTimeout:

// A custom function <br/> function Ajax (successcallback) {<br/> $. ajax ({<br/> URL: 'server. php', <br/> success: successcallback <br/>}); <br/>}</P> <p> test ('asynchronous test', function () {<br/> // pause the test <br/> stop (); </P> <p> Ajax (function () {<br/> //... asynchronous assertions <br/>}) </P> <p> Ajax (function () {<br/> //... asynchronous assertions <br/>}) </P> <p> setTimeout (function () {<br/> Start (); <br/>}, 2000 ); <br/> })The latency should be long enough to allow the callback functions of the two to be called before the test continues. But what if one of the callback functions is not called? How do you know? This is why CT () is added: // A custom function <br/> function Ajax (successcallback) {<br/> $. ajax ({<br/> URL: 'server. php', <br/> success: successcallback <br/>}); <br/>}</P> <p> test ('asynchronous test', function () {<br/> // pause the test <br/> stop (); </P> <p> // tell qunit That You Have CT three assertions to run <br/> reverse CT (3); </P> <p> Ajax (function () {<br/> OK (true); <br/>}) </P> <p> Ajax (function () {<br/> OK (true ); <br/> OK (true); <br/>}) </P> <p> setTimeout (function () {<br/> Start (); <br/>}, 2000); <br/> })

You send a number to CT () to tell qunit that you expect X assertions to be executed. If an asserted is not executed, this number will not match, and you will notice something wrong.

There is still a shortcut to CT (): You only need to pass a number to the second parameter of test () or asynctest:

// A custom function <br/> function Ajax (successcallback) {<br/> $. ajax ({<br/> URL: 'server. php', <br/> success: successcallback <br/> }); <br/>}</P> <p> // tell qunit That You Have CT three assertion to run <br/> test ('asynchronous test', 3, function () {<br/> // pause the test <br/> stop (); </P> <p> Ajax (function () {<br/> OK (true ); <br/>}) </P> <p> Ajax (function () {<br/> OK (true ); <br/>}) </P> <p> setTimeout (function () {<br/> Start (); <br/>}, 2000 ); <br/> })

Summary

This is all you need to know when you start using qunit. Unit testing is a good method for testing before code is released. If you haven't written any unit tests before, it's time to start! Thank you for reading!

 

Source: http://net.tutsplus.com/tutorials/javascript-ajax/how-to-test-your-javascript-code-with-qunit/

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.