博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
没有发现测试空测试套件_最低可行测试套件
阅读量:2518 次
发布时间:2019-05-11

本文共 13430 字,大约阅读时间需要 44 分钟。

没有发现测试空测试套件

minimum viable testing

In the last we detailed how to validate email addresses during user registration.

在上我们详细介绍了如何在用户注册期间验证电子邮件地址。

This time, we’ll add unit and integration tests (yay!) to our application using the extension, covering the most important features. This type of testing is called Minimum Viable Testing (or ) and is designed to test the high-risk functionality, centered around the application’s features.

这次,我们将使用扩展将单元测试和集成测试(是!)添加到我们的应用程序中,其中涵盖了最重要的功能。 这种类型的测试称为最小可行测试(或 ),旨在测试围绕应用程序功能的高风险功能。

Did you miss the first post? Grab the code from the to quickly get started.

您错过了第一篇文章吗? 从中获取代码以快速上手。

单元和集成测试-已定义 (Unit and Integration Tests – defined)

For those new to testing, it’s vital to test your applications since “untested applications make it hard to improve existing code and developers of untested applications tend to become pretty paranoid. If an application has automated tests, you can safely make changes and instantly know if anything breaks” ().

对于那些刚开始测试的人来说,测试您的应用程序至关重要,因为“未经测试的应用程序很难改进现有代码,而未经测试的应用程序的开发人员往往会变得偏执。 如果应用程序具有自动化测试,则可以安全地进行更改,并立即知道是否有任何中断”( )。

Unit tests, by nature, test isolated units of code – i.e., individual functions – to ensure that the actual output is the same as the expected output. In many cases, since you often have to make external API calls or touch a database, unit tests can rely heavily on mocking fake data. By simulating the tests, they may run faster, but they can also be less effective and are harder to maintain. Because of this, we will not be using mocks unless we absolutely have to; instead we will read and write to the database as needed.

本质上,单元测试将测试隔离的代码单元(即单个功能),以确保实际输出与预期输出相同。 在许多情况下,由于您通常必须进行外部API调用或触摸数据库,因此单元测试可能严重依赖于模拟假数据。 通过模拟测试,它们可能会运行得更快,但它们的效率也较低,并且难以维护。 因此,除非绝对必要,否则我们不会使用模拟程序。 相反,我们将根据需要读取和写入数据库。

Keep in mind that when a database is touched in a specific test, it is technically an integration test since the test itself is not isolated to a specific unit. Also, if you run your tests through the Flask app, using the test helper test , they are considered integration tests as well.

请记住,在特定测试中触摸数据库时,从技术上讲,它是集成测试,因为测试本身并未隔离到特定单元。 另外,如果您通过Flask应用程序使用测试助手测试运行测试,则它们也被视为集成测试。

入门 (Getting Started)

It’s often difficult to determine how to start testing an application. One solution to this problem is to think about your app in terms of end user functionality:

通常很难确定如何开始测试应用程序。 解决此问题的一种方法是从最终用户功能的角度考虑您的应用程序:

  1. Unregistered users must sign up before accessing the app.
  2. After users register, a confirmation email is sent – and they are considered “unconfirmed” users.
  3. Unconfirmed users can log in but they are immediately redirected to a page reminding them to confirm their account via email before they can access the app.
  4. Once confirmed, users have full access to the site, where they can view the main page, update their password on the profile page, and logout.
  1. 未注册的用户必须注册才能访问该应用。
  2. 用户注册后,将发送确认电子邮件-他们被视为“未确认”用户。
  3. 未经确认的用户可以登录,但他们会立即重定向到页面,提醒他们通过电子邮件确认其帐户,然后才能访问该应用程序。
  4. 一旦确认,用户就可以完全访问该站点,他们可以在其中查看主页,在配置文件页面上更新密码并注销。

Like stated in the beginning, we’ll write just enough tests to cover this main functionality. Testing is hard; we are hyper aware of that, so if you’re only keen on writing a few tests, test what matters the most. This, coupled with coverage testing via , which we’ll detail in the next article in this series, will make it much easier to structure a robust test suite.

如开头所述,我们将只编写足够的测试来涵盖此主要功能。 测试很难; 我们对此非常了解,因此,如果您只想编写一些测试,请测试最重要的部分。 这以及通过进行的覆盖率测试(我们将在本系列的下一篇文章中详细介绍)将使构建健壮的测试套件变得更加容易。

建立 (Setup)

Activate your virtualenv, then make sure the following environment variables are set:

激活您的virtualenv,然后确保设置了以下环境变量:

112233

Then run the current test suite:

然后运行当前的测试套件:

112233445566778899

These tests simply test the configuration and environment variables. They should be fairly straightforward.

这些测试仅测试配置和环境变量。 它们应该相当简单。

To expand the suite, we need to start with an organized structure to keep everything nice and neat. Since the app is already structured around blueprints, let’s do the same for the test suite. So create two new test files in the “tests” directory – test_main.py and test_user.py – and add the following code to each:

为了扩展套件,我们需要从一个有组织的结构开始,以保​​持所有内容的美观和整洁。 由于该应用程序已经围绕蓝图构建,因此我们对测试套件进行相同的操作。 因此,在“ tests”目录中创建两个新的测试文件– test_main.py和test_user.py –并向每个文件添加以下代码:

112233445566778899101011111212

NOTE: You could also structure your tests around test type – unit, integration, functional, etc..

注意 :您还可以围绕测试类型(单元,集成,功能等)构建测试。

第一部分–主要蓝图 (Part 1 – Main Blueprint)

Looking at the code in the views.py file (in the “project/main” folder), along with the end user workflow, we can see that we just need to test that the main route, /, requires the user to be logged in. So add the following code to test_main.py:

查看views.py文件(位于“ project / main”文件夹中)中的代码以及最终用户工作流程,我们可以看到我们只需要测试主路由/ ,要求登录用户即可。 in。因此将以下代码添加到test_main.py中:

1122334455

Here, we’re asserting that the response status code is 200 and that the correct template is used. Run the test suite. All 4 tests should pass.

在这里,我们断言响应状态代码为200并且使用了正确的模板。 运行测试套件。 所有4个测试都应通过。

第2部分–用户蓝图 (Part 2 – User Blueprint)

There’s quite a bit more going on in this blueprint, so the testing required is far more intensive. Essentially, we need to test the views and – so, we’ll break apart our test suite accordingly. Don’t worry I will guide you through it. Let’s create the 2 classes to ensure our tests are logically divided.

此蓝图还有很多工作要做,因此需要进行的测试更加密集。 本质上,我们需要测试视图,并且-因此,我们将相应地分解测试套件。 不用担心,我会指导您完成整个过程。 让我们创建2个类以确保逻辑上划分测试。

Add the following code to test_user.py so we can start testing the many functions required.

将以下代码添加到test_user.py,以便我们可以开始测试所需的许多功能。

112233445566

形式 (Forms)

Having a user register is a core concept in a log in based program, without it we have an “open door” to trouble. This must work as designed. So, following the user workflow, let’s start with the registration form. Add this code to the TestUserForms() class.

在基于登录的程序中,拥有用户注册是一个核心概念,没有它,我们就有麻烦的“敞开大门”。 这必须按设计工作。 因此,按照用户工作流程,让我们从注册表单开始。 将此代码添加到TestUserForms()类。

1122334455667788991010111112121313141415151616171718181919202021212222

In these tests, we’re ensuring that the form either passes or fails validation based on the data entered. Compare this to the forms.py file in the “project/user” folder. In the last test, we’re simply registering the same user from the setUpClass() method from our BaseTestCase in the util.py file.

在这些测试中,我们确保表单根据输入的数据通过或未通过验证。 将此与“项目/用户”文件夹中的forms.py文件进行比较。 在过去的测试中,我们只是注册在相同的用户setUpClass()从我们的方法BaseTestCase在util.py文件。

While we’re testing the forms, let’s go ahead and test the login form as well:

在测试表单时,让我们继续测试登录表单

112233445566778899

Finally, let’s test the change password form:

最后,让我们测试一下更改密码表单:

11223344556677889910101111121213131414

Make sure to add the required imports:

确保添加所需的导入:

1122

And then run the tests!

然后运行测试!

1122334455667788991010111112121313141415151616

For the form tests, we basically just instantiated the form and called the validate function which will trigger all validation, including our custom validation and return a boolean indicating if the form data is indeed valid or not.

对于表单测试,我们基本上只是实例化表单并调用validate函数,该函数将触发所有验证,包括我们的自定义验证,并返回一个布尔值,该布尔值指示表单数据是否确实有效。

With our forms tested, let’s move on to the Views…

在测试完我们的表单之后,让我们继续查看...

观看次数 (Views)

Logging in and viewing the profile are critical parts of security so we want to make certain this is thoroughly tested.

登录和查看配置文件是安全性的关键部分,因此我们要确保已对其进行了全面测试。

login

login

112233445566778899101011111212131314141515161617171818191920202121222223232424252526262727

profile

profile

11223344

Add the required imports as well:

还要添加所需的导入:

1122

register and resend_confirmation

registerresend_confirmation

Before writing tests to cover the register and resend_confirmation views, take a look at the . Notice how we’re utilizing the send_email() function from the email.py file, which sends the confirmation email. Do we really want to send this email or should we fake it using a mocking library? Even if we do send it, it’s very difficult to assert that an actual email shows up in a dummy inbox without utilizing Selenium to pull up the actual inbox in the browser. So, let’s mock the sending of the email, which we’ll handle in a subsequent article.

在编写覆盖registerresend_confirmation视图的测试之前,请看一下 。 请注意,我们如何利用email.py文件中的send_email()函数发送确认电子邮件。 我们是否真的要发送此电子邮件,还是应该使用模拟库对其进行伪造? 即使我们确实发送了它,也很难断言在没有利用Selenium在浏览器中提取实际收件箱的情况下,实际的电子邮件会显示在虚拟收件箱中。 因此,让我们模拟电子邮件的发送,我们将在后续文章中进行处理。

confirm/<token>

confirm/<token>

11223344

Like the last two views, the remaining parts of this view could be mocked since a confirmation token needs to be generated. However, we can just generate a token using the utility function from the token.py file, generate_confirmation_token():

与最后两个视图一样,由于需要生成确认令牌,因此可以模拟该视图的其余部分。 但是,我们可以使用token.py文件generate_confirmation_token()的实用程序函数来生成令牌:

11223344556677889910101111121213131414151516161717181819192020212122222323242425252626

Add the imports:

添加导入:

1122

And then run the tests. One should fail:

然后运行测试。 一个应该失败:

112233

This test failed – test_confirm_token_route_invalid_token(). Why? Because there’s an error in the view:

该测试失败– test_confirm_token_route_invalid_token() 。 为什么? 因为视图中有错误:

11223344556677889910101111121213131414151516161717

What’s wrong?

怎么了?

Right now the flash call – e.g., flash('The confirmation link is invalid or has expired.', 'danger') – does not cause the function to exit, so it will fall through to the if/else and confirm the user even if the token is invalid. This is why you write tests.

现在, flash调用-例如flash('The confirmation link is invalid or has expired.', 'danger') –不会导致该函数退出,因此它将进入if / else并确认用户,甚至如果令牌无效。 这就是您编写测试的原因。

Let’s rewrite the function:

让我们重写函数:

11223344556677889910101111121213131414151516161717

Run the tests again. All 18 should pass.

再次运行测试。 所有18个都应该通过。

What happens if a token expires? Write a test.

如果令牌过期怎么办? 编写测试。

11223344556677

Run the tests again:

再次运行测试:

1122334455667788991010111112121313141415151616171718181919202021212222232324242525

反射 (Reflection)

This is probably a good time to stop and reflect, especially since we are focusing on minimal testing. Remember our core features?

这可能是停止和反思的好时机,尤其是因为我们关注的是最小化测试。 还记得我们的核心功能吗?

  1. Unregistered users must sign up before accessing the app.
  2. After users register, a confirmation email is sent – and they are considered “unconfirmed” users.
  3. Unconfirmed users can log in but they are immediately redirected to a page reminding them to confirm their account via email before they can access the app.
  4. Once confirmed, users have full access to the site, where they can view the main page, update their password on the profile page, and logout.
  1. 未注册的用户必须注册才能访问该应用。
  2. 用户注册后,将发送确认电子邮件-他们被视为“未确认”用户。
  3. 未经确认的用户可以登录,但他们会立即重定向到页面,提醒他们通过电子邮件确认其帐户,然后才能访问该应用程序。
  4. 一旦确认,用户就可以完全访问该站点,他们可以在其中查看主页,在配置文件页面上更新密码并注销。

Are we covering each of these? Let’s look:

我们涵盖所有这些吗? 我们看看吧:

Unregistered users must sign up before accessing the app

未注册的用户必须注册才能访问该应用

  • test_main_route_requires_login
  • test_validate_email_already_registered
  • test_validate_invalid_email_format
  • test_validate_invalid_password_format
  • test_validate_success_register_form
  • test_main_route_requires_login
  • test_validate_email_already_registered
  • test_validate_invalid_email_format
  • test_validate_invalid_password_format
  • test_validate_success_register_form

After users register, a confirmation email is sent – and they are considered “unconfirmed” users. and Unconfirmed users can log in but they are immediately redirected to a page reminding them to confirm their account via email before they can access the app.

用户注册后,将发送确认电子邮件-他们被视为“未确认”用户。未确认的用户可以登录,但是他们会立即重定向到页面,提醒他们通过电子邮件确认其帐户,然后才能访问该应用。

  • test_validate_success_login_form
  • test_confirm_token_route_expired_token
  • test_confirm_token_route_invalid_token
  • test_confirm_token_route_requires_login
  • test_confirm_token_route_valid_token
  • test_correct_login
  • test_incorrect_login
  • test_profile_route_requires_login
  • test_validate_success_login_form
  • test_confirm_token_route_expired_token
  • test_confirm_token_route_invalid_token
  • test_confirm_token_route_requires_login
  • test_confirm_token_route_valid_token
  • test_correct_login
  • test_incorrect_login
  • test_profile_route_requires_login

Once confirmed, users have full access to the site, where they can view the main page, update their password on the profile page, and logout.

一旦确认,用户就可以完全访问该站点,他们可以在其中查看主页,在配置文件页面上更新密码并注销。

  • test_validate_invalid_change_password
  • test_validate_invalid_change_password_format
  • test_validate_success_change_password_form
  • test_validate_invalid_change_password
  • test_validate_invalid_change_password_format
  • test_validate_success_change_password_form

In the above tests we tested the forms directly, and then also created tests for the views (which exercise much of the same code as in the form tests). What are the tradeoffs of this type of approach? We’ll address this when we tie in coverage testing.

在上面的测试中,我们直接测试了表单,然后还为视图创建了测试(这些视图使用的代码与表单测试中的代码相同)。 这种方法的权衡是什么? 当我们进行覆盖测试时,我们将解决此问题。

下次 (Next Time)

That’s it for this post. In the next few posts we’ll-

就是这个帖子。 在接下来的几篇文章中,我们将-

  1. Mock all or parts of the following functions from the user blueprint to finalize unit/integration testing – register() and resend_confirmation()
  2. Add coverage testing via to help ensure that our code base is adequately being tested.
  3. Expand the test suite by adding functional tests with Selenium.
  1. user蓝图模拟以下功能的全部或部分,以完成单元/集成测试– register()resend_confirmation()
  2. 通过添加覆盖率测试,以帮助确保对我们的代码库进行了充分的测试。
  3. 通过使用Selenium添加功能测试来扩展测试套件。

Happy testing!

测试愉快!

翻译自:

没有发现测试空测试套件

转载地址:http://vpqwd.baihongyu.com/

你可能感兴趣的文章
访问属性和访问实例变量的区别
查看>>
Spring MVC 异常处理 - SimpleMappingExceptionResolver
查看>>
props 父组件给子组件传递参数
查看>>
【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
查看>>
十二种获取Spring的上下文环境ApplicationContext的方法
查看>>
UVA 11346 Probability 概率 (连续概率)
查看>>
linux uniq 命令
查看>>
Openssl rand命令
查看>>
HDU2825 Wireless Password 【AC自动机】【状压DP】
查看>>
BZOJ1015: [JSOI2008]星球大战starwar【并查集】【傻逼题】
查看>>
HUT-XXXX Strange display 容斥定理,线性规划
查看>>
mac修改用户名
查看>>
一道关于员工与部门查询的SQL笔试题
查看>>
Canvas基础
查看>>
[Hive - LanguageManual] Alter Table/Partition/Column
查看>>
可持久化数组
查看>>
去除IDEA报黄色/灰色的重复代码的下划波浪线
查看>>
Linux发送qq、网易邮件服务配置
查看>>
几道面试题
查看>>
【转】使用 WebGL 进行 3D 开发,第 1 部分: WebGL 简介
查看>>