Part one of five

Testing your frontend code: An introduction

Gil Tayar
frontend testing
© Shutterstock / REDPIXEL.PL

How do you start testing your apps? In this first installment in a series of five articles, JAX London speaker Gil Tayar introduces frontend testing for beginners, starting from what it is and why testing code is not optional.

A while ago, a friend of mine, who is just beginning to explore the wonderful world of frontend development, asked me how to start testing her application. Over the phone. I told her that, obviously, I can’t do it over the phone as there is so much to learn about this subject. I promised to send her links to guide her along the way.

And so I sat down on my computer and googled the subject. I found lots of links, which I sent her, but was dissatisfied with the depth of what they were discussing. But I could not find a comprehensive guide — from the point of view of a frontend newbie — to testing frontend applications. I could not find a guide that discusses both the theory and the practice, and is oriented towards testing frontend application.

So I decided to write one. And here it is. This is part one. You can find the other parts here:

What is testing?

Testing, as I define it, is code that checks that the code that you write in your app, also called “production code”, works as expected. Some people refer to this as TDD, but TDD (Test-Driven Development or Test-Driven Design) is a specific methodology of Testing, where the tests are written first and drive the design and implementation of the product.

Frankly, I don’t think it matters whether you write the test before or after the production code, as long as you write enough tests to make you feel confident that your production code is ready. But a lot of people (which I respect) do think it’s important, so I’m laying it here on the table.

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 choose to call it Developer Testing, or just plain Testing. If you’re interested in a series of discussions around this issue of TDD vs just plain testing, you can watch these, but I would suggest you watch this after you read the whole series of these blog posts.

SEE MORE: Angular, Ember and Vue: Is choosing a framework simply a matter of taste?

Why test?

No — I am not going to discuss the why of testing. If you don’t want to test your code, then don’t. Too bad for you, as you will be doing manual testing of your web app again and again and again. Those pesky bugs, which you remember fixing a while back, will come back again to haunt your nights. Deploying to production will become a task ridden with instability and fear.

But, no, I am not going to discuss why you should test.

The types of tests

Another area that is very confusing, especially to beginners starting to study testing, is the various types of tests. If you’ve researched the subject, you’ve probably heard about (and this is a partial list): unit tests, acceptance tests, integration tests, end to end tests, component tests, and service tests.

To make matters worse, when one person discusses one of these terms, it is probable that their definition of that term is different from another person’s.

SEE MORE: Testing Java Microservices: Not a big problem?

And again, I don’t really care about which term is used, since I believe that there is no hard definition of types of tests. But I do believe that all tests lie in a spectrum where on one side we have unit tests, and on the other end-to-end tests (henceforth to be abbreviated as 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).

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.

These are easy to test 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.

SEE MORE: Use automated testing to make sure your app is bug-free

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 (admittedly contrived) 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.

SEE MORE: Kotlin Native serverless tutorial: Fun with Fibonacci

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 means 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.

SEE MORE: Integration testing using Spring Boot, Postgres and Docker

The first part of the series, after this post, will discuss frontend unit tests. The second part will discuss integration tests, the third part will discuss E2E tests, and the last part will discuss testing strategies — how much of each tests do you need, and other considerations.

For the purpose of this blog, I wrote a small app — Calculator — that I will use to demonstrate the various types of testing. You can see the source code here. Note that it isn’t yet fully tested, but it will be once this series of blog posts will be done.

So keep tuned for the rest of the series! In part two, I will discuss unit testing.

 

This post was originally published on Hacker Noon.

Gil Tayar will be delivering a talk at JAX London that will go into more detail with these ideas, explaining how easy it is for you to build your own microservices architecture. He will also lead an introductory workshop on NodeJS.

just give me a reason, just a little ones enough

Author

Gil Tayar

30 years of experience have not dulled the fascination Gil Tayar has with software development. From the olden days of DOS, to the contemporary world of Software Testing, Gil was, is, and always will be, a software developer. He has in the past co-founded WebCollage, survived the bubble collapse of 2000, and worked on various big cloudy projects at Wix.

His current passion is figuring out how to test software, a passion which he has turned into his main job as Evangelist and Senior Architect at Applitools. He has religiously tested all his software, from the early days as a junior software developer to the current days at Applitools, where he develops tests for software that tests software, which is almost one meta layer too many for him.


Comments
comments powered by Disqus