Python教程

python web自动化笔记

本文主要是介绍python web自动化笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、pytest测试用例编写规则:

  1. 文件以test_开头或者_test结尾
  2. 类名以Test开头
  3. 方法/函数名以test_开头
  4. 注意:测试类中不可以添加 __init__构造函数

二、pycharm设置默认执行器为pytest:

  • setting->Tools->Python Intergrated Tools
  • Default test runner:pytest

三、运行多条用例:

  1. 执行包下所有的用例:pytest/py.test [包名]
  2. 执行单独一个pytest模块: pytest 文件名.py
  3. 运行某个单独模块里面某个类:pytest 文件名.py::类名
  4. 运行某个模块里面某个类里面的方法:pytest 文件名.py::类名::方法名:

四、测试装置介绍

  1. 全局模块级: setup_module/teardown_module
  2. 类级,只在类中前后运行一次: setup_class/teardown_class
  3. 函数级,在类外: setup_function/teardown_funnction
  4. 方法级,类中的每个方法执行前后: setup_method/teardown_method
  5. 在类中,运行在调用方法的前后: setup/teardown_class

五、pytest常用命令行参数

  • –help
  • -x 用例一旦失败(fail/error),就立刻停止执行
  • –maxfail=num 失败用例达到多少条终止测试
  • -m 标记用例
  • -k 执行包含某个关键字的测试用例
  • -v 打印详细日志
  • -s 打印输出日志(一般-vs一起使用)
  • –collect-only (测试平台,pytest 自动导入功能)
  • –lf (–last-failed) 只重新运行故障
  • –ff (–failed-first) 先运行故障然后再运行其余的测试

六、mark标记测试用例

  1. mark标记测试用例
  • 场景:只执行符合要求的某一部分用例,可以把一个web项目划分多个模块,然后指定木块名称执行。
  • 解决:在测试用例方法上加@pytest.mark.标签名
  • 执行:-m执行自定义标记的相关用例
    • pytest -s test_mark.py -m=webtest
    • pytest -s test_mark.py -m apptest
    • pytest -s test_mark.py -m “not ios”
  1. 跳过(skip)及预期失败(xFail)

    • 这是pytest的内置标签,可以处理一些特殊的测试用例——不能成功的测试用例
    • skip - 始终跳过改测试用例
    • skipif - 遇到特定情况跳过该测试用例
    • xfail - 遇到特定情况,产生一个“期望失败”的输出
  2. skip使用场景

    • 调试时不想运行这个用例
    • 标记无法在某些平台上运行的测试功能
    • 在某些版本中执行,其他版本中跳过
    • 比如:当前的外部资源不可用时跳过
      • 如果测试数据时从数据库中渠道的
      • 连接数据库的功能如果返回结果未成功就跳过,因为执行也会报错
    • 解决1:添加装饰器
      • @pytest.mark.skip
      • @pytest.mark.skipif
    • 解决2:代码中添加跳过代码
      • pytest.skip(reason)
  3. xfail 使用场景

    • 与skip类似,预期结果未fail,标记用例未fail
    • 用法:添加装饰器 @pytest.mark.xfail
  4. 参数化

    • 参数化设计方法就是将模型中的定量信息变量化,使之成为任意调整的参数。
    • 对于变量化参数赋予不同数值,就可得到不同大小和形状的零件模型。
  5. mark-参数化测试函数

    • 测试场景
      • 测试登录成功,登录失败(账号错误,密码错误)
      • 创建多种账号:中文账号,英文账号
    • 普通测试用例方法
      • Copy多份代码或者读入参数
      • 一次性执行多个输入参数
    • pyetst参数化实现方法
      • @pytest.mark.parametrize进行参数化和数据驱动,更灵活
  6. mark:参数化测试函数的使用

    • 单参数

      search_list = ['appium', 'selenium', 'pytest']
      
      @pytest.mark.parametrize('name', search_list)
      def test_search(name):
          assert name in search_list
      
    • 多参数

      @pytest.mark.parametrize("test_input, expected", [("3+5", 8), ("2+5", 7), ("7+5", 12)])
      def test_mark_more(test_input, expected):
          assert eval(test_input) == expected
      
    • 用例重命名-添加ids参数

      @pytest.mark.parametrize("test_input, expected", [("3+5", 8), ("2+5", 7), ("7+5", 12)], ids=['add_3+5=8', 'add_2+5=7', 'add_3+5=12'])
      def test_mark_more(test_input, expected):
          assert eval(test_input) == expected
      
    • 笛卡尔积

      • 比如:a=[1,2,3], b=[a,b,c]
      • 组合:
        • (1, a), (1, b), (1, c)
        • (2, a), (2, b), (3, c)
        • (3, a), (3, b), (3, c)

七、Python代码执行pytest

  1. 执行:

    • 使用main函数

    • 使用python -m pytest 调用 pytest(jenkins持续集成用到)

      if __name__ == "__main__":
          # 1、运行当前目录下所有符合规则的用例,包括子目录 (test_*.py 和 *_test.py)
          pytest.main()
          # 2、运行test_mark1.py::test_dk模块中的某一条用例
          pytest.main(['test_mark1.py::test_dk', '-vs'])
          # 3、运行某个标签
          pytest.main(['test_mark1.py', '-vs', '-m', 'dk'])
          
      
  2. 常用的异常处理方法

    +try...except

    try:
        可能产生异常的代码块
    except [(ERROR1, ERROR2, ...)] [as e]:
        处理异常的代码块1
    except [(ERROR3, ERROR4, ...)] [as e]:
        处理异常的代码块2
    except [Exception]:
        处理其他异常
    
    • pytest.raise()

      • 可以捕获特定的异常
      • 获取捕获的异常的细节(异常类型,异常信息)
      • 发生异常,后面的代码将不会被执行
      def test_raise():
          with pytest.raises(ValueError, match='must be 0 or None'):
              raise ValueError("value must be 0 or None")
              
      def test_raise1():
          with pytest.raises(ValueError) as exc_info:
              raise ValueError("value must be 42")
          assert exc_info.type is ValueError
          assert exc_info.value.args[0] == "value must be 42"
      

九、元素定位的常见问题

  1. Selenium定位的方法有几种?分别是?

    • 有8种定位方法
    • 分别是classname、css seletor、id、name、link text、partial link text(当前链接文本)、tagname、xpath
    • 最常用的是id、xpath、css seletor、name
  2. 定位不到元素是什么原因导致的?

    • 定位编写错误

    • 元素还没有完全加载出来,就去进行定位,导致找不到元素。

      • 解决方法:添加隐式等待;xpath相对定位:$x("//*[text()='文本信息']")
    • id通常是唯一且不会变化的,但是因为后面前端技术栈的发展,很多ID都是动态生成的,且一直再变化

      • 解决方法:不适用不稳定的定位方式,比如动态id,而使用更稳定的方式,使用css selector或者xpath定位,比如xpath相对定位:$x("//*[text()='文本信息']")
    • 页面有iframe,确认是否有iframe:Ctri+F再element页面搜索,找到即代表有,确定要定位的元素是否在iframe里,如果包含,那么就需要切换iframe

      • 解决方法:需要切换到对应的iframe之后再进行定位操作:switch_to.frame(frame)
    • 存在页面切换

      • 解决方法:切换到新窗口后,再进行定位

        windows = self.driver.window_handles  # 获取当前所有窗口
        self.driver.switch_to.window(-1)  # 切换到最新的窗口
        
    • 元素是隐藏的,如果点击或者操作,那么就会报ElementNotInteractableException,辨别:style="display: none;"或者 hidden="hidden"就是元素的隐藏状态

      • 解决方法:隐藏按钮不能直接点击,如果要点击,必须使用js进行操作
      self.driver.execute_script('document.querySelector(".el-button--info").click()')  # el-button--info为class值
      
    • 元素被遮挡

      • 解决方法:添加显示等待
  3. selenium中隐藏元素如何定位?

    • 使用js操作该元素
  4. 如何定位动态元素?

    • 解决方法:不适用不稳定的定位方式,比如动态id,而使用更稳定的方式,使用css selector或者xpath定位,比如xpath相对定位:$x("//*[text()='文本信息']")
  5. 如何通过子元素定位父元素?

    解决方案:

    • 使用css 或者其他方式都无法实现,只有xpath表达式可以实现

    • 定位到子元素(使用xpath表达式):

    • 通过 /..即可定位到父元素

    console里输入表达式:$x("//*[@data-sort-order='default']")定位到子元素,data-sort-order为属性名,'default’为属性值,然后通过输入表达式:$x("//*[@data-sort-order='default']/..")定位到父元素

  6. 如何通过父元素定位子元素?
    在这里插入图片描述
    在这里插入图片描述

    通过父元素的class定位到父元素,console里输入 $(".class")回车定位,class为父元素的class值,然后输入$(".class .sub")回车定位子元素,sub为子元素的属性值。

  7. 如何判断一个页面上元素是否存在?

    • 通过查看当前页面dom,搜索该元素是否存在,如果是脚本自动化运行过程中,应该通过打印怕个_source,即可了解该元素在运行过程中是否存在
  8. 有的元素就在加载页面上,但是却定位不到,怎么解决?

    • 可能是隐藏元素,通过js进行操作
  9. 如果产品总是出现弹窗,导致用例无法执行,应该如何解决?

    • 原因:突然出现弹窗,元素被遮挡
    • 解决方法:通过添加黑名单异常处理解决
  10. 一个元素明明定位到了,点击无效(也没报错),如何解决?

    • 原因:异步加载js导致点击不到
    • 解决方案:利用显示等待循环点击该按钮,直到生效为止
这篇关于python web自动化笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!