Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Working with JavaScript QUnit Test Framework

This article demonstrates how to work with QUnit framework for the development of unit tests in JavaScript programming language.

Most of the time, JavaScript-based applications tend to grow and be complex given the increasing amount of business rules in the application. Even with good programmers working in the JavaScript code to improve, the software will still have defects. Test engineers do their best to reduce the flaws before the software is released, but hardly detect up all the flaws manually. So to improve and increase the efficiency of tests to identify the faults, automated tests can be considered viable, because they reveal any (if well planned) problem in the early stages of development, thereby reducing the cost of defects correction significantly.

Regardless of the technologies used, the best development practices include the automation of the testing stages:

  • Unit testing: Aims to test the lower part (for example, class methods) of the application;
  • Integration testing: Aims to test the components (for example, classes) in combined groups;
  • System testing: Aims to test if the system functions as a whole;
  • Functional tests: Aims to test the system functionalities, at application level.

Currently, the market offers several tools for automating tests in JavaScript. One of the most popular is the QUnit, subject of this article.

Taking a look at QUnit

QUnit is a framework of JavaScript unit testing that helps us to test the code. Developed by the jQuery team, this is currently the standard program of all projects of the group, including the jQuery core, jQueryUI, jQueryMobile, among others. Furthermore, QUnit can be used to test any JavaScript-based code.

To get started you'll first add the code from Listing 1 in the so called "index.html", which contains all the files (html, css and js) necessary for the operation of QUnit.

Listing 1. index.html code to start the QUnit

<html>
<head>
  <meta charset="utf-8">
  <title>Article about QUnit </title>
  <!--Includes the QUnit stylesheet -->
  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.19.0.css">
</head>
<body>
  <!-- User Interface of QUnit-->
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>
  <!-- End -->
  <script src="http://code.jquery.com/qunit/qunit-1.19.0.js"></script>
  <script src="tests.js"></script>
</body>
</html>

Then, we will create the JavaScript file and call it "tests.js" with the source code shown in Listing 2, which contains our first QUnit test.

Listing 2. tests.js source code.

QUnit.test( "First test with QUnit", function( assert ) {
	assert.ok( 1 == "1", "Passed!" ); 
});

Note that in the statement ofQUnittesting we declare the QUnit class for calling the test method, including the parameters (such as the test name and function with it). Within the function there is a method called "assert.ok" which only checks whether it is true or false the comparison of the two values. If true, QUnit displays the message "Passed" in the index.html page.

To perform the test simply access the index.html page in the browser, where the results of our first test, if all has worked, will result shown in Figure 1.

Figure 1. Result of the first test with QUnit

Note that QUnit shows the page header ("Article about QUnit") and below you see a green bar, which means the test passed. If this bar turns red, it means that one or more tests did not pass.

In the second section there are three check boxes:

  • Hide passed tests: If checked, QUnit will hide the passed tests;
  • Check for Globals: This option, if checked, allows you to check whether a property has been added to the window object, comparing it before and after each test. If the test fails, the differences will be listed;
  • In the try-catch: If checked, allows you to check if the code has launched an exception when you ran the tests with QUnit.

In addition to the check boxes there is a search field next to the text "Filter", which we can use to filter the tests performed to look for one in particular.

In the third section we can see the value of window.navigator.userAgent property, which returns the user agent information of the web browser accessing the page.

The lower section shows the time spent by QUnit to perform the tests defined. Also in this section, there are a number of statements defined, the number of tests that passed and the number that failed.

Testing the code using comparative claims

Affirmations are the software testing core, because they allow us to verify that the code is working as expected. So QUnit provides several functions to compare objects or values within the function "QUnit.test()". Let's look at the overview of the comparison functions:

  • equal(): Performs a non-strict comparison (weak typing), roughly equivalent to assertEquals of JUnit;
  • notEqual(): Performs a non-strict comparison, checking for inequality;
  • strictEqual(): Performs a strict comparison (strong typing);
  • notStrictEqual(): Performs a rigorous comparison, checking for inequality;
  • propEqual(): Performs a rigorous comparison of the properties and values of an object;
  • notPropEqual(): Performs a rigorous comparison of the properties and values of an object, checking for inequality;
  • deepEqual(): Performs a rigorous comparison of the properties, values, and the prototype of an object;
  • notDeepEqual(): Performs a rigorous comparison of the properties, values, and the prototype of an object, checking for inequality.

For a better understanding of each method mentioned, now we will do some examples using them.

We'll start with the equal() and notEqual() using the Listing 1 file and then adding the code in Listing 3 within the <head> tag.

Listing 3. JavaScript function that makes multiplication and returns the result

<script language="javascript"> 
	function multiply(a, b) {
		return a * b; 
	} 
</script>

Then use the file of Listing 2, replacing the existing test by the one inListing 4, in which we will do some tests using the multiply(), equal() and notEqual() functions.

Listing 4. tests.js code

QUnit.test('Tests using the functions equal(...) and notEqual(...)', function(assert) {
   assert.expect(6);
   // With equal()
   assert.equal(multiply(2, 2), 4, 'Multiplication of two positive numbers');
   assert.equal(multiply(-2, -2), 4, 'Multiplication of two negative numbers');
   assert.equal(multiply(-2, 2), -4, 'Multiplication of a negative number and a positive number');
   assert.equal(multiply(2, 0), 0, 'Multiplication of a positive number and a neutral number ');
   
   // With notEqual()
   assert.notEqual(multiply(1, 1), 0, 'Multiplication of two equal positive numbers');
   assert.notEqual(multiply(2, 3), 0, 'Multiplication of a positive number and a positive number');
});

In the above code we can also highlight the importance of using the call "assert.expect (4)" in which we are telling to QUnit that we expect that the four tests are performed. It's just a best practice to set the number of claims that we expect to run. Another point is that most of the assert QUnit functions follow the same pattern, for example:

assert.<asset-function>(<calculated or actual value>,<expected value>, <optional description of the assertion>)
assert.equal(multiply(2, 2), 4, 'Multiplication of two positive numbers');
assert.notEqual(multiply(1, 1), 0, 'Multiplication of two positive numbers’);

Then to execute our test simply access the index.html file in the browser and if everything went as expected, the result will look like Figure 2.

Figure 2. Results of tests using the equal() and notEqual() functions.

Now we will create unit tests using the strictEqual() function and notStrictEqual of QUnit. These two functions are used when applying a strict comparison (strong typing). Add the code in Listing 5to tests.js file.Listing 5. tests.js code

QUnit.test('Tests using the functions strictEqual(...) and notStrictEqual(...)', function(assert) {
   assert.expect(2);
   // With strictEqual()
   assert.strictEqual(multiply(-2, 2), -4, 'Multiplying a negative and a positive number is equal to a negative integer');
   // With notStrictEqual()
   assert.notStrictEqual(multiply(-2, 2), '-4', 'Multiplying a negative and a positive number is not equal to a string');
});

Then to execute our test simply access the index.html file in the browser and if everything went as expected, the result will look likeFigure 3.

Figure 3. Results of tests using the strictEqual() and notStrictEqual()

Note that if we replace the notStrictEqual() function for equal() in the previous example, the test passes because the equal() does not perform a strict comparison (of strong typing '==='), unlike strictEqual(), which uses .

We will do some tests now using the propEqual() and notPropEqual(). To do this, use the index.html file and then add the Listing 6 code within the <head> tag. Basically, we define a function called "Person" containing two properties and after this function we declare a literal object called "human" containing two properties initialized to zero. These two definitions we will use in the tests.

Listing 6. index.html file code within the <head> tag

<script language="javascript">
	// Function Person with two props
	function Person(name, email) {
		this.name = name
		this.email = email
	}
	
	// Literal object with two props initialized as null
      var human = {
		name: null,
		email: null
      };
</script>

Then use the file tests.js replacing the existing test for Listing 7, where we will do some tests using the propEqual() and notPropEqual().

Listing 7. tests.js code

QUnit.test('Test using the function propEqual(...)', function(assert) {
   assert.expect(1);
   // 1º Object
   var person = new Person('John Nash','johnnash@gmail.com');
   // 2º Object
   human.name = 'John Nash';
   human.email = 'johnnash@gmail.com';
   
   assert.propEqual(person, human, 'Both objects have the same props and values');
 
});
 
QUnit.test('Test using the function notPropEqual(...)', function(assert) {
   assert.expect(1);
   // 1º Object
   var person = new Person('John Nash','johnnash@gmail.com');
   // 2º Object
   human.name = 'Mary';
   human.email = 'johnnash@gmail.com';
    
   assert.notPropEqual(person, human, 'Even both objects having the same props, one of them has a different name');
});

Basically what we want to test in the displayed list is simply if the two objects pass through the propEqual() and notPropEqual() functions without the prototype restriction (how JavaScript objects are created). To execute our test simply access the index.html file in the browser and if everything went as expected, the result will look like Figure 4.

Figure 4. Results of tests using the propEqual() and notPropEqual()

Finally, we will create unit tests using the deepEqual() and notDeepEqual() of QUnit, which are used when it requires a thorough comparison and that takes into account the prototype objects.

For the new example add the code in Listing 8to tests.js file, noting that these tests will use the Listing 6 also.

Listing 8. tests.js code

QUnit.test('Test using the function deepEqual(...)', function(assert) {
   assert.expect(1);
   // 1º Object
   var person = new Person('John Nash','johnnash@gmail.com');
   // 2º Object
   var person2 = new Person('John Nash','johnnash@gmail.com');
   
   assert.deepEqual(person, person2, 'Both objects have the same props, values and prototypes');
 
});
 
QUnit.test('Test using the function notDeepEqual(...)', function(assert) {
   assert.expect(1);
   // 1º Object
   var person = new Person('John Nash','johnnash@gmail.com');
   // 2º Object
   human.name = 'John Nash';
   human.email = 'johnnash@gmail.com';
    
   assert.notPropEqual(person, human, 'Both objects have the same props and values, but they are different because have different prototypes');
});

What we want to test is the verification between the two objects to see if they pass through the deepEqual() and notDeepEqual() with the prototype restriction (how JavaScript objects are created). After we run the test, if everything went as expected, the result will look like Figure 5.

Figure 5. Results of tests using the deepEqual() and notDeepEqual()

Note that if we replace the notDeepEqual() function by propEqual() in the previous example the test goes well, for the propEqual() does not take into account how the object is created (prototype), unlike deepEqual() or notDeepEqual().

Conclusion

Thus, in this article we saw how to work with the main features of unit testing framework JavaScript QUnit.

Thanks!



Fabrí­cio Galdino is a software expert and has worked with IT analysis and business development for more than five years. It has extensive experience with testing, back and front-end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login