文章总览图

fixtureunittest是冲突的。舍弃unittest只用pytest

会遇到在很多用例当中,它的前置条件是长得一样的。用例写的越来越多的时候,肯定会遇到前置条件都差不多,大家差距不是很大。这样的话,如果每个py文件都写个setUptearDown,就重复率挺高的。要是能拎取出来做个公共的就好了。

实际上在unittest这个模式下,也可以做个公共的setUpClass,单独创建一个文件,然后引用下,继承一下,就变成公用的了。想做也是可以做的,但是pytest做的更好。

fixture在项目当中作为公共用法来用。可以专门定义额外的setUptearDown,在单独的地方,不放在测试用例当中。测试用例将它主动引进来,作为它的前置和后置就好了。

首先定义fixture,怎么定义呢?

它是一个函数,只不过这个函数,我们要加上一个装饰说明,说明这个函数是有特殊用途的。什么特殊用途呢?

是作为我们的前置和后置。

那这个装饰器就是@pytest.fixture,在函数名称前面。

pytest中,环境准备和环境清理是完全放在一起的。在unittest中,它是两个都分开的,一个是setUp,一个是tearDown,我们会定义两个函数。

pytest中,只要一个函数就可以了。fixture可以在当前的文件中来定义,也可以额外得去定义。

第一种,公有化的方式:

前置和后置定义在特殊的文件当中,以后谁想要用,就直接调用就好了。一般调用函数,需要引进来才能调用,但是在pytest当中不需要。直接用个装饰器引用下就可以了,完全不需要引用这个文件。

1.它是怎么实现这种公有化的方式呢?

TeatCase目录下,新建一个Python文件,文件名固定是:conftest

这个文件就是个公有化的文件。

conftest文件必须和测试用例放在一起,和测试用例文件是同级。

fixture是一个函数。

可以看到源码解析:


  1. def fixture(
  2. callable_or_scope=None,
  3. *args,
  4. scope="function",
  5. params=None,
  6. autouse=False,
  7. ids=None,
  8. name=None
  9. ):
  10. """Decorator to mark a fixture factory function.
  11. This decorator can be used, with or without parameters, to define a
  12. fixture function.
  13. The name of the fixture function can later be referenced to cause its
  14. invocation ahead of running tests: test
  15. modules or classes can use the ``pytest.mark.usefixtures(fixturename)``

可以看到第一个参数是scopescope就是会话级、模块级、类级、函数级。代表它的作用域,默认是function。什么是function

函数是指单个的测试用例,也就是每一个测试用例。剩下的一些参数可以暂时不用管。

默认的是function,代表的是setUptearDown。测试用例是以函数的形式呈现的。既然是函数级别的,也就是一个测试用例一个测试用例的。类级别的参数,源码解析:

  1. :arg scope: the scope for which this fixture is shared, one of
  2. ``"function"`` (default), ``"class"``, ``"module"``,
  3. ``"package"`` or ``"session"`` (``"package"`` is considered **experimental**
  4. at this time).

参数有functionclassclass就是setUpClasstearDownClass

setUptearDown是作用在每个测试用例上,setUpClasstearDownClass是作用在测试类当中,module就是整个Py文件。package是包,session是会话。这个会话是指测试用例会话。高级别的用法暂时用不上,就不用管它。

session级别的,在接口自动化中可能用得上。每个测试用例可能都涉及数据库校验,它的前提就是数据库连接,得到一个数据库对象以及游标操作。那么就可以用session了。

在所有测试用例之前,先把这个东西运行一下,在后续所有操作中,直接用这个对象就行了。不需要在不同的测试用例中去连接。

实际上,接口自动化中用setUpClass就可以解决这个问题。

2.怎么知道在这个access_web函数中,哪些代码是前置,哪些代码是后置啊?

用关键字yield分隔前置操作和后置操作。如果没用后置,那么关键字yield都不用写。

代码如下:

  1. import pytest
  2. from selenium import webdriver
  3. from PageObjects.login_page import LoginPage
  4. from TestDatas import Comm_Datas as cd
  5. driver=None
  6. #声明它是一个fixture
  7. @pytest.fixture(scope="class")
  8. def access_web():#说明整个测试类只运行一次
  9. global driver
  10. #前置操作
  11. print("=======所有测试用例执行之前的,setup====整个测试类只执行一次======")
  12. driver=webdriver.Chrome()
  13. driver.get(cd.web_login_url)
  14. lg=LoginPage(driver)
  15. yield(driver,lg) #分隔线;#后面接返回值
  16. print("========所有测试用例之后的,teardown====整个测试用例只执行一次======")
  17. driver.quit()
  18. #后置操作
  19. @pytest.fixture#默认是`setUp`和`tearDown`,所以这里不需要带括号。
  20. def refresh_page():
  21. global driver
  22. #前置操作
  23. yield
  24. #后置操作
  25. driver.refresh()
  26. @pytest.fixture(scope="session")
  27. def session_demo():
  28. print("****我是整个测试会话期间的开始****")
  29. yield
  30. print("****我是整个测试会话期间的结束****")
  31. @pytest.fixture(scope="class")
  32. def class_demo():
  33. print("****我是class的开始****")
  34. yield
  35. print("****我是class的结束****")
  36. @pytest.fixture
  37. def func_demo():
  38. print("****我是function的开始****")
  39. yield
  40. print("****我是function的结束****")

fixture功能和ddt不能共用。现阶段不能适用ddt,它有它自己的方式来实现数据驱动。

@pytest.mark.usefixtures("refresh_page") 可以写在测试用例前面,但是这个测试类下面每一个测试用例都用到了 fixture,大家的操作都是一样的,就没必要在每个函数前面都写上它。直接把它放在类前面就可以了。表示大家都用。

  1. @pytest.mark.usefixtures("access_web")#在运行的时候,会去运行access_web函数
  2. @pytest.mark.usefixtures("refresh_page")
  3. class TestLogin:
  4. # 正常用例 - 登陆成功 #fixture的函数名称,用来接收它的返回值
  5. @pytest.mark.smoke
  6. def test_login_2_success(self,access_web):#fixture的函数名称作为用例参数,用来接收fixture的返回值
  7. logging.info("****登陆用例:正常场景:适用正确的用户名和密码登陆***")
  8. #步骤 输入用户名和密码 点击登陆
  9. access_web[1].login(ld.success_data["user"],ld.success_data["passwd"])
  10. #断言 首页当中,如何找到退出这个元素
  11. assert IndexPage(self.access_web[0]).isExist_logout_ele()

登陆的话,可以不需要它,用setUptearDown就可以解决这个问题。因为它的前置和后置只有它自己用,没用别人用。

第二种,私有化的方式:

假如TestLogin中9个前置后置都一样,只有1个前置后置不一样,该怎么做?

此代码运行可能会报错,用法需根据实际代码调试:

  1. @pytest.mark.usefixtures("func_demo")#在运行的时候,会去运行access_web函数
  2. @pytest.mark.usefixtures("class_demo")
  3. @pytest.mark.demo
  4. def test_demo():
  5. print("ffffffffffffffff")

1.把单独的这一个拎取出来,定义成一个函数就好了,作为函数的形式放在外面。其它9个一样的都放在类当中。

2.假如10个测试用例中,5个是这样的,另外5个是另外一个样子的。就可以定义2个测试类。2个测试类用不一样的fixture

以上私有化的方式的2种方法需要实操,根据实际情况判断2种方法的可用性以及调试。


欢迎扫码关注!

本文使用 mdnice 排版

pytest的fixture怎么用?的更多相关文章

  1. pytest.4.Fixture

    From: http://www.testclass.net/pytest/fixture/ 我们可以简单的把Fixture理解为准备测试数据和初始化测试对象的阶段. 一般我们对测试数据和测试对象的管 ...

  2. pytest(6)-Fixture(固件)

    什么是固件 Fixture 翻译成中文即是固件的意思.它其实就是一些函数,会在执行测试方法/测试函数之前(或之后)加载运行它们,常见的如接口用例在请求接口前数据库的初始连接,和请求之后关闭数据库的操作 ...

  3. 『德不孤』Pytest框架 — 12、Pytest中Fixture装饰器(二)

    目录 5.addfinalizer关键字 6.带返回值的Fixture 7.Fixture实现参数化 (1)params参数的使用 (2)进阶使用 8.@pytest.mark.usefixtures ...

  4. pytest 15 fixture之autouse=True

    前言 平常写自动化用例会写一些前置的fixture操作,用例需要用到就直接传该函数的参数名称就行了.当用例很多的时候,每次都传这个参数,会比较麻烦.fixture里面有个参数autouse,默认是Fa ...

  5. pytest 5. fixture之yield实现teardown

    前言: 1.前面讲的是在用例前加前置条件,相当于setup,既然有setup那就有teardown,fixture里面的teardown用yield来唤醒teardown的执行 看以下的代码: #!/ ...

  6. pytest 3.fixture介绍一 conftest.py

    前言: 前面一篇pytest2 讲到用例加setup和teardown可以实现在测试用例之前或之后加入一些操作,但这种是整个脚本全局生效的,如果我想实现以下场景: 用例1需要先登录,用例2不需要登录, ...

  7. pytest的fixture和conftest

    解决问题:用例1需要先登录,用例2不需要登录,用例3需要先登录.很显然这就无法用setup和teardown来实现了,这个时候就可以自定义测试用例的预置条件,比setup灵活很多. 1.fixture ...

  8. 【Pytest04】全网最全最新的Pytest框架fixture应用篇(2)

    一.Fixture参数之params参数可实现参数化:(可以为list和tuple,或者字典列表,字典元祖等) 实例如下: import pytest def read_yaml(): '] @pyt ...

  9. 【Pytest03】全网最全最新的Pytest框架fixture应用篇(1)

    fixtrue修饰器标记的方法通常用于在其他函数.模块.类或者整个工程调用时会优先执行,通常会被用于完成预置处理和重复操作.例如:登录,执行SQL等操作. 完整方法如下:fixture(scope=' ...

  10. pytest之fixture使用详解

    简介: fixture区别于unnitest的传统单元测试(setup/teardown)有显著改进: 1.有独立的命名,并通过声明它们从测试函数.模块.类或整个项目中的使用来激活. 2.按模块化的方 ...

随机推荐

  1. Java Web(5)-Servlet详解(下)

    一.HttpServletRequest 类 1. HttpServletRequest 类作用? 每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解 ...

  2. PHP unset() 函数

    unset() 函数用于销毁给定的变量.高佣联盟 www.cgewang.com PHP 版本要求: PHP 4, PHP 5, PHP 7 语法 void unset ( mixed $var [, ...

  3. JWT到底是个什么鬼?

    前面一篇我们了解了微服务安全认证架构是如何演进而来的,但是发现v2.5架构仍然较重,有没有轻量级一点的方法呢?其实业界早已有了实践,它就是基于JWT的安全认证架构.JWT到底是个什么鬼呢?本篇为你解答 ...

  4. [草稿]基于 Virtuoso 环境比较便捷的项目文件及权限管理方案

    https://www.cnblogs.com/yeungchie/ 假设如下情况: 1 项目名称 Project_01 2 包含 4 名研发用户,user01 和 user02 为前端工程师,use ...

  5. C/C++编程笔记:inline函数的总结!C/C++新手值得收藏!

    在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间. 在系统下, ...

  6. Android JNI之数据类型

    JNI中数据类型的意义在于桥接Java数据类型与C数据类型. 简单数据类型: Java Type Native Type Description boolean jboolean unsigned 8 ...

  7. idea安装testng插件后,无法使用调用testng里面的类

    1.已经安装好idea的testng插件,并且应用上相关的两个插件. 2.已经导入maven仓库的testng.jar,并且重启过idea后:发现不能调用. 本人在百度很多相关资料,始终没有找到解决方 ...

  8. RabbitMQ好文章推荐

    文章来源:掘金    作者:申城异乡人 RabbitMQ使用教程(一)RabbitMQ环境安装配置及Hello World示例     https://juejin.im/post/5ce644b9f ...

  9. JDK8的Stream操作

    原文:https://mp.weixin.qq.com/s/N2zor5RzuHHTHQLHWVBttg 作者:思海同学  好好学java 其他资料:https://mp.weixin.qq.com/ ...

  10. Linux 下使用 killall 命令终止进程的 8 大用法

    Linux 的命令行提供很多命令来杀死进程.比如,你可以向 kill 命传递一个PID来杀死进程:pkill 命令使用一个正则表达式作为输入,所以和该模式匹配的进程都被杀死. 但是还有一个命令叫 ki ...