首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python测试

Python测试
EN

Code Review用户
提问于 2022-01-29 04:30:46
回答 1查看 107关注 0票数 0

我用Python编写了基本代码:

  1. 从Swagger/Postman读取API集合,并提取有效载荷、链接和方法。
  2. 它使用令牌(从令牌链接生成)创建响应。
  3. 它在CSV中记录响应。

在进一步格式化代码方面需要帮助

  1. 创建函数。
  2. 减少代码行。
  3. 使用来自urllib.request导入urlopen导入请求的多线程进行性能优化,从bs4导入BeautifulSoup导入json从jsonpath_ng导入jsonpath,解析def GenerateToken():Link = "“页=urlopen(链接)# link以生成令牌内容= page.read() BeautifulSoup= BeautifulSoup( contents ) shred = list(soup.stripped_strings) BeautifulSoup= shred #获取带打开的令牌返回令牌(”TestResults.csv“),( "w")作为f_object: field= writer = csv.DictWriter(f_object,( fieldnames=fields) writer.writeheader() headers ={“授权”:"Bearer {}“.format(GenerateToken()}),其中open("postman_collection.json")作为f: data = json.load(f),用于数据中的res: for d in res: if "GET”in res : payload ={}url = res方法= res : response = requests.get(url,headers=headers,( data=payload)如果response.status_code == 200: rows1 = writer.writerows(rows1) # writer.writerows(rows1) if : rows2 =writer.writerows(rows2) # print(response.json().get("message")) (除了requests.ConnectionError: print(“未能连接”)= res有效载荷= res try:# response = requests.request("GET",headers=headers,data=payload)响应= requests.request( "POST",url,headers=headers,data=payload )# print(response.json())如果response.status_code == 200: rows3 = writer.writerows(rows3)的话:rows4 = writer.writerows(rows4) # print(response.json().get("message")),但requests.ConnectionError: print(“未能连接”)除外:url = res方法= res有效载荷= res:# response = requests.request("GET",headers=headers,data=payload)响应= requests.request( "POST",url,headers=headers,data=payload )# print(response.json())如果response.status_code == 200: rows5 = writer.writerows(rows5)的话:rows6 = writer.writerows(rows6) # print(response.json().get("message")),但requests.ConnectionError: print(“未能连接”) f_object.close()
EN

回答 1

Code Review用户

回答已采纳

发布于 2022-01-29 22:08:20

在这段代码中确实有很多重复

你有三个案子: GET,POST,other。所以我们有:

代码语言:javascript
运行
复制
 if "GET" in res["request"]["method"]:
     payload = {}
     url = res["request"]["url"]["raw"]
     method = res["request"]["method"]
 elif "POST" in res["request"]["method"]:
     url = res["request"]["url"]["raw"]
     method = res["request"]["method"]
     payload = res["request"]["body"]["raw"]
 else:
     url = res["request"]["url"]["raw"]
     method = res["request"]["method"]
     payload = res["request"]["body"]["raw"]

现在我们有了一个简单的概述,我们可以将整个块简化如下:

代码语言:javascript
运行
复制
url = res["request"]["url"]["raw"]
method = res["request"]["method"]
if "GET" in res["request"]["method"]:
    payload = {}
else:
    payload = res["request"]["body"]["raw"]

方法之间的差别很小:有效载荷。

然后,我们着手处理请求本身:

代码语言:javascript
运行
复制
# GET
response = requests.get(url, headers=headers, data=payload)

# POST
response = requests.request(
 "POST", url, headers=headers, data=payload
)

# other
response = requests.request(
 "POST", url, headers=headers, data=payload
)

再说一遍,一切都很相似。我们可以构建这样一个通用语句:

代码语言:javascript
运行
复制
method = res["request"]["method"]
response = requests.request(method, url, headers=headers, data=payload)

没有必要使用3种不同的语句,因为它们都传递相同的参数。唯一不同的是方法,您也可以将其作为参数传递。

现在您有一个语句来发出请求,我们需要查看结果。这是一个简单的条件200或更多。因此:

代码语言:javascript
运行
复制
if response.status_code == 200:
    result = "OK"
else:
    result = response.text

rows = [
    {
    "API_Endpoint": url,
    "Method": method,
    "Status_Code": response.status_code,
    "Message": result,
    "Timestamp": datetime.datetime.utcnow(),
    }
]
writer.writerows(rows)

据我所见,你重复了6次同样的事情。唯一变化的是方法+ HTTP状态代码和结果响应消息。这可以很容易地简化。

最后的f_object.close()并不是必需的,因为您正在使用上下文管理器(with)。

因此,您的代码已经可以像这样被缩短(未经测试,但希望简洁是可以察觉的):

代码语言:javascript
运行
复制
with open("TestResults.csv", "w") as f_object:
    fields = ["API_Endpoint", "Method", "Status_Code", "Message", "Timestamp"]
    writer = csv.DictWriter(f_object, fieldnames=fields)
    writer.writeheader()
    headers = {"Authorization": "Bearer {}".format(GenerateToken())}
    with open("postman_collection.json") as f:
        data = json.load(f)
        for res in data["item"]:

            for d in res["request"]:

                # common for all methods
                url = res["request"]["url"]["raw"]
                method = res["request"]["method"]

                # empty payload for GET
                if "GET" in res["request"]["method"]:
                    payload = {}
                else:
                    payload = res["request"]["body"]["raw"]

                try:
                    response = requests.request(method, url, headers=headers, data=payload)

                    if response.status_code == 200:
                        result = "OK"
                    else:
                        result = response.text

                    rows = [
                        {
                        "API_Endpoint": url,
                        "Method": method,
                        "Status_Code": response.status_code,
                        "Message": result,
                        "Timestamp": datetime.datetime.utcnow(),
                        }
                    ]
                    writer.writerows(rows)
                    # print(response.json().get("message"))
                except requests.ConnectionError:
                    print("failed to connect")

因此,在删除重复代码之后,代码现在变得更易于管理了。基本上,我们从118条线路上升到43条。

该代码块可以放入一个函数中,该函数的名称应该反映实际用途(我们不知道)。那么最好将文件名作为参数传递,而不是让它们在函数中硬编码。

如果要对主机执行重复请求,那么应该使用requests.session来提高性能,简化状态、cookie、标头等的处理。

为了解决您的一些问题:如果目的是执行并行处理或多线程处理,那么在Python中有不止一种方法可以做到这一点。哪一个最好取决于你的情况。我可以推荐一个作为教程的链接:Python多线程和多处理教程

但是您有两个不同的任务:写入CSV文件和向API发送数据。因此,将代码分成两个函数是有意义的。如果您要进行并行处理,那么基本上可以一次读取JSON一个项,然后输入一个“队列”。因此,您需要某种接受URL的函数,它带有可选的有效负载并返回您想要的任何内容,这可能只是基于HTTP状态代码的响应消息。如果您查看上面引用的链接并根据您的需要对其进行调整,也许您可以围绕现有代码构建一些内容。

我可能会编辑这篇文章,以增加更多的建议。

我还推荐Tarek & Michal编写的“专家Python编程”一书,如果您想深入了解这些主题的话。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/273515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档