Pichí, by etringita

Still interested in unit testing in WordPress? That’s good, because today we’ll move from PHP to JavaScript and, hence, to the front-end! Pretty cool, huh? ? In this post I’ll present you some frameworks for unit testing JavaScript code and we’ll see a step-by-step example. And now that you’re an (almost) expert unit tester ?, I’ll share a couple of YouTube videos that I loved and that’ll teach you some further insights on the topic.

But before we dive into the JavaScript world…

The solution of our PHPUnit problem

In the previous post I gave you some homework, remember? Here’s what I asked you to do:

Rewrite the function neliovat_get_vat so that money quantities expressed as strings like15,20, 1.000, or 3€ (where the optional thousand separator is ., decimal separator is ,, there might be a currency symbol, and there aren’t any spaces) passes the test.

The original function I presented was:

and the failing test was:

So, how do we solve this? The idea is pretty simple—you have a string with some “extra” characters you have to get rid of (like the thousands separators or the currency) and change the decimal separator from a comma to a dot. If you do that, the number can be understood by PHP as a float number and, therefore, its VAT can be computed. The resulting function looks like this:

and the results you get after running the test again are:

Example of a PHPUnit test that passes
See? Now the test passes and we know that our function meets our requirements ?

JavaScript Testing Frameworks

If you want to test PHP, the most obvious solution is PHPUnit—there aren’t any “real” alternatives to unit test it. But if we talk about JavaScript the reality is completely different—there’s plenty of options for you to choose. In stateofjs there’s a detailed comparison of some JavaScript testing frameworks and, man, it’s huge!

JavaScript Testing Frameworks
Comparison of different JavaScript testing frameworks(source).

Mocha

Mocha is a feature-rich JavaScript test framework that can run on both Node.js and your browser, created to be a simple, extensible, and fast testing suite. It’s used for unit and integration testing, and it’s also a great candidate for Behavior Driven Development (BDD).

Mocha - JavaScript Testing Framework
Mocha is a fantastic JavaScript Testing Framework

Jasmine

Another trendy framework is Jasmine. As stated in their website, it’s a behavior-driven development framework for testing JavaScript code. Jasmine doesn’t require a DOM, has no dependencies, and has a clean and clear syntax. Its documentation is quite good too, so you can quickly learn how to use it.

Jasmine - JavaScript Testing Framework
Jasmine is another trendy testing framework for JavaScript.

If you’re wondering which one is better, there’s plenty of blog posts comparing them (and others). If you want my opinion, though, you should try them all and stick to the one that makes you the happiest. However, you might also want to take a look at QUnit.

QUnit

QUnit is the last JavaScript testing framework I wanted to mention today. Its goal was to test jQuery (you’re familiar with it, right?) and it’s been with us for a while. As far as I can tell, it looks like QUnit has lost some momentum, but it’s worth talking about it, as QUnit is the framework used in WordPress to test its JavaScript components.

QUnit - jQuery's testing framework
Qunit is yet another JavaScript testing framework. It’s special because (a) it was born to test jQuery and (b) it’s currently used in WordPress core.

Setting Up Our First QUnit Test

Let’s assume we have our beloved function nelio_get_vat written in a JavaScript file named functions.js:

As you can see, there’s nothing fancy with it—it’s the exact function we saw in PHP, but written in JavaScript. Therefore, this function will behave (presumably) as the PHP counterpart did—it’ll compute the 21% VAT of any given amount of money, regardless of its format. The function accepts both numbers and strings, and strings can… well, you’re already familiar with our function, aren’t you?

The tests we want this function to pass could be written as follows in a file named, for instance, tests.js:

I’ve slightly changed the particular tests, but I’m sure you have no problem in understanding what’s going on. To check whether our function can pass these tests or not, we need to create a tiny HTML document that includes all the requirements: the QUnit library, the JavaScript function we want to test, and the tests themselves:

If we now open this document in our web browser, we’ll get the following:

QUnit Test Results
Hurrah! Our QUnit tests were a complete success. Man, I love that green ?

which means all our tests were a complete success!

A Few Tips and Tricks to Become a Better Programmer and Tester

As you can see, there’s no magic behind unit tests—sure, there’s a lot of things we haven’t discussed yet (such as, for example, how to set up an environment with already-existing data), but it’s all about using the testing framework and its functionalities properly. Truth is, it doesn’t really matter the language you’re testing—what’s important is to believe in testing as a concept and try to be as efficient as possible when doing it.

The most difficult part is, as always, getting started and keep up with the initiative. Questions like “am I testing the right component?”, “am I forgetting about something important?”, “are these tests really useful?”, “would anyone care if I skip this test?”, and so on are not always easy to answer and the answers can be discouraging. But if you’re asking them yourself, at least it’s clear you care.

To answer most of them, I recommend you watch the following videos. I loved them both, and I still re-watch them from time to time.

In this first video, Roy Osherove talks about good practices and horrible mistakes when testing JavaScript code (but, as I said before, his ideas apply to all languages and testing frameworks). I really encourage you to spend one hour of your time and watch the video—he teaches how to improve your testing skills easily and effectively.

In my opinion, the most interesting parts of his talk are:

  • A good unit test has three basic properties (watch in the video)
    1. It’s  TRUSTworthy. If the test tells you everything’s alright and you don’t trust it, you’ll want to recheck your code to make sure that, indeed, it is. Or if it tells you something isn’t right and you don’t believe it, you might be tempted to tell yourself “hey, tests sometimes fail; I’m sure everything’s alright”. See? If you don’t trust the results of your test, why would you bother to create them in the first place?
    2. It’s MAINTAINable. Tests will eventually change because your tested code will probably change too, so make sure they’re clean and clear. Don’t intermingle too much information in a unique test, keep them clean and short so that they can be easily adapted to your future needs.
    3. It’s READable. If a test fails, a programmer will want to know why. In other words, they’ll probably need to take a look at the test, read it, and understand what it was supposed to test (if it’s properly named, they might even be able to skip the source code). If your test can’t be read, you and future programmers will have trouble maintaining your code.
  • Tests must be simple (watch in the video). The more code you add in a test, the more likely it is that the test itself will have bugs. And that’s kinda weird! You don’t want your test code to contain bugs itself. The easiest way to “guarantee” that is by writing simple tests. So try to write short, simple tests, with no loops, no if/else statements, etc.
  • Use meaningful names (watch in the video). This is probably the most enlightening part of the video. If you really want people to understand what a test does, name it properly. To do so, make sure the following three facets are perfectly stated:
    1. Unit of Work: WHAT we are testing. This might be a class, a function, a module… whatever, but make sure it’s clearly stated.
    2. Scenario: WHEN and HOW we are running the test, what the context is. There are functions that behave exactly the same no matter what, others depend on the types of their attributes, others on the database state. For instance, saving a post that doesn’t exist behaves differently from saving a post that already exists, so that’s the scenario: are we saving a new instance or are we overwriting an already-existing instance?
    3. Expected Behavior: WHAT should (or shouldn’t) happen as the result of our test? The most important part here is to state that using the verbs SHOULD and SHOULDN’T. For instance, the following test is very clear: “Given the function wp_post_save (unit of work), when we save an already-existing post (scenario), the post’s ID should be the same as it was before saving it (expected behavior)”. If, on the other hand, the expected behavior was states as “…, the post ID is the same as it was before saving it”, it’s not clear if we’re stating a problem (the post ID is the same, and it shouldn’t) or if we’re already stating what we expect.

The second video is very useful for beginners. I remember that one of the things I struggled the most when I started to test my code was the fact that it couldn’t be tested—my code wasn’t that complicated, but I didn’t know how I could test it!

And that’s when Rebecca showed me the light! At 4:43 Rebecca shows a small JavaScript application and reveals its source code—it’s not very elegant, but it’s not a mess either. Or is it? That was the kind of code I used to write (and, I must confess, sometimes I still do), but this code can’t be tested at all! Different functionalities are intermingled, there’s no clear distinction between UI and application state, between server communication and setup, there’s plenty of lambda functions…

A few minutes later, the speaker shows you the light and tells you how to write your test so that it becomes testable and, as a result, readable and maintainable:

  • Use constructors to create instances
  • Support configurability
  • Keep methods simple
  • Don’t intermingle responsibilities

I could try to summarize her thoughts about each guidelines, but I really, really encourage you to watch her explain them. If you do so, you’ll see how wonderful it is to apply them in your own work

In Summary

Testing JavaScript code is no different from testing PHP or any other language. What matters is your willingness to (first) start to test code and (second) to improve your skills so that your code can be easily tested and, as a result, become better code per se. Tests are supposed to be short and clear, and so should be your tested components. If you apply the guidelines described in the videos above, you’ll become a better tester and programmer; I guarantee that!

Next week we’ll see a complete example in WordPress where we’ll test both PHP and JavaScript. In particular, we’ll create a small AJAX callback and we’ll see how to test both the front-end and the back-end. See you soon! ??

Featured Image by etringita.

Leave a Reply

Your email address will not be published. Required fields are marked *

I have read and agree to the Nelio Software Privacy Policy

Your personal data will be located on SiteGround and will be treated by Nelio Software with the sole purpose of publishing this comment here. The legitimation is carried out through your express consent. Contact us to access, rectify, limit, or delete your data.