A little talk about front-end testing

I should have written this article in December, roughly because my colleagues need to do SDK development, and I require corresponding tests, but I am confused about how to design tests. I originally wrote an article as early as 19 years ago. Construct some meaningful tests , but from a certain point of view this is more back-end, and there are some differences for front-end tests.
Then I was laid off. I didn’t want to write it at first, but I actually mentioned some content when I helped to do mock interviews and was interviewed, so here is a brief talk about my views on front-end testing.
Attention for new readers: I talk a lot of nonsense, don’t spray if you don’t like it, click the cross on the upper corner. (I’m so fragile, brother.jpg)

when do we need to test

If your answer is: “Of course you need to test at any time” – then congratulations, you have not been beaten by real scheduling and business (here refers to the situation of the domestic Internet).

Ideally, we certainly hope that “there are all tests and the test coverage reaches 100%”, but the reality often cannot support this beautiful vision.

When do we choose to write test code in this case? A few core points are:

  1. Core, high-risk business content, such as the article I wrote in 19 years, is a large-scale coverage of the back-end services of payment, membership, and orders
  2. Providers of basic capabilities, such as infrastructure and general infrastructure, including the SDK in the introduction part of this article
  3. For the front end, basic components can also be used as test items

In fact, we can see from the above that, in addition to the core business is to stop losses, most of the parts that can be written first are because the overall demand development is relatively controllable and will not change overnight. One shot moves the whole body, one bug, and the whole family is finished.

Of course, in fact, many companies are in the state of 0 testing, including some internal tools that I used when I was at station B, but there are actually no tests or low test coverage. Therefore, there are indeed many hidden dangers buried in it.

Due to the iteration rate of most companies and the instability of requirements, it is not cost-effective to do some integration tests for the business. More importantly, if you are free, you can do some tests for your own utils methods.

Of course, if the business is stable and the schedule is loose, there is no doubt that you can achieve the effect you want.

test coverage

In the 19-year article, there is actually a description of test coverage. Here it is reiterated that testing needs to pursue coverage, but not 100% coverage.

This point was also discussed with the interviewer in this interview (it seems that there are more than one), if there is no test coverage indicator, then the test will be meaningless, because everyone can be lazy and not do the test for various reasons; but if Excessive pursuit of numbers, the next face may be more disastrous results:

In personal (open source) projects, you can play whatever you want, but in enterprise development, we often encounter a balance between time and robustness. Most bosses actually only pay attention to “fast, rough and fierce”. Push the first version up, and we’ll talk about the rest later. If you pursue coverage too much in this situation, it is basically equivalent to an inhumane forced march. You can set a small goal first, such as 80% coverage instead of 90%-100%.

Because it is easy to shout a slogan, but when you actually start writing tests, you will find that to perfectly cover your case instead of just caring about numbers, the time to write tests will be 1.5-3 times the development time, and with the The coverage index has risen exponentially, that is to say – there are some corners where it is not easy to do, that is, “the cost performance is not high”.

Of course, if these difficult things are the core content, then it has to be done. In this case, it is actually more inclined to once and for all, and it is also a cost-effective investment. This is another matter.

what is the test for

This seems to be a nonsense, you may say “testing, of course it is for testing”. But in fact the test provides us with the following convenience:

  1. It is convenient to find problems in time – this is the original function of testing
  2. Provide examples of usage through the test set – can effectively reduce the amount of your documents and explain less popular cases
  3. It is convenient for future generations to pick up the code – when there is a test, you will know whether you are writing a bug or a feature

In fact, the simplest integration test itself is a Quick Start, which can be directly pasted for testing, and we usually add comments at the same time. Coincidentally, the readability of the code has increased.

Of course, there are occasionally speechless situations here: the accepted students changed the code and changed the test together-maybe it is another kind of correctness. It is recommended that you must see clearly the meaning and value of the test code before starting the test.

front-end testing

The back-end test already has a portal at the beginning of the article. The focus of this article is still on the front-end test. Common tests are unit tests and integration tests.

Here we take the buried point library SDK as an example, because the unit test in the UI business has limited space to play, and it is relatively thankless. The case of the front-end SDK is more typical (simple) and comprehensive.

unit test

When it comes to unit testing, the first thing we think of is jest . It is an old-fashioned test. You can read official documents and various articles about how to use it. Skip this one here; in addition, our last legacy SDK has already used Vitest . In theory, it should be better to use than jest.

In terms of directory structure, one src file corresponds to one test file, which is more clear at a glance:

 ├── src │  ├── index.ts │  ├── trackers │  │  └── web │  │  ├── click.ts │  │  ├── expose.ts │  │  └── pv.ts │  ├── typings │  │  └── window.d.ts │  └── utils │  ├── buvid.ts │  ├── format.ts │  ├── http.ts │  └── utils.ts ├── test │  └── unit │  ├── index.test.ts │  ├── trackers │  │  └── web │  │  ├── click.test.ts │  │  ├── expose.test.ts │  │  └── pv.test.ts │  ├── tsconfig.json │  └── utils │  ├── buvid.test.ts │  ├── format.test.ts │  └── utils.test.ts

Here are a few points worth discussing:

The first is whether we want to use TDD, TDD is a very old topic, I even wrote an article when I was not working (2016, check it out, don’t dig the grave): Node.js with Mocha+ Chai is an introduction to unit testing , but in actual work, due to the reasons mentioned at the beginning of the article, we rarely use full TDD (I used it in back-end testing, because this is clearly what must be tested, and the rest In most cases, it may be affected by iteration scheduling), in most cases, our more development ideas are:

  1. What capabilities does my library need to provide
  2. How to split these capabilities into functions (try to have no side effects)
  3. Overwrite the functions of my export one by one
  4. Fill in the edge cases that come to mind

The most difficult part of unit testing may be to mock the parts you need one by one. At the same time, in order to avoid interference, it is recommended to use less global variables and write more side-effect-free functions, which will make your development journey much smoother.

For most infrastructure projects, unit testing is a very cost-effective method, and it is highly recommended that you take the time to do it. (Of course, it’s easy to get numb with mocking. For example, I can’t continue scrolling until the end, and I need to mock too many things).

Integration Testing

As mentioned above for a long time, in fact, for unit testing, there is not much difference between the front end and the front end. The front end mocks the browser and network IO; .

It is even more painful for integration testing. Here we are trying to use cypress . If unit testing is to test functions, then integration testing is to test capabilities. Simplify the idea introduced in the single test above:

  1. What capabilities does my library need to provide
  2. How to achieve it with code
  3. ability to override my design
  4. Fill in the edge cases that come to mind

It can be said that if the unit test still requires you to split the specific code and then test the design, then the integration test can be designed from the beginning-after all, in the system design stage, you have already finalized “what will I provide” .

The rest may be a long and painful mock stage, and you may even need to prepare a server to host your test page.

Summarize

For most engineers who have just started writing tests, the stuck point may be more about how to choose and how to design my test cases. Here are some simple ideas. As for the use of specific libraries, there are already too many on the Internet. Basic tutorials, and the pits should be filled by stackoverflow and GitHub issues.

And why everyone is too lazy to write tests-according to my actual test experience, it is not more about testing, but about mocking, which is long and painful.

Looking forward to the future, we naturally hope that AI can solve most of our troubles, such as the “integration test based on the provided capabilities” mentioned above-is there a kind of input that can be given to AI to spit out code for me, and I can delete, modify and modify it? It’s a wonderful illusion of being able to run.

This article is transferred from https://www.codesky.me/archives/meaningful-frontend-test.wind
This site is only for collection, and the copyright belongs to the original author.