Today, we are going to discuss testing in JavaScript and help you start your journey towards understanding and mastering it.


Testing is one of the most important topics in software development, but a lot of developers still shy away from it. This article is here to change that.

测试是软件开发中最重要的主题之一,但是许多开发人员仍然回避它。 本文是为了改变这一点

The primary motivation behind this article is to give a clear overview of the entire world of JavaScript testing and making it simple to understand. Even if you have no prior experience in testing, this article will prove to be the perfect start for your journey.

本文的主要动机是为了清晰地概述JavaScript测试的整个世界,并使之易于理解。 即使您没有测试经验,这篇文章也将被证明是您旅程的完美起点。

So, without wasting any further time, let’s get started.


为什么测试很重要 (Why testing is important)

Before diving into the various types and concepts of software testing, you should first have a clear understanding of why you should actually care about automated testing in the first place.


建立对代码的信心: (Building Confidence In Your Code:)

To know that your code is working as planned, it needs to be tested in some kind. Manual test work for most small applications but don’t provide the security and confidence level you get using automated tests.

要知道您的代码是否按计划工作,需要进行某种形式的测试。 手动测试适用于大多数小型应用程序,但不能提供使用自动测试获得的安全性和置信度。

Automated tests make it easy to test almost every possible situation and allow you to run them whenever you are making a change to your code.


Identifying every success and failure case and writing tests for them will ensure that you are confident with the code you are deploying for production.


编写最小代码: (Writing Minimal Code:)

Testing also helps you to reduce the amount of code you are writing for a particular feature. After testing, your main goal is to write the minimal required code to make the tests pass. This coding style where you write tests before you write the actual implementation is also known as TDD (Test-driven development).

测试还可以帮助您减少为特定功能编写的代码量。 测试之后,您的主要目标是编写所需的最少代码以使测试通过。 在编写实际实现之前编写测试的这种编码方式也称为TDD(测试驱动的开发)。

After successfully testing, you can focus on writing clean implementations with as minimal code as possible.


摆脱回归错误: (Getting Rid Of Regression Bugs:)

Do you know the feeling when you have just finished a new feature of your application and want to release it to production and all of a sudden, an old feature isn’t working anymore? You are absolutely clueless about why this is happening and will probably waste a lot of time searching for the issue.

当您刚刚完成应用程序的新功能并想将其发布到生产环境中时,突然之间,旧功能不再起作用了,您是否知道这种感觉? 您绝对不知道为什么会这样,并且可能会浪费大量时间来寻找问题。

This situation would have never occurred if you had tested your old features. You could have frequently run those tests to check if your application is still working as expected. The tests would also give you a better idea of what exactly isn’t working anymore because the appropriate test cases would fail.

如果您已经测试了旧功能,则永远不会发生这种情况。 您可能经常运行这些测试,以检查您的应用程序是否仍按预期运行。 这些测试还将使您更好地了解什么不再起作用,因为适当的测试用例将失败。

测试类型 (Types of tests)

There are a few different types of tests, and it is essential to know how they differ from each other. Most applications will require you to write multiple kinds of tests to get the best result possible.

有几种不同类型的测试,因此必须知道它们之间的区别。 大多数应用程序将要求您编写多种测试以获得最佳结果。

单元测试: (Unit tests:)

The purpose of a unit test is to validate the functionality of a relatively small piece of software, independently from other parts. Unit tests are narrow in scope, which allows us to cover all cases to ensure that every single part works correctly.

单元测试的目的是独立于其他部分,验证相对较小软件的功能。 单元测试的范围很窄,这使我们能够涵盖所有情况,以确保每个部分都能正常工作。

They are small and highly focused tests that can efficiently be executed on your local machine because of their fast execution time. You are going to have hundreds, if not thousands of these tests and run them on a regular basis while developing.

它们是小型且高度集中的测试,由于其执行时间短,因此可以在本地计算机上有效地执行。 您将拥有数百个(如果不是数千个)这些测试,并在开发时定期运行它们。

The only downside to these kinds of tests is that they are not executed on real devices and therefore have lower fidelity than the other types of tests.


集成测试: (Integration tests:)

Integration tests demonstrate that the different parts of your application work together in a real-life production environment. They verify that two separate modules or components are working together in the way they should.

集成测试表明,应用程序的不同部分可以在实际的生产环境中协同工作。 他们验证了两个独立的模块或组件是否按应有的方式协同工作。

These tests are of medium size and have a much higher execution time then Unit tests. They aren’t executed as often but are still vital for checking the health status of your applications. Their fidelity is also a lot higher because they run on real devices and verify the actual interaction between various components of your application.

这些测试的大小适中,执行时间比单元测试长得多。 它们执行的频率不高,但对于检查应用程序的运行状况仍然至关重要。 它们的保真度也更高,因为它们在真实设备上运行并验证应用程序各个组件之间的实际交互。

端到端测试: (End-to-End tests:)

End-to-End tests validate complex scenarios from end to end, and usually require external resources, like databases or web servers, to be present. Imagine you have an application with a sign-up flow comprising of several steps, and you want to test the entire flow, that’s where End-to-End tests come into play.

端到端测试从头到尾验证复杂的场景,并且通常需要使用外部资源,例如数据库或Web服务器。 想象一下,您的应用程序具有包含几个步骤的注册流程,并且您想要测试整个流程,这就是端到端测试的作用。

E2E tests will also run on real devices just like integration tests and therefore, will again be quite slow in their execution.


The only downside to these kinds of tests is that debugging them and finding out what went wrong if a particular test fails becomes very hard because of their vast scope.


概念 (Concepts)

Before starting to write tests for your code, you first need to be familiar with the most crucial testing concepts and when you need to use them. These concepts will influence the architecture of your application and how you write code in general but more on that in a later section.

在开始为代码编写测试之前,您首先需要熟悉最关键的测试概念以及何时使用它们。 这些概念将影响应用程序的体系结构以及总体上编写代码的方式,但在后面的部分中会对此有更多影响。

匹配器: (Matchers:)

Matchers let you validate the results and values of your tests in different ways and are used to make sure that the results of the test match your expectations.


Imagine you have a function that calculates the result of a certain factorial number. Testing the function can then be done using the expect() function and a simple matcher that checks if the result of the function matches the expected value.

假设您有一个函数可以计算某个阶乘数的结果。 然后,可以使用Expect()函数和一个简单的匹配器来测试该函数,该匹配器检查函数的结果是否与期望值匹配。

test('factorial of 2', () => { expect(factorial(2)).toBe(2); });

The expect() function checks if the result meets the conditions defined by the matcher. We will make use of different matchers in the Jest testing framework at a later point in this guide.

Expect()函数检查结果是否满足匹配器定义的条件。 在本指南的后面,我们将在Jest测试框架中使用不同的匹配器。

模拟: (Mocking:)

An object under a test might have dependencies on other objects or services. To isolate the behavior of an object, you want to replace the other objects it interacts with by mocks that simulate the behavior of the real objects.

被测对象可能与其他对象或服务具有依赖性。 要隔离对象的行为,您想用模拟真实对象行为的模拟替换与之交互的其他对象。

Mocks help your tests to avoid test unreliability (flakiness) and improve the speed of your tests. They are also useful if the real objects are impractical to incorporate into tests.

模拟可以帮助您避免测试的不可靠性(易碎性)并提高测试速度。 如果实际对象不适合合并到测试中,它们也很有用。

In short, mocking is creating objects or services that simulate the behavior of real objects (A database, for example).


生命周期: (Lifecycle:)

When testing, you often execute multiple tests after each other and have some setup work that needs to happen before the tests run. Most frameworks provide helper functions to handle these scenarios.

测试时,您经常会接连执行多个测试,并且在运行测试之前需要进行一些设置工作。 大多数框架提供帮助程序功能来处理这些情况。

Here is an example of lifecycle methods in the Jest testing framework.


beforeEach(() => {
// Initialize objects
});afterEach(() => {
// Tear down objects

可测试的架构 (Testable architecture)

Before starting to write tests for your code, you first need to make sure that your application’s architecture is testable. If it is not, you need to understand why not and what you can do about it.

在开始为代码编写测试之前,首先需要确保应用程序的体系结构是可测试的。 如果不是,那么您需要了解为什么不这样做以及您可以对此做些什么。

Untestable architecture is probably the most common reason why many people find testing tedious and difficult. If your code is not structured properly, you are definitely going to find it difficult to write tests for it.

无法测试的架构可能是许多人发现测试乏味且困难的最常见原因。 如果您的代码结构不正确,您肯定会发现很难为其编写测试。

Let’s explore some important concepts you should know when talking about testable architecture.


依赖注入: (Dependency injection:)

Dependency injection is a concept where an object supplies the dependencies of another object. Instead of using the new keyword whenever creating a new object, all you need to do is ask the other object to give you the instance you want.

依赖注入是一个对象提供另一个对象的依赖关系的概念。 您只需要做的就是让另一个对象为您提供所需的实例,而不是在创建新对象时使用new关键字。

This concept helps when you need to change the implementation of some object, e.g. when you mock it for a particular test. Many modern frameworks like Angular and Nest.js have dependency injection already build in, but it is still good to know how it functions at a base level.

当您需要更改某些对象的实现时,例如,当您为特定测试模拟它时,此概念会有所帮助。 许多现代框架(例如Angular和Nest.js)已经内置了依赖项注入,但是最好知道它在基本级别上如何工作。

For more information on dependency injection, you can visit the following article.


SRP(单一责任原则): (SRP (Single responsibility principle):)

The single responsibility principle, also known as SRP, is one of the SOLID principles and defines that a function should have a single purpose. This makes it far easier to test that each function does its part correctly.

单一责任原则,也称为SRP,是SOLID原则之一,它定义了功能应具有单一目的。 这使得测试每个功能是否正确发挥作用变得容易得多。

If your function or service is performing more than one responsibility, then it is time to identify those responsibilities and separate them into individual functions.


避免副作用: (Avoid side effects:)

Your functions depend on external variables and services, and you have to set up that variable or service before testing your function. You’ll also have to trust that any other code being run isn’t altering that same variables and states.

您的函数取决于外部变量和服务,并且在测试功能之前必须设置该变量或服务。 您还必须相信正在运行的任何其他代码都不会更改相同的变量和状态。

That is why you should avoid writing functions that alter any external state (like writing to a file or saving values to a database). This prevents side effects and allows you to test your code with confidence.

这就是为什么您应避免编写会更改任何外部状态的函数(例如,写入文件或将值保存到数据库)的原因。 这样可以防止副作用,并使您可以放心地测试代码。

得墨meter耳定律: (Law of Demeter:)

The Law of Demeter, which is also known as the “principle of least knowledge” states that a specific unit should have limited knowledge of the other units it coordinates with. The more your code depends on the internal details of the objects it interacts with, the more difficulty you will have when writing tests for them.

得墨meter耳定律(也称为“最少知识原理”)规定,特定单位对与其协调的其他单位的了解有限。 您的代码越依赖于与之交互的对象的内部细节,在为它们编写测试时就会遇到更多的困难。

More information about the Law of Demeter can be found here.


各种测试工具概述 (Overview of the different testing tools)

Now that you have an overview of the essential concepts in the testing world and when you need to use them, let’s continue by looking at a short summary of the different Javascript testing tools that are available today.


Note: I will not cover every tool there is but instead look at the most important once to give you a quick overview of there benefits and weaknesses.


Jest is an open-source testing framework created by Facebook with a focus on simplicity. Jest makes it faster and easier to write JavaScript tests by having everything included out of the box and needing zero configuration. Jest also runs your tests in parallel, providing a smoother, faster test run.

Jest是Facebook创建的一个开放源代码测试框架,专注于简单性。 Jest通过开箱即用并需要零配置来使编写JavaScript测试更快,更轻松。 Jest还可以并行运行测试,从而提供更流畅,更快的测试运行。

Mocha is a flexible JavaScript testing libraries available and aims to make asynchronous testing simple and fun. It provides developers with a basic test framework and gives them the option to choose which assertion, mocking, and spy libraries they want to use.

Mocha是一个灵活JavaScript测试库,旨在使异步测试变得简单而有趣 它为开发人员提供了一个基本的测试框架,并为他们提供了选择要使用的断言,模拟和间谍库的选项。

It requires some additional setup and configuration but gives you complete control of your testing framework in return.


Cypress is an all in one testing tool that is focused on making End-to-End testing easy and modern. Their tests are executed in the browser themself which gives them a better execution time and no network lag.

赛普拉斯是一款多功能的测试工具,致力于使端到端测试变得轻松而现代。 他们的测试在他们自己的浏览器中执行,这为他们提供了更好的执行时间并且没有网络延迟。

Cypress is used to deal with complex UI’s running on modern Javascript stacks. By using their framework and assertion library, it becomes easy to validate states in the UI. Cypress will then automatically wait for your application to reach this state before moving on.

赛普拉斯用于处理在现代Javascript堆栈上运行的复杂UI。 通过使用它们的框架和声明库,可以轻松验证UI中的状态。 然后,赛普拉斯将自动等待您的应用程序达到该状态,然后再继续。

Cypress is a newer and more modern tool than Jest and Mocha and is an excellent start for beginners and End-to-End testing in general.


笑话简介 (Introduction to Jest)

As already mentioned above, this guide will focus on the Jest testing framework because it is the most popular framework out there. But most of the concepts apply to all testing frameworks and can be useful no matter which technology you are using.

如前所述,本指南将重点介绍Jest测试框架,因为它是目前最流行的框架。 但是大多数概念都适用于所有测试框架,并且无论您使用哪种技术,它都可能有用。

Jest is an open-source project maintained by Facebook and is especially well suited for Unit and Integration testing. Its strengths are:

Jest是Facebook维护的一个开源项目,特别适合单元测试和集成测试。 它的优势是:

  • It is simplistic and fast

  • It provides everything out of the box and thereby doesn’t require and configuration (though you can change the configuration if you so choose)

  • It can perform snapshot testing


Now we will explore some practical examples so you can put your knowledge into practice.


安装 (Installation)

Jest can be installed using either npm or yarn:


yarn add --dev jest 
# or
npm install --save-dev jest

Notice that this will install Jest as a dev dependency as part of your package.json file in the current project. You can alternatively install it globally if you so choose.

注意,这会将Jest作为开发依赖项安装为当前项目中package.json文件的一部分。 您也可以选择在全球范围内安装它。

yarn global add jest 
# or
npm install jest -g

You can also add this line to your package.json to run your test using the test command.


{ "scripts": { "test": "jest" } }

您的第一个测试 (Your first test)

Now that we have installed Jest it is finally time to write our first test. But before we do that, we will write some basic code that we can test in the first place.

现在我们已经安装了Jest,现在终于可以编写我们的第一个测试了。 但是在执行此操作之前,我们将首先编写一些可以测试的基本代码。

For that, we will create two files so we can get going.


touch maths.js 
touch maths.spec.js

We will use the following function for calculating a factorial number to write our first test.


function factorialize(num) {
  if (num < 0) return -1;
  else if (num == 0) return 1;
  else {
    return num * factorialize(num - 1);

module.exports = { factorialize }

Here are some very basic test cases for this small function.


const { factorialize } = require("./maths");

test("factorial of 3", () => {

test("factorial of 5", () => {

Running the yarn test command in your terminal should give you the following output:

在终端中运行yarn test命令,将为您提供以下输出:

匹配器 (Matchers)

As already said above matchers let you validate the results and values of your tests in different ways.


They are most commonly used to compare the result of the expect() function to the value passed as an argument to the matcher (That is also what we did above).


Here is a list of the most common matchers:


  • toBe — compares for strict equality (e.g. ===)

    toBe —比较严格相等(例如===)
  • toEqual — compares the values of two variables/objects

    toEqual —比较两个变量/对象的值
  • toBeNull — checks if the value is null

    toBeNull —检查值是否为null
  • toBeDefined — checks if the value is defined

  • toBeUndefined — checks if the value is undefined

    toBeUndefined —检查值是否未定义
  • toBeTruthy — checks if the value is true (similar to an if statement)

  • toBeFalsy — checks if the value is false(similar to an if statement)

    toBeFalsy —检查值是否为false(类似于if语句)
  • toBeGreaterThan — checks if the result of the expect() function is greater than the argument

    toBeGreaterThan —检查Expect()函数的结果是否大于参数
  • toContain — checks if the result of expect() contains a value

    toContain —检查Expect()的结果是否包含值
  • toHaveProperty — checks if an object has a property, and optionally checks its value

    toHaveProperty —检查对象是否具有属性,并可选地检查其值
  • toBeInstanceOf — checks if an object is an instance of a class

    toBeInstanceOf —检查对象是否是类的实例

These matchers can also be negated using the not statement:


test("factorial of 3 is not 5", () => {     expect(factorialize(3)).not.toBe(5); 

You can also use additional matchers that are maintained by the Jest community.


设置和拆卸 (Setup and Teardown)

Often when writing tests, you will have to do some kind of setup like initializing variables before tests run and some sort of action after they have finished.


Jest provides two different ways you can do that.


一次性设置: (One-Time Setup:)

In some cases, you only need to do the setup once, at the beginning of your test file. In that scenario, you can use the beforeAll() and afterAll() helper functions that will execute before the tests start and after all have finished.

在某些情况下,您只需在测试文件的开头执行一次设置即可。 在那种情况下,您可以使用beforeAll()afterAll()帮助程序函数,这些函数将在测试开始之前和完成之后执行。

beforeAll(() => {
  return initializeDatabase();

afterAll(() => {
  return clearDatabase();

test('query from database', () => {

为每个测试重复设置:(Repeating setup for each test:)

If you have a setup process that needs to run before each test than you should use the beforeEach() and afterEach() functions.


beforeEach(() => {

afterEach(() => {

test('query from database', () => {

Note: There will be scenarios where you will use both of these setup processes together to get the best results.


分组测试 (Grouping tests)

You can also group related tests together so you can isolate the setup and teardown functions. Grouping tests will also help you get a better overview of your different test cases.

您还可以将相关测试分组在一起,以便可以隔离设置和拆卸功能。 将测试分组还可以帮助您更好地了解不同的测试用例。

describe('testing factorial function', () => {
    beforeAll(() => {
    	//do something
    afterAll(() => {
    	//do something
    test("factorial of 3", () => {

    test("factorial of 5", () => {

    test("factorial of 3 is not 5", () => {

测试异步功能(Testing async functions)

It is common for Javascript code to run asynchronously using either promises or callbacks. The problem with testing asynchronous code is knowing when the code that you are testing is actually complete. Jest has several ways to handle this.

Java代码通常使用promise或callbacks异步运行。 测试异步代码的问题是知道您要测试的代码何时真正完成。 笑话有几种处理方法。

承诺: (Promises:)

Testing promises is straight forward in Jest. Just return the promise and Jest will wait for the promise to resolve. If the promise fails, the test will automatically fail as well.

在Jest中测试诺言很简单。 只需返回承诺,Jest将等待承诺解决。 如果承诺失败,则测试也会自动失败。

// string.js
const reverseString = str => {
  return new Promise((resolve, reject) => {
    if (!str) {
      reject("Empty string");
module.exports = reverseString;

// string.spec.js
const reverseString = require("./string");

test(`reverseString 'String' to equal 'gnirtS'`, () => {
  return reverseString("String").then(str => {

You can also catch rejected promises using the catch() function.


test(`reverseString '' to reject promise`, () => {
  return reverseString("String").catch(error => {
    expect(e).toMatch("Empty string");

异步等待:(Async await:)

Alternatively, we can use async and await for testing promises.


const reverseString = require("./string");

test(`reverseString 'String' to equal 'gnirtS' using await`, async () => {
    const str = await reverseString("String")

Note: You need to make your testing function async to use async and await.


回调: (Callbacks:)

By default Jest tests complete once they reach the end of their execution which means that the test will be completed before the callback is called. This can be fixed by passing a single argument named done to your test function. Jest will wait until the done callback is called before finishing the test.

默认情况下,Jest测试在执行结束时会完成,这意味着测试将在调用回调之前完成。 可以通过将一个名为done的参数传递给测试函数来解决此问题。 Jest将等待直到完成的回调被调用,然后再完成测试。

// string.js
function reverseStringCallback(str, callback) {

module.exports = {reverseStringCallback};

// string.spec.js
const {reverseStringCallback} = require("./string");

test(`reverseStringCallback 'string' to equal 'gnirts'`, (done) => {
    reverseStringCallback('string', (str) => {

If done() is never called, the test will fail with a timeout error.

如果从不调用done() ,则测试将失败,并显示超时错误。

模拟 (Mocking)

Mocking is creating objects or services that simulate the behavior of real objects and plays a vital part in testing. The goal for mocking an object or function is to replace something we don’t control like an external service with something we do, that is why it’s essential that what we replace it with something that has all the features we need.

模拟正在创建对象或服务,以模拟真实对象的行为,并在测试中发挥至关重要的作用。 模拟对象或函数的目的是用我们所做的事情来替换我们无法控制的东西,例如外部服务,这就是为什么我们必须用具有我们所需的所有功能的东西来替换它的原因。

Using mocks also helps you to inspect information about your code e.g. if a function has already be called and which parameters were used.


将Mocks传递给函数: (Passing Mocks to functions:)

One of the common ways to use the Mock function is by passing it as an argument to the function you are testing. This allows you to run your tests without importing the real dependencies and objects you would pass in your real application.

使用Mock函数的常见方法之一是将其作为参数传递给要测试的函数。 这使您可以运行测试,而无需导入将在实际应用程序中传递的实际依赖关系和对象。

const multiplyNumbers = (a, b, callback) => {
  callback(a * b);

test("calls callback with arguments added", () => {
  const mockCallback = jest.fn();
  multiplyNumbers(1, 2, mockCallback);

This strategy is great but requires that your code supports dependency injection. If that is not the case you will need to mock already existing modules or functions instead.

这个策略很棒,但是需要您的代码支持依赖注入。 如果不是这种情况,则需要模拟已经存在的模块或函数。

模拟单个功能: (Mocking a single function:)

You can mock a single function using Jest.fn():


const lodash = require('lodash')

lodash.chunk = jest.fn(() => 'test')
test(`Test lodash chunk function`, () => {
    const result = lodash.chunk(['a', 'b', 'c', 'd'], 2)
    expect(lodash.chunk).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], 2)

Here I create a mock of the lodash.chunk function and test if it gets called and if the parameters are right.


模拟模块: (Mocking Modules:)

Mocking single functions works well if you only use one or two functions of a package or library but can get very cluttered when you need more functions of a module. Here we use jest.mock to automatically set the exports of an entire module instead of mocking the modules manually.

如果仅使用一个程序包或库的一个或两个功能,则模拟单个功能会很好地工作,但是当您需要一个模块的更多功能时,模拟会很混乱。 在这里,我们使用jest.mock来自动设置整个模块的导出,而不是手动模拟模块。


test(`Test lodash chunk function`, () => {
    const result = lodash.chunk(['a', 'b', 'c', 'd'], 2)
    expect(lodash.chunk).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], 2)

    const concatResult = lodash.concat(2, [3], [[4]]);
    expect(lodash.concat).toHaveBeenCalledWith(2, [3], [[4]])

As you can see I can now call all function of the lodash library as mock objects.


The only disadvantage of this strategy is that it is difficult to access the original implementation of the module. For those use cases, you can use the spyOn function instead.

该策略的唯一缺点是很难访问该模块的原始实现。 对于这些用例,可以改用spyOn函数。

间谍包: (Spying packages:)

You can also spy on a package without creating a mock for it. This is done using the spyOn() function provided by Jest.

您也可以监视软件包而无需为其创建模拟。 这是通过Jest提供的spyOn()函数完成的。

const lodash = require('lodash')

test(`Test lodash chunk function`, () => {
  const spy = jest.spyOn(lodash, 'chunk')
  const result = lodash.chunk(['a', 'b', 'c', 'd'], 2)

  expect(lodash.chunk).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], 2)

您应该注意的重要事项(Important things you should look at)

There are a few more concepts you should definitely look at on your way to mastering testing in JavaScript. But I would greatly recommend learning the basics first and putting them into practice in your applications.

在掌握JavaScript测试方法的过程中,您肯定还应该考虑一些其他概念。 但是,我强烈建议您先学习基础知识,然后在您的应用程序中将其付诸实践。

  • Snapshot testing — Is used for testing the UI of your application


  • CI (Continous Integration) — The practice of automating the integration of code changes from multiple contributors into a single software project

  • CD (Continous Deployment) — Is a software release process that uses automated testing to validate if changes to a codebase are correct

  • Automated dependency updates


It is vital to practice testing in your own applications. If you do it long enough, then you will master the art of testing and make your applications more stable and secure in the process.

在您自己的应用程序中进行测试至关重要。 如果您做的时间足够长,那么您将掌握测试的技巧,并使您的应用程序在过程中更加稳定和安全。

资料来源: (Sources:)

Here is a list of the sources I used for this article:



You made it all the way until the end! I hope that this article helped you understand the basics of automated testing in JavaScript.

一路走到最后! 我希望本文能帮助您了解JavaScript自动测试的基础

If you have found this useful, please consider recommending and sharing it with other fellow developers. If you have any questions or feedback, let me know using my contact form or contact me on Twitter.

如果您发现此功能有用,请考虑推荐并与其他开发人员共享。 如果您有任何疑问或反馈,请使用我的联系表或通过Twitter与我联系。

Originally published at






  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
钱包余额 0