北京建设项目管理有限公司网站,唐山做网站哪家好,建立团购网站,网站跟信息推广有哪些信息化建设这些是之前的文章#xff0c;里面有一些基础的知识点在前面由于前面已经有写过#xff0c;所以这一篇就不再详细对之前的内容进行描述 Python自动化测试实战篇#xff08;1#xff09;读取xlsx中账户密码#xff0c;unittest框架实现通过requests接口post登录网站请求里面有一些基础的知识点在前面由于前面已经有写过所以这一篇就不再详细对之前的内容进行描述 Python自动化测试实战篇1读取xlsx中账户密码unittest框架实现通过requests接口post登录网站请求JSON判断登录是否成功
Python自动化测试实战篇2unittest实现批量接口测试并用HTMLTestRunner输出测试报告 Python自动化测试实战篇3优化unittest批量自动化接口测试代码ddt驱动yaml实现用例调用输出HTMLTestRunner测试报告 Python自动化测试实战篇4seleniumunttestddt实现自动化用例测试模拟用户登陆点击交互测试Assert捕获断言多种断言 Python自动化测试实战篇5优化seleniumunittestddt搞定100条测试用例只执行前50条
本篇主要是对之前的代码用PO分层的方式去优化梳理整个的自动化测试的流程 主要就是针对之前写过的文章进行用PO分层的思想去优化代码
Python自动化测试实战篇6用PO分层模式及思想优化unittestddtyamlrequest登录接口自动化测试PO分层简介1.本篇运用的PO分层流程图2.未优化之前的代码3.用PO分层优化自动化代码1.po_public 存放公共包2.po_config 存放项目包的路径3.po_data 存放数据报告4.po_usecase 存放测试用例和unittest的测试组件5.po_lastrun 存放运行文件PO分层简介
PO分层主要是为了帮助已经进入自动化的公司进行在测试用例上的维护增强代码可读性和减少用例维护的成本将测试代码和业务代码进行一个分离开来。
也就是意味着你用selenium用来做自动化和接口自动化测试的代码实际上是分开但是最终你还是可以一起调用但是如果你换了需要换一个其他的功能进行测试时你又要重新写一套新的测试用例这样就非常浪费时间。
PO分层就是将这些分开变成一个模块就像是餐厅大厨炒菜那样
#mermaid-svg-gmNqu21JW5bBe39t {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-gmNqu21JW5bBe39t .error-icon{fill:#552222;}#mermaid-svg-gmNqu21JW5bBe39t .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gmNqu21JW5bBe39t .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-gmNqu21JW5bBe39t .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gmNqu21JW5bBe39t .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gmNqu21JW5bBe39t .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gmNqu21JW5bBe39t .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gmNqu21JW5bBe39t .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gmNqu21JW5bBe39t .marker.cross{stroke:#333333;}#mermaid-svg-gmNqu21JW5bBe39t svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gmNqu21JW5bBe39t .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gmNqu21JW5bBe39t .cluster-label text{fill:#333;}#mermaid-svg-gmNqu21JW5bBe39t .cluster-label span{color:#333;}#mermaid-svg-gmNqu21JW5bBe39t .label text,#mermaid-svg-gmNqu21JW5bBe39t span{fill:#333;color:#333;}#mermaid-svg-gmNqu21JW5bBe39t .node rect,#mermaid-svg-gmNqu21JW5bBe39t .node circle,#mermaid-svg-gmNqu21JW5bBe39t .node ellipse,#mermaid-svg-gmNqu21JW5bBe39t .node polygon,#mermaid-svg-gmNqu21JW5bBe39t .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gmNqu21JW5bBe39t .node .label{text-align:center;}#mermaid-svg-gmNqu21JW5bBe39t .node.clickable{cursor:pointer;}#mermaid-svg-gmNqu21JW5bBe39t .arrowheadPath{fill:#333333;}#mermaid-svg-gmNqu21JW5bBe39t .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gmNqu21JW5bBe39t .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gmNqu21JW5bBe39t .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-gmNqu21JW5bBe39t .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-gmNqu21JW5bBe39t .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gmNqu21JW5bBe39t .cluster text{fill:#333;}#mermaid-svg-gmNqu21JW5bBe39t .cluster span{color:#333;}#mermaid-svg-gmNqu21JW5bBe39t div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gmNqu21JW5bBe39t :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}洗菜选材切菜炒菜熬汤端盘上菜假如我需要做红烧鱼那么我就调用后厨进行红烧鱼的制作那么前面的选材-洗菜-切菜过程都是一样我只要去考虑怎么烧鱼好吃和烧鱼多久的问题以及那个加强和优化那个环境更好留住顾客和增加翻台率
同样的如果我换了一道菜变成鲫鱼汤那么也很简单只要在最后变成熬汤的方法就可以前面的那些功能也是一样。
实现功能复用减少重复创建的流程这就是PO思想如果不用的话那么我需要在后厨重新搞一遍那样又是浪费很多时间。
1.本篇运用的PO分层流程图
那么结合到自动中如何走 大致如下图所示
2.未优化之前的代码
可以看到未优化前的代码虽然能够让人一眼就能看清晰知道需要做些什么但是对于复用性较差如果更换了功能再去调用的话结果就非常复杂
import timeimport yaml #导入yaml模块获取yaml文件值
import os #导入路径拼接
import unittest,requests
from ddt import ddt,data,unpack #导入数据驱动from HTMLTestRunner3_New import HTMLTestRunnerfopen(os.path.join(D:\pythonpj\pytest\lojump.yaml),moder,encodingutf-8)
ts_etyaml.safe_load(f)
url http://192.168.52.129:8080/cms/manage/loginJump.do
headers {Content-Type: application/x-www-form-urlencoded}
ddt
class lg(unittest.TestCase):data(*ts_et)unpackdef test_logjump(self,**dict):#定义一个测试用例repsrequests.post(urlurl,headersheaders,data{userAccount:dict[userAccount],loginPwd: dict[loginPwd]})print(reps.text)
def logjum():t_ime time.strftime(%Y-%m-%H-%M-%S)a1_path os.path.abspath(os.path.dirname(__file__))report_path os.path.join(a1_path, t_ime测试报告.html)discre unittest.defaultTestLoader.discover(start_dira1_path,patterng2.py)p open(report_path,wb)run HTMLTestRunner(streamp,titleCMS总计报告,description执行情况,testeryou)run.run(discre)
if __name__ __main__:logjum()unittest.main()我可以用PO分层将这里面的内容分开存放 3.用PO分层优化自动化代码
在Pycharm中新建6个包用于存放相应的功能
1.po_public 存放公共包 定义两个方法用户后续调用时使用 新建 use_configini.py
import configparser
class use_ini:def __init__(self,file):#定义一个构造方法self.file1 configparser.ConfigParser()#创建对象self.file1.read(file)def read_ini(self,a,b):value self.file1.get(a,b)#获取变量节点和变量名称return value#获取文件中变量节点的值新建 use_yaml.py
from po_config.deposit import *
import yaml
class use_yml:staticmethoddef re_yml(filename):yml open(os.path.join(yaml_path,filename),encodingutf-8)data yaml.safe_load(yml)return data
if __name__ __main__:print(use_yml.re_yml(lojump.yaml))新建 logjump.py
#用于存放通用的登录元素
class logjump:useraccount (userAccount,)password (loginPwd,)2.po_config 存放项目包的路径
在这里将这些路径类的放在po_config这个包里面 新建一个config.ini文件用于存放路径 新建一个deposit.py文件
import time
import yaml #导入yaml模块获取yaml文件值
from po_public.util.use_configini import *
import os #导入路径拼接
import unittest,requests
# from ddt import ddt,data,unpack #导入数据驱动
#获取ini的绝对路径
po_cofing_pathos.path.abspath(os.path.dirname(__file__))
get_pathuse_ini(os.path.join(po_cofing_path,config)).read_ini(conf,de_path)
print(get_path)
#封装一个yaml路径
yaml_path os.path.join(get_path,po_usecase)
#封装测试报告路径
time_t time.strftime(%Y-%m-%d-%H-%M-%S)
testlog os.path.join(get_path,po_data,time_t测试报告.html)
print(testlog)新建一个logurl.py文件
url http://192.168.52.129:8080/cms/manage/loginJump.do
headers {Content-Type: application/x-www-form-urlencoded}3.po_data 存放数据报告 4.po_usecase 存放测试用例和unittest的测试组件
这里直接将yaml用例放进去即可 新建logjump_ts.py 存放调用登录用例测试
import unittest,requests
from ddt import ddt,data,unpack #导入数据驱动
from po_config import logurl
from po_public.util import use_yamlts_etuse_yaml.re_yml#调用yaml
url logurl.url #调用 url
headers logurl.headers #调用存放的headersddt
class lg(unittest.TestCase):data(*ts_et)unpackdef test_logjump(self,**dict):#定义一个测试用例repsrequests.post(urlurl,headersheaders,data{userAccount:dict[userAccount],loginPwd: dict[loginPwd]})print(reps.text)
if __name__ __main__:unittest.main()5.po_lastrun 存放运行文件
新建一个log_run.py文件 可以看到用PO分层思想优化过后的代码很明显减少了很多很多重复性的东西就可以直接复用
import unittest
from po_config.deposit import *
from po_lastrun.HTMLTestRunner3_New import HTMLTestRunner
def logjump():unitRun unittest.defaultTestLoader.discover(start_dirget_path,patternlogjummp.py)fopen(testlog,wb)#导入存放测试报告的地址runHTMLTestRunner(streamf,title登录报告,description结果如下,testeryourname)run.run(unitRun)#执行对应文件中的测试报告
if __name__ __main__:logjump()#函数调用函数执行结果使用PO分层之后每个模块都可以随时修改而不用一个功能出现就重新创建一次影响工作效率