文章目录

  • 一、参数化parametrize的使用
  • 二、skip3与skipif的用法
  • 1、skip(reason)
  • 2、skipif(condition, reason)
  • 3、skip和skipif标记功能的巧用:
  • 4、最常用的用法
  • 三、setup和teardown
  • 四、fixture固件函数
  • 1、调用方式(一)
  • 2、调用方式(二)
  • 3、调用方式(三)
  • 五、conftest.py
  • 1、用法:初始化数据
  • 2、用法:作为变量传递
  • 六、自定义标记


一、参数化parametrize的使用

使用pytest.mark.parametrize()进行参数化传递,参数传递有以下三种方式,分别适用不同的场景

# 列表内存放多个数据
data1 = ['zhangsan', 'lisi']
# 列表内嵌套元组,一般适用读取的excel数据后,按此格式存放进行数据驱动
data2 = [('zhangsan', '男'),('lisi', '女')]
# 列表内嵌套字典,一般用的少
data3 = [{'公司': 'XXX公司','强项':'打台球'},{'公司': '智能','强项':'骑驴'}]

@pytest.mark.parametrize('name_data', data1)
def test_a(name_data):
	print('参加踢球的人有{}'.format(name_data))
	
@pytest.mark.parametrize('sex_data', data2)
def test_b(sex_data):
	print('{0}的性别是{1}'.format(sex_data[0],sex_data[1]))
	
@pytest.mark.parametrize('aihao_data', data1)
def test_b(aihao_data):
	print('%s公司的强项是%s' % (aihao_data['公司'],aihao_data['强项']))

二、skip3与skipif的用法

skip3与skipif可以放在单个函数前,也可以放在整个类前

1、skip(reason)

# 还可以写理由:@pytest.mark.skip(reason='这里写理由')
# 一个函数可以同时出现两个不同类型的修饰器,上下顺序无所谓
@pytest.mark.skip()   
@pytest.mark.parametrize('name', data)   
def test_a(name):
	print('hahahah')

2、skipif(condition, reason)

@pytest.mark.skipif(sys.platform=='win32',reason='如果是win系统就跳过')
def test_a():
	pass

3、skip和skipif标记功能的巧用:

skip_mark = pytest.mark.skip(reason='这里写理由')
@skip_mark
def test_a():
	pass	
		  
skipif_mark = pytest.mark.skipif(sys.platform=='win32',reason='如果是win系统就跳过')
@skipif_mark
def test_b():	
	pass

4、最常用的用法

@pytest.mark.parametrize('my_name', ['小李', '小王', '小刘'])
def test_pytest_dot_skip_01(my_name):
    if my_name == '小刘':
        # pytest.skip()方法有点类似于continue,跳过“本次”函数执行
        # 做自动化测试时,我们可以巧用这个方法,根据动态的条件结果做一些“跳过”
        # 该方法可以不入参,入参的话直接写上一段跳过理由的字符串
        # 但不可以写成pytest.skip(reason='xxx理由'),这是语法规定
        pytest.skip('我是【{0}】,但我被跳过了。'.format(my_name))
    else:
        print('我是', my_name)

三、setup和teardown

  • setup_module、teardown_module # 整个.py模块开始前后
  • setup_function、teardown_function # 每个独立函数级别用例开始前后
  • setup_class、teardown_class # 类的开始前后
  • setup_method/teardown_method、setup/teardown #都是类内的每个用例方法,但是如果存在
  • setup_method/teardown_method,先执行setup_method/teardown,再执行setup

四、fixture固件函数

使用@pytest.fixture()装饰器生成固件函数

@pytest.fixture()
def login():
    print('我登录了')

1、调用方式(一)

把fixture固件函数作为入参
注意:只有Pytest的测试函数或方法可以把fixture固件函数作为入参

# login为固件函数直接作为参数传入
def test_a(login):
    print('成功进入了我的主页。')

2、调用方式(二)

使用@pytest.mark.usefixtures(‘固件函数名称’)装饰器

# login为固件函数
@pytest.mark.usefixtures('login')
@pytest.mark.parametrize('course_name', ['PyTest', 'UnitTest'])
def test_buy_course(course_name):
    print('购买课程【{0}】成功。'.format(course_name))

3、调用方式(三)

使用@pytest.fixture()装饰器时可以传入autouse和scope参数

  • autouse:默认为False,设置为True后会自动调用,且调用优先级高于autouse=False的
  • scope:有四个级别参数"function"(默认),“class”,“module”,"session
  • function:每一个函数或方法都会调用
  • class:每一个类调用一次,一个类中可以有多个方法
  • module:每一个.py文件调用一次,该文件内又有多个function和class
  • session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
@pytest.fixture(autouse=True)
def open_app():
    print('成功打开了App首页。')

五、conftest.py

可以理解conftest是PyTest的中央处理器,文件名只能是conftest.py
注意:一定要注意conftest.py的位置,不同文件夹下均可以有此文件

1、用法:初始化数据

@pytest.fixture(scope="session",autouse=True)
def setup_function():
    print("执行conftest文件")
    basefunc.delfile()
    # yeild分割开始和结束
    # 在所有的用例开始前会执行yield前面的代码
	# 在所有的用例结束后会执行yield后面的代码
    yield
    print("执行conftest文件")
    basefunc.delfile()

2、用法:作为变量传递

# conftest.py中编写固件函数
@pytest.fixture
def url_ip():
	ip = '127.0.0.1'
	# 公共变量必须是被装饰过的方法,并且要有返回值
	return ip
# test_1.py中使用,直接作为参数传递
data = ['liyanda']
@pytest.mark.parametrize('api_data', data)+

def test_api(url_ip, url_port, api_data):
    print(url_ip)
    print(url_port)
    print(api_data)

六、自定义标记

@pytest.mark.xxx可以自定义标记(个人觉得很有实用性的功能),可以标记测试类,也可以标记测试函数

# 标记类
@pytest.mark.high
class TestApi:
	def test_a():
	    assert 1 != 1

	# 标记函数    
	@pytest.mark.medium
	def test_b():
	    assert 2 > 1
	    
# 标记函数 
@pytest.mark.low
def test_c():
    assert 1 == 1

使用命令行模式启用PyTest配合上-m参数,可以指定执行的函数

pytest -v -m "high or medium" test_api.py