文本

PythonAPI测试自动化框架发出HTTP请求-2

Python API测试自动化框架(第2部分)发出HTTP请求 了解被测API 让我们更好地了解本教程中将使用的API。 我们将使用people-api,这是一组使用Python Flask,SQLAlchemy开发的CRUD HTTP操作,并使用sqlite作为数据库,并表示具有名字,姓氏和ID的人员列表 要从github设置克隆people-api存储库,然后通过运行以下命令激活pipenv: 皮壳 通过执行以下命令,确保所有依赖项都已安装在pipenv中: pipenv安装 完成后,通过执行以下命令来初始化数据库 python build_database.py 这将为本地sqlite数据库添加一些虚拟记录 最后,通过执行并确保该服务在测试过程中保持运行,在本地启动HTTP服务 python server.py 从日志中我们可以看到本地服务已启动,您还将看到对服务器的任何请求的日志

* Serving Flask app "config" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 105-008-664

让我们导航至http://0.0.0.0:5000以查看该应用程序, 注意:要查看此API的规范,我们可以导航至http://0.0.0.0:5000/api/ui/#/ 如您所见,此API支持基本的CRUD操作(CREATE,READ,UPDATE,DELETE) https://automationhacks.io/assets/images/2020/11/swagger.png 如果您想处理这些请求,我还在此回购协议中的postman文件夹下包括了一个postman集合,其中已经设置了所有这些基本操作。 API支持创建人员,更新人员,删除人员并能够读取数据库中的一个或多个用户。 在编写测试时,我们将看到这些操作。 第一次测试,通过GET API读取 让我们看看如何创建一个基本测试以使用已经导入的请求模块通过python发出此HTTP请求 该API的curl为: curl --location --request GET 'http://0.0.0.0:5000//api/people'
--header 'Accept: application/json' 下面的代码片段连接了一个基本的HTTP GET请求,然后断言该服务向我们返回了200个状态代码,并且返回的人员列表中有kent。 注意,我们使用来自assertpy模块的assert_that来进行流畅的断言,来自这些断言的失败消息非常可读,我们将在以后的文章中讨论更多有关此的消息。 请确保使用pipenv install assertpy将其安装在virtualenv中 如果您想处理这些请求,我还在此回购协议中的postman文件夹下包括了一个postman集合,其中已经设置了所有这些基本操作。 API支持创建人员,更新人员,删除人员并能够读取数据库中的一个或多个用户。 在编写测试时,我们将看到这些操作。 第一次测试,通过GET API读取 让我们看看如何创建一个基本测试以使用已经导入的请求模块通过python发出此HTTP请求 该API的curl为: curl --location --request GET'http://0.0.0.0:5000//api/people'
--header'接受:application / json' 下面的代码片段连接了一个基本的HTTP GET请求,然后断言该服务向我们返回了200个状态代码,并且返回的人员列表中有kent。 注意,我们使用来自assertpy模块的assert_that来进行流畅的断言,来自这些断言的失败消息非常可读,我们将在以后的文章中讨论更多有关此的消息。 请确保使用pipenv install assertpy将其安装在virtualenv中

import requests
from assertpy.assertpy import assert_that
from config import BASE_URI

def test_read_all_has_kent():
    # We use requests.get() with url to make a get request
    response = requests.get(BASE_URI)
    # response from requests has many useful properties
    # we can assert on the response status code
    assert_that(response.status_code).is_equal_to(requests.codes.ok)
    # We can get python dict as response by using .json() method
    response_text = response.json()
    first_names = [people['fname'] for people in response_text]
    assert_that(first_names).contains('Kent')

在上面,我们使用BASE_URI变量来获取要使用的基本api URL。 它存储在config.py文件中,如下所示: BASE_URI ='http://0.0.0.0:5000/api/people' 使用POST方法创建人 好了,现在我们已经处理了GET API的基本情况,让我们看看如何发出POST请求。 通常在Rest API中,当您需要创建资源时,可以使用POST方法 下面是发出请求的cURL,我们的python代码将提供相同的标头,正文和URL来满足请求

curl --location --request POST 'http://0.0.0.0:5000//api/people' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   "fname": "TAU",
   "lname": "User"
 }'

这是我们要自动化的完整流程: 在数据库中创建一个新人 使用GET API验证是否存在新创建的用户 进行过滤以查找创建的数据是否存在于系统中的所有用户中

def test_new_person_can_be_added():
    unique_last_name = create_new_person()

    # After user is created, we read all the users and then use list comprehension to find if the
    # created user is present in the response list
    peoples = requests.get(BASE_URI).json()
    is_new_user_created = search_created_user_in(peoples, unique_last_name)
    assert_that(is_new_user_created).is_not_empty()

def create_new_person():
    # Ensure a user with a unique last name is created everytime the test runs
    # Note: json.dumps() is used to convert python dict to json string
    unique_last_name = f'User {str(uuid4())}'
    payload = dumps({
        'fname': 'New',
        'lname': unique_last_name
    })

    # Setting default headers to show that the client accepts json
    # And will send json in the headers
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }

    # We use requests.post method with keyword params to make the request more readable
    response = requests.post(url=BASE_URI, data=payload, headers=headers)
    assert_that(response.status_code, description='Person not created').is_equal_to(requests.codes.no_content)
    return unique_last_name

def search_created_user_in(peoples, last_name):
    return [person for person in peoples if person['lname'] == last_name]


在这里Ln 2:调用create_new_person(),在此我们首先创建要作为请求的一部分传递的正文 请注意,在Ln 14上,我们使用json模块中的dumps()方法将python dict转换为json字符串(序列化),并使用str(uuid4())在Ln 13上获得唯一的姓氏,以确保我们没有冲突的数据 在每次测试中 最后,我们使用发出POST请求 响应= request.post(url = BASE_URI,data = payload,headers = headers) 然后使用search_created_user_in()方法查看数据库中是否存在新创建的用户 使用DELETE方法删除一个人 我们将如何删除方法? 在此API中,我们可以通过传入person_id来删除人员,在尝试删除操作之前创建自己的测试数据而不是使用任何现有数据始终是一个好习惯,因为这可能会导致不确定性测试 所以这是流程: 创建一个新人 使用读取的API获取人员ID 点击删除端点并断言 由于我们已经有创建和读取用户的方法,因此剩下的唯一事情就是通过确保在API路径参数中传递person_id来实现DELETE操作。我们使用出色的f字符串创建我们的URL,然后使用 requests.delete()方法。

def test_created_person_can_be_deleted():
    persons_last_name = create_new_person()

    peoples = requests.get(BASE_URI).json()
    newly_created_user = search_created_user_in(peoples, persons_last_name)[0]

    delete_url = f'{BASE_URI}/{newly_created_user["person_id"]}'
    response = requests.delete(delete_url)
    assert_that(response.status_code).is_equal_to(requests.codes.ok)

奖金 请注意,在断言中我们没有为状态代码指定数值,请求提供了一个查找字典,您可以在其中轻松使用语法等可读英语指定代码,这绝对比每次解析X在MDN上的含义都更好-Mozilla开发人员网络 😉 换句话说,我们可以将其写成request.codes.ok而不是200 结论 这只是图书馆可以进行的请求的一种体验。 有关其提供的所有功能的更多详细信息,请阅读requests文档,希望这对您如何使用请求进行HTTP调用有一个好主意。 在下一篇文章中,我们将讨论有关使用JSON / XML数据类型和断言的更多信息。 敬请关注。 ⏰ 这是从MDN读取的Content-Type和Accept标头 如果您认为这篇文章很有用,请与朋友或同事分享,如果您有想法,我很乐意在Twitter或评论中聊天。 直到下一次。 快乐的测试和编码。

author

石头 磊哥 seven 随便叫

company

thoughtworks(离职了。。。。)

大家好,本人不才,目前依旧混迹于thoughtworks,做着一名看起来像全栈的QA,兴趣爱好前端,目前是thoughtworks 西安QA社区的leader,如果有兴趣分享话题,或者想加入tw,可以找我

roles

QA(营生) dev(front-end dev 兴趣爱好)

联系方式

如果想转载或者高薪挖我 请直接联系我 哈哈

wechat:

qileiwangnan

email:

qileilove@gmail.com