AlignMinds Technologies logo

Why Testing with Jasmine is Fun?

What is Jasmine?

Jasmine is a behaviour-driven development framework, used for testing JavaScript code. To know about behaviour-driven development, we must know about test-driven development.

Test-driven development, as per definition, is a software development process that relies on the repetition of a very short development cycle: first, the developer writes an automated test case that defines a desired improvement or new function, then produces a minimum amount of code to pass that test, and finally refactors the new code to acceptable standards.

Behaviour-driven development, on the other hand, is a software development process that is emerged from test-driven development. The behaviour-driven development process can be called as a combination of general techniques and principles of test-driven development.

Why use Jasmine for testing?

Jasmine is an independent software as it does not depend on any other software development frameworks. It does not require a Document Object Model (DOM). A basic advantage that can be called of Jasmine is that its syntax is so obvious that it’s easy to understand. It also helps you to write your tests easily.

Working with Jasmine

Function

Let’s start with an example code that you want to test using Jasmine. We all know, in every programming language, we start with a Hello World program. Here also, let’s begin with a helloworld.js. A JavaScript function that returns “Hello World”.

Spec

Initially, you need to grab the latest standalone version of Jasmine on your computer. They are easily available on Google. All you need to do is search for it and download it. Unzip the downloaded file. The /src and /spec directories will have many files in it. You’ll have to empty them out as they are just examples which you probably won’t require.

Now, the function or let’s call the helloworld.js file should be put into the /src directory. We now have created the src. What we must do next is to create the spec.

The code has two parts.

The ‘describe’ part and the ‘it’ part. The ‘describe’ part will contain the main codes or functions that do the tests. ‘Describe’ is followed by the suite, which is just the English language and not any code, which helps to understand what it describes. Inside of ‘describe’, you have the ‘it’ part of the code. ‘It’ part is generally called as a ‘spec’.

The whole code might look like classes written in a function. ‘It’ describes what the code must do in general English language and in JavaScript code. You can have any number of specs in a suite.

Matchers

When a code is needed to be tested, you will definitely require a matcher. A matcher is something that will do the checking whether your code provides the required output. For beginners, we can use expect() and toEqual() as matchers. In our Hello World example program, we need the code to return the expected output – “Hello World”.

To test this, the matchers will run as expect (helloworld()).toEqual(“Hello World”); If that comes true, the program is successfully tested with no errors reported. There are many other matchers too. Matchers are selected according to the requirement of what is to be tested and what should be returned. In addition to this, you can make your own matchers too.

Example code

describe(“The ‘toEqual’ matcher”, function() { it(“works for simple literals and variables”, function() { var a = 12; expect(a).toEqual(12); }); it(“should work for objects”, function() { var foo = { a: 12, b: 34 }; var bar = { a: 12, b: 34 }; expect(foo).toEqual(bar); }); }); it(“The ‘toMatch’ matcher is for regular expressions”, function() { var message = “foo bar baz”; expect(message).toMatch(/bar/); expect(message).toMatch(“bar”); expect(message).not.toMatch(/quux/); }); it(“The ‘toBeDefined’ matcher compares against `undefined`”, function() { var a = { foo: “foo” }; expect(a.foo).toBeDefined(); expect(a.bar).not.toBeDefined(); }); it(“The `toBeUndefined` matcher compares against `undefined`”, function() { var a = { foo: “foo” }; expect(a.foo).not.toBeUndefined(); expect(a.bar).toBeUndefined(); }); it(“The ‘toBeNull’ matcher compares against null”, function() { var a = null; var foo = “foo”; expect(null).toBeNull(); expect(a).toBeNull(); expect(foo).not.toBeNull(); }); it(“The ‘toBeTruthy’ matcher is for boolean casting testing”, function() { var a, foo = “foo”; expect(foo).toBeTruthy(); expect(a).not.toBeTruthy(); }); it(“The ‘toBeFalsy’ matcher is for boolean casting testing”, function() { var a, foo = “foo”; expect(a).toBeFalsy(); expect(foo).not.toBeFalsy(); }); it(“The ‘toContain’ matcher is for finding an item in an Array”, function() { var a = [“foo”, “bar”, “baz”]; expect(a).toContain(“bar”); expect(a).not.toContain(“quux”); }); it(“The ‘toBeLessThan’ matcher is for mathematical comparisons”, function() { var pi = 3.1415926, e = 2.78; expect(e).toBeLessThan(pi); expect(pi).not.toBeLessThan(e); }); it(“The ‘toBeGreaterThan’ matcher is for mathematical comparisons”, function() { var pi = 3.1415926, e = 2.78; expect(pi).toBeGreaterThan(e); expect(e).not.toBeGreaterThan(pi); }); it(“The ‘toBeCloseTo’ matcher is for precision math comparison”, function() { var pi = 3.1415926, e = 2.78; expect(pi).not.toBeCloseTo(e, 2); expect(pi).toBeCloseTo(e, 0); }); it(“The ‘toThrow’ matcher is for testing if a function throws an exception”, function() { var foo = function() { return1 + 2; }; var bar = function() { return a + 1; }; expect(foo).not.toThrow(); expect(bar).toThrow(); }); it(“The ‘toThrowError’ matcher is for testing a specific thrown exception”, function() { var foo = function() { thrownew TypeError(“foo bar baz”); }; expect(foo).toThrowError(“foo bar baz”); expect(foo).toThrowError(/bar/); expect(foo).toThrowError(TypeError); expect(foo).toThrowError(TypeError, “foo bar baz”); }); });

(Code was taken from http://jasmine.github.io/2.0/introduction.html)

Some advantages of using Jasmine

  • Jasmine is independent. It does not depend on any other JavaScript frameworks.
  • It does not require a DOM.
  • It has a clean, obvious syntax.
  • Help maintainers understand the intention behind the code.
  • Brings validation and proper data handling concerns to the forefront.

Conclusion

There is plenty more you can do with Jasmine. Overall, Jasmine makes your testing fun. So, if you’re not yet into testing, now is an excellent time to start your JavaScript testing. It makes your testing pretty simple with Jasmine’s fast and simple syntax.

– Shekhar R

Codeception: Efficient Key to Kill Bugs!

In 1985, Canada’s Therac-25 radiation therapy machine malfunctioned due to software bug and delivered lethal radiation doses to patients, leaving 3 people dead and critically injuring 3 others.

During the first Gulf War, an American Patriot Missile system in Saudi Arabia failed to intercept an incoming Iraqi Scud missile due to a software rounding error in calculation. The missile destroyed an American Army barracks and 28 soldiers dead, 100 injured.

In May of 1996, a software bug caused the bank accounts of 823 customers of a major U.S. bank to be credited with 920 million US dollars.

Do you realize, how Testing is vital?

Do you think, understanding a product and testing the same against functionality, performance, security, GUI and many others is an easy task?

We can implement new & better choices for a product’s quality and security. There are lots of ways to test our product.

The most accepted deal is unit testing. Also, we should need to write functional or acceptance tests as well. For all these Codeception is the right choice! The Codeception testing framework figures out all these levels of testing and it is a multi-featured testing framework for PHP.

Codeception can handle unit, functional, and acceptance testing of web applications.

Major types of Tests

It was evoked in November 2011 and released the first stable version 1.0 in January 2012. Codeception tries to simplify and combine the process of writing tests, plugging different testing suites with the use of modules and it opens the way to anyone to extend and sharpen it. Codeception is testing framework in which all tests are written in a single descriptive manner.

What variety of tests & How?

Major types of Tests covered and its Pros & Cons

Acceptance Test (WebGuy)

Acceptance testing can be performed by a non-technical person. That person can be your tester, manager or even client. It allows us to test our applications using the normal website viewing process i.e.; visit a webpage, fill in a form, and submit the form to see the desired result.

The difference is with Codeception, we don’t have to waste time going to the browser each time we want to test a new feature out, instead, we can just run our acceptance tests to see its passes or not.

Try a sample scenario;

Probably the first test you would want to run would be signing in. In order to write such a test, we still require basic knowledge of PHP and HTML.

This scenario can probably be read by non-technical people. Codeception can even ‘naturalize’ this scenario, converting it into plain English:

It can be done by command:

The Want To section describes your scenario in brief. The $I object is used to write all interactions. The methods of the $I object are taken from the PhpBrowser and Db modules. We assume that all am commands should describe the starting environment. The amOnPage command sets the starting point of a test to the /login page. With the PhpBrowser you can click the links and fill the forms. That will probably be the majority of your actions.

Functional Test (TestGuy)

We can check our application without running it on a server, this is what done on Functional tests. These tests are written in the same way as Acceptance tests with PhpBrowser module enabled. It’s tested by a technically advanced guy i.e., TestGuy. The TestGuy knows how the application works, passes different $_GET, $_POST and $_REQUEST variables to assure the functionality. Codeception can connect to numerous web frameworks Symfony2, Laravel4, Yii2, Zend Framework and others which support functional testing.

We can open a web page with amOnPage command.

We can click links to open web pages of the application.

Functional tests will perform much better if we use powerful frameworks. It allows us to access and manipulate their internal states and this helps our tests shorter and faster. On the other hand, if we do not use frameworks there is no practical reason to write functional tests.

Let’s allow our application tested by this technically advanced guy for better results.

Unit Test (CodeGuy)

“Unit” casually refers to low-level tests and the developer understands how and what is tested here, though some would say a better name is DeveloperTest. The person testing, CodeGuy, knows the internals of the application and tests database operations and anything else that might need proof of concept. Codeception provides some well-built tools to make your unit tests simpler and cleaner. Even inexperienced developers should understand what is tested and how.

We can start with generating a classical PHPUnit test by this command:

We can use another command to create Codeception-powered unit tests.

Both tests will create a new ExampleTest file located in tests/unit directory.

A test created by generate:test command will look like this:

This class has predefined _before and _after methods to start with. We can use them to create a tested object before each test and destroy it afterwards. All Codeception tests are written in a descriptive manner. We can easily catch it from the test body. Its aim is to make tests easy to read, easy to write and easy to debug.

After all, this is how the Codeception works and you should give it a try on yourself.

Go ahead, use Codeception skillfully.

(Reference: codeception.com)

– Jisna Mathew

Agile Testing: 10 Principles to Follow While Testing Your Web and Mobile Applications

Having worked in various organizations for many years in the area of Software Testing, I could firmly say that an Agile based testing approach is becoming a critical factor in bringing superior quality to today’s web and mobile applications.

Agile testing process by Ayal Shimoni

Though there are several testing approaches available, it is high time to come out of traditional approaches and adopt more rigorous and iterative testing practices that make testing more real and bring more effective results.

Agile testing is becoming very crucial while delivering quality results to the customer. I thought I will share with you some basic principles if followed that can bring drastic value additions to your test approach and make your client happy.

Agile Testing: Top 10 principles

Deliver value to the customer

Ensure that each prototype delivered to customer meet their expectation. Example: Is the layout of the website as expected by the customer, are the messages meaningful and user-friendly, does the click on button work, are there any broken pages etc.

Enable face-to-face communication

Direct communication with the client is very important to get a clear picture of the requirements. There might not be proper documents for the change requests as change occurs in a rapid manner in agile environment, however, if a representative from each team (developer, tester, program manager) meet together on a regular basis to discuss the amount of work done, it can help measure the work progress, determine bug status (how many severe bugs still exist, how many were re-opened etc.) and where we stand when compared to customer needs.

Keep it simple

Make a note of changes happening. Organized documents might not be available for every change that comes from the customer, but if you have a record of all changes (with date and comments) preserved at a commonplace, it will help you refer in future in case any confusions arise.

Also, when you report issues to the developer via bug tracking tool (or any other means like a simple spreadsheet), give a precise description of the issue that gives clear idea about the issue, if possible always attach a screenshot as the saying goes “A picture is better than 1000 words”.

Keep a big picture in mind

Although in agile testing methods, prototypes are delivered in short intervals, testers must not get distracted from the big picture of the overall product. Continuous change in code and implementation can sidetrack you from the original requirement of the client. Ensure that rigorous code change does not alter the output from the original agenda.

Provide continuous feedback

Testers must be proactive enough to provide timely feedback to developers and program managers about the quality (bugs founds, requirement missing etc.) of each prototype being delivered to client as each prototype is developed in short time spans and the early the feedback, the sooner the developers can fix those bugs, thus, ensuring delivery of quality product to the client. Focus more on people – make sure all teams (including developers, program managers, and testers) and the customer has the same understanding about a requirement.

Have courage

Sometimes a customer might not have an exact idea of what fits best for his/her requirement. Asking questions and offering ideas can help them choose the best fit for their requirement. Also, it gives you better insight into customer expectations.

Sometimes implementation must be questioned as it might not be the exact way customer is expecting. So, dare to question implementation and the way in which system is behaving as a developer who has developed that piece of the product might not have enough understanding about the requirement and your question can help them build the right piece of product.

It might create friction among teams as you cross-question their code; however, a friendly approach and the right attitude can lead to a fruitful discussion to build a product that fulfils customer needs. Ensure that your team is not intimidated by developers.

Picture by Dave Gray on Flickr

Practice continuous improvement

Always strive to improve your testing skills. Evaluate your testing skills at each delivery. How closely you tested customer requirements?

Were any of the areas left out while testing?

Did customer raise issues that you missed while testing?

Learn from your past experience, make a note of mistakes happened, list out how testing could have been improved at your side and try to implement new steps in your next project.

Respond to change

Change is a constant part of agile testing. Requirements change continuously, code change continuously. If you are having difficulty in keeping track of changes, make a practice of writing down each change (with date and comments that will help you remember why the changes were made etc.). Sometimes this kind of documentation is also helpful to other teams while re-visiting requirements or you can also show it to the customer when they say your product does not match their requirements.

Self-organize

Plan beforehand how your day is going to be. Be prepared to handle an unexpected situation. In an agile environment, there will be constant changes; so, keep a note of what tasks are to be tested on a daily basis and on what priority.

Keeping your work organized and a planned approach to handle your testing tasks can help you to test better and finish tasks in a more efficient and productive way.

Enjoy your work

Knowingly or unknowingly you are doing a very responsible part of bringing the world to a better place, so take this responsibility with great enthusiasm and passion. It gives a great sense of satisfaction to see the product you tested is the built-in right way that makes your customer happy, thus, bringing joyous results to your hard work.

– Susan B. John