准备就绪函数_如何测试您的微服务以确保它们已准备就绪

准备就绪函数

Microservices architecture describes the practice of breaking up an application into a series of smaller and more problem-solution oriented components. Then each of these components communicates with one another across common protocols like HTTP or the more lightweight TCP.

微服务体系结构描述了将应用程序分解为一系列较小的,面向问题解决的组件的实践。 然后,这些组件中的每个组件都会通过常见协议(例如HTTP或更轻量的TCP)相互通信。

您可能想知道-测试对我来说重要吗? (You might be wondering - are tests important for me?)

Long story short - YES.Software testing is important for a number of reasons, but most importantly:

长话短说-是的。 出于多种原因,软件测试很重要,但最重要的是:

  • It saves money and a lot of time

    既省钱又省时间
  • Security

    安全
  • Product quality (fewer bugs and errors)

    产品质量(更少的错误和错误)
  • Customer satisfaction

    顾客满意度
  • It lets you sleep peacefully at night

    它可以让您在晚上安然入睡

No one likes an application that has bugs and stops working for no reason. And there is no need to talk about the hazards of poor security, which allows hackers to steal credentials and even money.As long as you develop an application that will be used by users and has some complexity, tests should not be an option – they should be mandatory.

没有人喜欢一个有错误且无缘无故地停止工作的应用程序。 而且,无需讨论安全性差的危害,它会使黑客窃取凭据甚至金钱。只要您开发了供用户使用且具有一定复杂性的应用程序,就不应选择测试–应该是强制性的。

我应该写什么测试? (What test should I write?)

There are various types of software testing.Functional Testing types include:

有各种类型的软件测试。 功能测试类型包括:

  • Unit Testing

    单元测试
  • Integration Testing

    整合测试
  • Smoke Testing

    烟雾测试
  • Regression Testing

    回归测试
  • Sanity Testing

    健全性测试
  • Beta/Acceptance Testing

    Beta /验收测试
  • End to End (e2e) Testing

    端到端(e2e)测试

Non-functional Testing types include:

非功能测试类型包括:

  • Performance Testing

    性能测试
  • Load Testing

    负载测试
  • Stress Testing

    压力测试
  • Security Testing

    安全测试
  • Compliance Testing

    符合性测试
  • Usability Testing

    可用性测试

The more complex the app gets the more types of tests you will use.

应用程序越复杂,您将使用的测试类型越多。

The basic tests that you should always use are the following:

您应该始终使用的基本测试如下:

  • Unit Testing

    单元测试
  • Integration Testing

    整合测试
  • E2E Testing combined with Regression testing and Security Testing

    端到端测试与回归测试和安全测试相结合

The process goes like this: first you write tests to check if your app behaves as expected in almost all aspects, including corner cases. Second, if your app is already live, you write tests to check if any new changes to the code break the current functionality.Side note: besides these basic tests that you should use at any type of software, there are additional tests you should write for microservices. Don't forget load tests, for example, to check your system's behavior under both normal and anticipated peak load conditions.

流程如下:首先编写测试以检查您的应用在几乎所有方面(包括极端情况)的行为是否均符合预期。 其次,如果您的应用程序已经上线,则编写测试以检查对代码的任何新更改是否破坏了当前功能。 旁注:除了您应该在任何类型的软件上使用的这些基本测试之外,还应该为微服务编写其他测试。 例如,不要忘记进行负载测试,以检查系统在正常和预期峰值负载条件下的行为。

少说话,多代码 (Less talk, more code)

In the following examples, we will see how we can implement those basic types of software testing from above in a microservice. The microservice uses the TCP protocol for communication and is written in Node.js using the Nest Framework.If NestJS sounds new to you, don't worry – all you need to know is the following:

在以下示例中,我们将看到如何在微服务中从上面实现那些基本类型的软件测试。 微服务使用TCP协议进行通信,并使用Nest Framework在Node.js中编写。如果NestJS对您来说听起来很陌生,请不用担心–您需要了解的是以下几点:

"Nest is a framework for building efficient, scalable Node.js server-side applications.

Nest是用于构建高效,可扩展的Node.js服务器端应用程序的框架。

"Nest is a framework for building efficient, scalable Node.js server-side applications.

Nest是用于构建高效,可扩展的Node.js服务器端应用程序的框架。

It uses modern JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

它使用现代JavaScript,并使用TypeScript构建(保留与纯JavaScript的兼容性),并结合了OOP(面向对象编程),FP(功能编程)和FRP(功能React编程)的元素。

It uses modern JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

它使用现代JavaScript,并使用TypeScript构建(保留与纯JavaScript的兼容性),并结合了OOP(面向对象编程),FP(功能编程)和FRP(功能React编程)的元素。

Under the hood, Nest makes use of Express, but also, provides compatibility with a wide range of other libraries, like e.g.

在底层,Nest使用Express ,但还提供与许多其他库的兼容性,例如

Under the hood, Nest makes use of Express, but also, provides compatibility with a wide range of other libraries, like e.g.

在底层,Nest使用Express ,但还提供与许多其他库的兼容性,例如

Under the hood, Nest makes use of Express, but also, provides compatibility with a wide range of other libraries, like e.g. Fastify, allowing for easy use of the myriad third-party plugins which are available." – Official Github repo description

底层 ,Nest使用Express ,但还与广泛的其他库(例如Fastify)兼容 ,从而允许轻松使用众多可用的第三方插件。” – Github官方仓库说明

For this example we will use a simple module, name: user, with a simple function createUser, that will create a new user in our database.The folder structure for the module looks like this:

在此示例中,我们将使用一个简单的模块,名称为: user 使用一个简单的函数createUser ,它将在我们的数据库中创建一个新用户。模块的文件夹结构如下所示:

We have a controller that listens for a message create_user. After it does the validation with the ValidationPipe it will call a function with the same name inside its service.

我们有一个监听消息create_user的控制器。 用ValidationPipe进行验证后,它将在其服务内调用一个具有相同名称的函数。

Inside the service, we hash the user password. Then using TypeORM we save a new user inside our database.

在服务内部,我们对用户密码进行哈希处理。 然后使用TypeORM将新用户保存在数据库中。

For this module we use TypeORM as the ORM linked to the table User, and another module named UtilsModule in which we have some helper function:

对于此模块,我们将TypeORM用作链接到表User的ORM,并使用另一个名为UtilsModule的模块,在其中我们具有一些辅助功能:

单元测试 (Unit testing)

A unit is the smallest testable part of an application like functions, classes or procedures. Unit Testing is a software testing method by which individual units of source code are tested to determine whether they are good for us.

一个单位 是应用程序(例如函数,类或过程)中可测试的最小部分。 单元测试是一种软件测试方法,通过该方法可以测试源代码的各个单元以确定它们是否对我们有利。

Basically, unit tests are written to make sure that each simple implementation of different code forms (functions, classes, and so on) meets their design and requirements and behaves as expected.The goal of unit testing is to segregate each part of the program and test that the individual parts are working correctly. This means that the other parts of the code that are not directly from the testing unit (but are linked with it) will be mocked.In our case, the function we want to test (createUser) is our unit we want to test. This means that we have to isolate it from the other components. So we have to mock our user repository class which represents the link with the database using TypeORM.If we analyze the function (the one in the service), we see that all it does is hash a password and then to save a User object inside our database. Given this fact we write the following test suite:

基本上,编写单元测试是为了确保不同代码形式(函数,类等)的每个简单实现均符合其设计和要求,并能按预期方式运行。 单元测试的目的是将程序的每个部分与测试各个零件是否正常工作。 这意味着将模拟不是直接来自测试单元的其他部分(但与其链接),在我们的例子中,我们要测试的函数( createUser )是我们要测试的单元。 这意味着我们必须将其与其他组件隔离。 因此我们必须使用TypeORM来模拟表示与数据库链接的用户存储库类。如果我们分析函数(服务中的那个),我们看到它所做的只是散列密码,然后将User对象保存在其中我们的数据库。 鉴于这一事实,我们编写了以下测试套件:

First, we write a beforeAll function which creates our testing module. Then we replace the original repository with our mock class, which will only return the object we want to save in the database.

首先,我们编写一个beforeAll函数来创建我们的测试模块。 然后,我们用模拟类替换原始存储库,该模拟类将仅返回我们要保存在数据库中的对象。

In our function we had one requirement with one corner case:

在我们的函数中,我们对一个极端情况有一个要求:

  • create a new user object with some given properties (email, password), but with a hashed password

    使用某些给定的属性(电子邮件,密码)创建新的用户对象,但使用哈希密码

We mocked the function save(), since it’s from TypeORM, outside of our unit, and we overrode it with a simple function that returns the object we passed. So all we had to do was to check if we were sending the object with the right email property and with the correct hash.

我们嘲笑了函数save(),因为它来自TypeORM,在我们的单元之外,我们用一个简单的函数覆盖了它,该函数返回我们传递的对象。 因此,我们要做的就是检查我们是否通过正确的电子邮件属性和正确的哈希值发送对象。

整合测试 (Integration testing)

Integration Testing is a software testing method by which units of source code are tested to verify the combined functionality. Unit tests are basically written to make sure that code meets its design and requirements and behaves as expected. The goal of unit testing is to blend together different modules and test if they interact properly.So now, for our example, we combine our UserModule with the TypeORM module (dependency) to check if the user is saved in the database.Again we have the same function from above, but this time with the following test:

集成 测试是一种软件测试方法,通过该方法可以测试源代码单元以验证组合功能。 编写单元测试基本上是为了确保代码符合其设计和要求,并能按预期运行。 单元测试的目的是将不同的模块混合在一起并测试它们是否正确交互,因此,在我们的示例中,我们将UserModule与TypeORM模块(依赖项)结合起来,以检查用户是否保存在数据库中。与上面的功能相同,但是这次进行了以下测试:

This time, in our beforeAll function we don’t mock the userRepository. Instead we use the original one, plus we add our databaseModule which creates the connection to our database.At the same time, because we use a real database now, we have to write several functions that will prepare our database for tests. We need to empty the database before and after our tests, just to be sure that it is completely empty. In the same time we have to manually close the connection to it, so that we do not remain with any open handlers after we finish the tests.With Unit Testing, we checked to see if our function was working as designed. So here all we have to do is to test if our function blends with the save() method from TypeORM and our user is stored inside the database.We write a helper function name getOneUserFromDb, which does what it says it does. Then we check if the email is correct as well as the property accountConfimed, which was set in entity class with the default value false.

这次,在我们的beforeAll函数中,我们没有模拟userRepository 。 取而代之的是,我们使用原始数据库 ,然后添加我们的databaseModule创建与数据库的连接。同时,由于我们现在使用的是真实数据库,因此我们必须编写一些函数来为测试做准备。 在测试之前和之后,我们需要清空数据库,只是为了确保它完全清空。 同时,我们必须手动关闭与之的连接,以免在完成测试后不留下任何打开的处理程序。使用单元测试,我们检查了函数是否按设计工作。 因此,这里我们要做的就是测试我们的函数是否与TypeORM的save()方法混合并且我们的用户是否存储在数据库中。我们编写了一个辅助函数名称getOneUserFromDb,该函数可以执行其声明的操作。 然后,我们检查电子邮件是否正确以及属性accountConfimed (在实体类中设置为默认值false)是否正确

端到端测试 (End-to-End Testing)

End-to-End Testing is a software testing technique used to test whether the flow of an application is performing as designed from start to finish. We do this type of testing to ensure that the application will work as expected in a real-world situation.Up to this point we've tested whether the user password was hashed accordingly and if the password and email were saved inside the database. Now we need to test our validations at the request level. In our controller, we have a validation pipe which tests the incoming payload to check if the object matches with CreateUserDto .

端到端测试是一种软件测试技术,用于从头到尾测试应用程序的流程是否按设计进行。 我们进行这种类型的测试,以确保应用程序能够在实际情况下正常运行。到目前为止,我们已经测试了用户密码是否被相应地哈希化,以及密码和电子邮件是否保存在数据库中。 现在,我们需要在请求级别测试我们的验证。 在我们的控制器中,我们有一个验证管道,用于测试传入的有效负载,以检查对象是否与CreateUserDto匹配

And the tests:

和测试:

Here we tested to see what would happen if we tried to create a user but didn't send the entire object or sent properties in an incorrect format.These are some examples of the corner cases from our function that we tested using just 3 types of software testing.

在这里我们进行了测试,以查看尝试创建用户但未以错误的格式发送整个对象或发送属性会发生什么情况,这些是我们仅使用3种类型的函数进行测试的一些极端案例的示例。软件测试。

手动测试与自动测试 (Manual vs Automated Tests)

So far, we've written our tests manually – and for this case that was just perfect. But the more code you have, the more complex and larger your test suits will become.For example, if you are going to test an authentication system, you will have to replicate the entire behavior of a real user. And you will have to mock the requests and responses, including cookies and many more things, just to build the environment for your tests. A long test suite can take a lot of time to run.Luckily you have one more option when it comes to testing: automated tools. These tools have built-in functionalities for you to mock the entire environment for your tests, which makes the test process way easier. You can go even further and use automated API testing tools for your application. These are tools that come with extra options which makes them great for load testing, regression testing, and data reports for real situations. Plus they have a good UI that makes it way easier to write tests.

到目前为止,我们已经手动编写了测试-对于这种情况,这是完美的。 但是您拥有的代码越多,您的测试服就会变得越复杂和越大,例如,如果您要测试身份验证系统,则必须复制真实用户的整个行为。 而且,您将不得不模拟请求和响应,包括cookie和更多其他内容,仅用于构建测试环境。 较长的测试套件可能需要花费大量时间才能运行。幸运的是,在测试方面,您还有其他选择:自动化工具。 这些工具具有内置功能,可让您模拟整个测试环境,从而使测试过程更容易。 您甚至可以走得更远,并为您的应用程序使用自动化的API测试工具 。 这些工具带有附加选项,非常适合负载测试,回归测试和实际情况的数据报告。 另外,它们具有良好的UI,可以更轻松地编写测试。

结论 (Conclusion)

Building software that's ready for production requires tests. And sometimes, depending on the complexity of the app, those tests can become a bottleneck for you or your team. In this case, be sure to separate your test suites by their type, just like we did earlier. And only to test the functionality that belongs to the current test type. If this is not enough for your use case, or tests are too hard to write and take too much time, then you can use automated tools and platforms to make things easier.

构建准备投入生产的软件需要进行测试。 有时,根据应用程序的复杂性,这些测试可能成为您或您的团队的瓶颈。 在这种情况下,请确保按照测试套件的类型分开测试套件,就像我们之前所做的那样。 并且仅用于测试属于当前测试类型的功能。 如果这还不足以满足您的用例,或者测试太难编写且花费太多时间,则可以使用自动化工具和平台使事情变得更容易。

翻译自: https://www.freecodecamp.org/news/testing-microservices-are-they-production-ready-2/

准备就绪函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值