pytest框架整体设计及规划

一、研发pytest框架的两种场景

场景1:测试脚本已提交

场景2:测试脚本未研发

二、框架分层

1.pytest框架层:脚本层、配置层、测试报告层、数据驱动层、日志层

2.项目框架层:前台、后台、服务器端

三、梳理框架

1.收集现有脚本

2.执行顺序调整

3.数据集梳理

4.调用传参梳理

四、脚本优化

1.结构优化

2.数据集优化

3.检查点优化

4.测试报告优化

5.测试日志优化

五、框架分层思想

先是执行pytest.ini文件

再是执行conftest.py文件

再是执行框架驱动层,框架驱动层可以是有多个

用驱动去执行脚本层、公共模块层、数据层、测试报告、测试日志

六、前置方法初始化的各种设置

1.setup的初始化合并。

若干个脚本都需要打开登录页面,怎样把setup提取出来,可以放到configtest里面去driver=none,是把脚本setup初始化下的语句放到configtest里面,但是不能用脚本上的driver了,只能configtest里面的browser,这个browser在方法后面要以参数的形式,改好的东西,在你的框架文档里面说明一下版本变更,保持框架和文档的一致性

定好的设计后面就不要再改了,再改的话就不要叫browser了,再改的话就是自己定义的self.driver了,公共的地方不能随意改,要改的话,也到大家通过一致才能改

这里是conftest.py文件
 

这里是conftest.py文件


from selenium import webdriver
import pytest
driver = None


@pytest.fixture(scope='session', autouse=True)
def browser():
    global driver
    chrome_options=webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    if driver is None:
        driver = webdriver.Chrome()
        url = "http://testplt.share.atstudy.com/admin/login/?next=/admin/"
        driver.get(url)
    return driver

修改后的脚本

# 登录成功的selenium代码

from selenium import webdriver
import pytest

# 定义类
class Test_lei_login1():

    # # 初始化里面放一些公共的属性,一个类里面只执行一次
    # def setup_method(self):
        # # 定义url
        # self.url='http://testplt.share.atstudy.com/admin/login/?next=/admin/'
        # # 启动谷歌浏览器
        # self.driver=webdriver.Chrome()
        # # 窗口最大化
        # # self.driver.maximize_window()
        # # 访问url
        # self.driver.get(self.url)

    # 定义登录方法
    @pytest.mark.smoke1
    def test_login(self,browser):

        # selenium跟接口的发送请求,有什么区别吗?
        # 有区别,接口的发送请求是
        # 第一种
        # response=requests.post(url,data=)
        # 第二种
        # s=requests.session()
        # response=s.post(url,data=)
        # selenium的发送请求是这样的

        # 找到元素输入内容
        browser.find_element_by_name('username').send_keys('atstudy')
        browser.find_element_by_name('password').send_keys('51testing')
        browser.find_element_by_xpath('//*[@id="login-form"]/div[3]/input').click()

        # 找到实际的结果
        result=browser.find_element_by_xpath('//*[@id="content-main"]/div/table/caption/a').text

        # 来一个断言
        assert result=='测试平台'

    # # 场景后置
    # def teardown_method(self):
    #     self.driver.close()


if __name__ == '__main__':
    pytest.main(['test_login1.py','-s','-v'])



2.什么情况下,会初始化两个浏览器

在运行的时候,会先去执行configtest,会初始化一个浏览器对象,在你的脚本里面也会初始化一个浏览器对象

3.browser的释放

def test_login_1(self,browser):
        browser.close()

七、driver驱动文件

在驱动脚本文件上,pytest.main里面的路径是能是相对路径,这样脚本移植到另外一个路径也不会有变化,只要内部结构路径不变就ok

import pytest

if __name__ == '__main__':
    pytest.main(["-vs",'D:\PythonLearn\pytest_five\login\\test_login1.py','-m smoke1'])

八、pytest标签整合处理

1.脚本上的标签:@pytest.mark.smoke2.qy

2.驱动脚本上:pytest.main(['脚本名','参数名','-m smoke'])

如果pytest.ini文件的addops上,写了参数-m smoke ,那么驱动脚本上,对应的参数就不需要写

3.pytest.ini文件上:addopts=-vs -rs -m smoke   

九、测试报告及日报与测试框架的整合

1.在测试报告中添加一个feature

@allure.feature("标签说明")

这个标签是放在脚本的class上面的

脚本最上面需要导入一个allure的类库

# 登录成功的selenium代码

from selenium import webdriver
import pytest
import allure

# 定义类
@allure.feature("标签说明")
class Test_lei_login1():

2.生成测试报告所需要的数据,是在驱动脚本上面加上--alluredir=./a/b,

import pytest

if __name__ == '__main__':
    pytest.main(["-vs",'D:\PythonLearn\pytest_five\login\\test_login1.py','-m smoke1','--alluredir=./report'])

3.生成测试报告

以前都是在命令行中写,现在整合成框架

系统的对象要导进来,然后再是通过系统的system方法,输入生成测试报告的命令

生成测试报告的路径跟生成测试报告所需要的数据的路径得是一致的

import pytest
import os


if __name__ == '__main__':
    # pytest.main(["-vs",'D:\PythonLearn\pytest_five\login\\test_login1.py','-m smoke1','--alluredir=./report'])
    os.system('allure generate ./report')

4.如果想让每个脚本运行的时候,都能生成测试报告,可以把相关的命令放在pytest.ini文件里,addopts下

5.如何把我们的日志整合在脚本里面

1日志这个统一的配置,都可以放一个config文件,以后所有的脚本都得去写日志,所以就把模板定义下来,给日志定义一个相关的文件,因为在我们原来的试验的时候,这个.conf文件名不是固定的,可以起其他的名字,不像是说py的日志公共配置,默认的是conftest,一般来说,一个项目就是统一的一个日志,加在根目录下,对整个项目都是有效的

2头文件要先复制过来,放到我们当前的脚本文件里面

import logging

import logging.config

3日志对象初始化的过程可以放到最上面,可以当做全局变量去用,在每一个需要打印出日志的代码输入日志输出语句

# 日志控制台输出的初始化
logging.config.fileConfig('logger.conf')
root_logger = logging.getLogger('root')

# 日志文件输出的初始化
logger = logging.getLogger('main')


# 定义类
@allure.feature("这是一个最基础的登录测试脚本")
class Test_lei_login1():
    # 定义登录方法
    @pytest.mark.smoke1
    def test_login(self,browser):
        # 找到元素输入内容
        browser.find_element_by_name('username').send_keys('atstudy')
        # 日志控制台输出
        root_logger.info("请输入用户名atstudy")
        # 日志文件输出
        logger.info("请输入用户名atstudy")
        browser.find_element_by_name('password').send_keys('51testing')
        root_logger.info("请输入密码atstudy")
        logger.info("请输入密码atstudy")
        browser.find_element_by_xpath('//*[@id="login-form"]/div[3]/input').click()
        root_logger.info("点击登录按钮")
        logger.info("点击登录按钮")
        # 找到实际的结果
        result=browser.find_element_by_xpath('//*[@id="content-main"]/div/table/caption/a').text
        root_logger.info("进行检查点验证")
        logger.info("进行检查点验证,实际结果:测试平台,预期结果:"+result)
        # 来一个断言
        assert result=='测试平台'

日志都是自己写出来的,是为了今后调试用的,如果出现错误了,就知道哪一个步骤错误了,

4.日志的变量反映到日志里面

        # 找到实际的结果
        result=browser.find_element_by_xpath('//*[@id="content-main"]/div/table/caption/a').text
        root_logger.info("进行检查点验证")
        logger.info("进行检查点验证,实际结果:测试平台,预期结果:"+result)
        # 来一个断言
        assert result=='测试平台'

5.日志总结,不是每个脚本都需要写日志,一般都是脚本比较复杂的脚本才需要写日志,来进调试用的

十、脚本的并发

脚本的内部可以并发,脚本和脚本之间没有相互干扰,脚本与脚本之间没有顺序控制

在多个机器上,按不同的目录去执行,并发不是一定需要,但是技术可以有一个扩展

当脚本支持并发,想让脚本执行更快一些

-n就是并发的数,建议一般不要超过5个,太大的话,你的内存cpu不够的话,反而速度会下降

因为他要初始化很多进程

pytest虽然提供给我们一个参数,非常方便,但是需要导入一个插件

import  pytest
import  time as t

def add(a,b):
   try:
      return a+b
   except Exception as e:
      return e.args[0]

@pytest.mark.parametrize('a,b,result',[
      (1,1,2),
      (1.0,1.0,2.0),
      (1, 1.0, 2.0),
      (1,0,1),
      ('','',''),
      ('hi ','wuya','hi wuya'),
      (0, '', "unsupported operand type(s) for +: 'int' and 'str'"),
      (1,'hi',"unsupported operand type(s) for +: 'int' and 'str'"),
       (1.0,'wuya',"unsupported operand type(s) for +: 'float' and 'str'"),
])
def test_add(a,b,result):
   t.sleep(1)
   assert  add(a,b)==result

#导入插件 pytest-xdist
if __name__=="__main__":
    # pytest.main(["-s","-v","test_conexe.py"])
    pytest.main(["-s","-v","-n=4","test_conexe.py"])

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
pytest是一个功能强大且易于使用的Python测试框架。它提供了丰富的功能和灵活的扩展性,使得编写和组织测试变得简单而高效。下面是pytest框架设计要点: 1. 测试用例的发现:pytest通过自动发现测试文件和测试函数来组织测试用例。它会在指定目录下递归搜索以"test_"或"_test"开头的文件,并查找以"test_"开头的函数作为测试用例。 2. 断言机制:pytest提供了丰富的断言方法,用于验证测试结果是否符合预期。这些断言方法包括assert语句、assert表达式、以及一些特殊的断言函数,如assertEqual、assertTrue等。 3. 丰富的插件系统:pytest具有强大的插件系统,可以通过插件扩展其功能。例如,可以使用插件来生成测试报告、集成其他测试工具、自定义测试收集规则等。 4. 参数化测试:pytest支持参数化测试,可以通过装饰器@pytest.mark.parametrize来定义多组输入参数,并自动运行多次测试用例。 5. 夹具(Fixture)机制:pytest通过夹具机制提供了一种方便的方式来管理测试用例中的共享资源。夹具可以在测试用例执行前后进行设置和清理操作,以确保测试环境的一致性。 6. 测试运行和报告:pytest提供了丰富的测试运行和报告功能。它可以以不同的方式运行测试,如按模块、类、函数等级别运行;同时,还可以生成详细的测试报告,包括测试用例的执行结果、覆盖率等信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值