Introduction to the front-end testing. Part one

SHARE

We are starting a series of articles devoted to testing. This introductory part will delve you into the front-end testing as it is told on behalf of one of our friend who is a blogger too. Here we go!

Recently, a friend of mine who is just getting started in the wonderful world of front-end development called me to ask on how to test her application. I replied that I could not help her over the phone, as I needed a lot of time to study this topic, promising to send her some links.

Sitting at my computer, I googled this question and found many links that I sent to her, but was dissatisfied with the depth of the material presented in them. I haven’t been able to find a detailed front-end testing guide that addresses this issue from a beginner’s perspective, both theory and practice.

In the end, I decided to write it myself.

What is testing?

In my opinion, testing is code that checks whether your application code, the so-called “production code”, works as expected. Some people refer to it as TDD (test-driven development), a specific methodology of testing where tests are written at the very beginning and guide further product development.

Frankly, I don’t think it matters whether you write tests before or after the production code, as long as there are enough of them to be sure of the quality of the product. However, many people I respect think it’s important.

Unfortunately, the industry has conflated the idea of Testing with TDD, and thus there is no standard term for code that is written by the developer alongside the production code. I decided to call it just testing.

Why is testing necessary?

No, I’m not going to discuss why code should be tested. If you don’t want to test it, just don’t. It will be very frustrating for you to manually check your application over and over again. You will definitely remember fixing those pesky bugs that will keep coming back to deprive you of sleep. Deploying to production will become a task ridden with instability and fear.7

No, I’m not going to discuss why testing is necessary.

Types of testing

Another area that confuses people who are learning about testing is the different types of tests. If you have studied this topic, you have probably heard about unit testing, integration testing, end-to-end (E2E) testing (ADD LINKS), and component testing.

And even worse, each person describes these concepts in his own way.

Again, the question of terminology does not concern me much – I believe that test types do not have a strict definition. In my opinion, all tests lie in the range that starts with unit tests and ends with E2E tests.

The Spectrum of Test Types

Let’s start with the simplest type  –  the unit test. The unit test is, by definition, code that tests a “unit”. And what is a unit? Well, that depends on your programming language. It can be a function, a module, a package, a class. Even an object (for languages like JavaScript and Scala). In JavaScript, it’s usually a class or a module (a “module” in the npm/CommonJS sense of the world, i.e. a file with code).

Do not forget to read our article “Purposes of Unit Tests” (ADD LINK)

The important thing is that this unit is tested in isolation. This is perfect for algorithmic, functional stuff, like a function that counts the number of characters in a string, or a class that has a set of validation functions.

It is easy to test code in isolation, because they do not depend on other units at all. But what if the unit I want to test does depend on another unit? Well, we can do two things here: either test the two units together, or mock the other unit.

If we test the two units together, is it still a unit test? This is where the spectrum starts – purists will say that it isn’t a unit test anymore. I say that I don’t care. I tend to still call them unit tests, but if somebody else wants to call them integration tests, or two-unit tests, then I’m fine with that.

What does mocking mean? Let’s give an example:

exports.writeSumToFile = (a, b, fileSumWriter) => {

  const sum = a + b

 

  fileSumWriter(sum)

}

This unit is a module with a writeSumToFile function that accepts two numbers and writes their sum to a file.

But notice that it doesn’t do the writing itself. It uses another unit (fileSumWriter) to do the writing.

To test this unit, we can either pass the real fileSumWriter or we can create a mock implementation that doesn’t really do the writing.

When we pass a mock to the function_,_ then the test is definitely a unit test, in the purest sense of the word. But if we test the two units together, a lot of people will argue that it’s not a unit test.

I don’t care what it’s called.

So on the one hand, we have code that tests one unit. And on the other hand, there is the E2E test – the test of the whole application. Everything is tested in the E2E test, and the application is run in the same setup as in production.

Those are the two ends of the spectrum. The points between these two extremes are where most tests lie — they define an ever increasing scope of testing. In those points between the extremes, more and more of the code is tested, and less and less of the code is mocked.

Some people call the tests between these two extremes “Integration Tests”, but for the TDD-ers, integration tests mean a whole different thing, which we’ll discuss in a bit. I am going to use the non-purist name – integration tests – for exactly that: tests that test more than a unit, but don’t test all of the units.

So where do you put your tests? Most people argue that there is a testing pyramid – lots of unit tests, much less integration tests, and a really small number of E2E tests. But let’s leave that discussion to the end of this series of posts, because in this series of posts I want to discuss how to do unit, integration, and E2E tests for frontend code.

For the purpose of this blog, I wrote a small app – Calculator – that I will use to demonstrate the various types of testing.

So, keep posted for further updates on the topic!