Advanced advanced testing project, summary of Pytest automated testing framework (3)


foreword

1. Two ways of writing pytest preconditions + postconditions

Use the yield keyword to implement:
it is recommended to use this, because the yield keyword can return the value of the function

import pytest
@pytest.fixture()
def befor_func():
    print('xxxxxxxxxxxxx测试用例的初始化xxxxxxxxxxxxxxxx')
    yield 10                            #yield后面跟的是测试用例的后置条件,支持用例执行后就执行yield里的内容
    print('zzzzzzzzzzzzzzzzzz测试用例的清除zzzzzzzzzzzzzz')

def test_001(befor_func):
    print("测试用例001")
    res=befor_func
    print(res)

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

Use the finc() function to achieve:
this kind of return value cannot be returned

import pytest
@pytest.fixture()
def befor_func(request):
    print('xxxxxxxxxxxxx测试用例的初始化xxxxxxxxxxxxxxxx')
    def fin():                        #尾部这是后置条件,测试用例执行后就会调用这个函数      
        print('zzzzzzzzzzzz测试用例的清除zzzzzzzzzzz')

    request.addfinalizer(fin)               #回调,当我整个包运行完了后回调fin这个方法          
def test_001(befor_func):
    print("测试用例001")

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

2. pytest data-driven (parameterized)

The meaning of pytest data-driven:
parameterization (4 login use cases, each account password is different, use the framework to execute all 4 use cases, do not need for loop traversal execution, use data-driven scheme to do it)

pytest's built-in decorator @pytest.mark.parametrize can parameterize the test data and manage the test data separately, similar to the role of ddt data drive, which facilitates the separation of code and test data

@pytest.mark.parametrize("a",[1,2,3]):        # 参数化传一组参数  

@pytest.mark.parametrize("a,b", [(1,2),(3,4),(5,6)])    #  参数化传多组参数

Login account password (different use case combinations of name and psw, how to do dozens of use cases for one interface - dozens of sets of data - different parameters passed (what request method is the same as all kinds)

The name and psw can be parameterized by taking multiple sets of data respectively, the data is separated, and one interface is run 4 times, each time with different parameters)

import pytest
    #[(1,2),(3,4),(5,6)]   [1,2,3]
    class Test_login():  
        def setup_class(self):
            print("执行测试类之前,我需要执行操作")

        @pytest.mark.parametrize("a",[1,2,3])            #("变量名",[1,2,3]),数据需要封装成一个列表,多个数据需要封装成列表嵌套元组   ----数据驱动
        def test_login01(self,a):                  #数据驱动,一定要把变量名a引入引来,不然无法参数化
            print("---test_login01----")
            assert 1 + 1 == a

        @pytest.mark.parametrize("a,b", [(1,2),(3,4),(5,6)])    #数据驱动传多组参数
        def test_login02(self,a,b):
             print("---test_login02----")
             assert a + 1 == b

        def teardown_class(self):
            print("------该测试类的环境清除-----")

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

3. pytest combined with allure report operation

The report framework pytest-html that comes with pytest;
allure environment construction (allure is a report library not exclusive to python, a very comprehensive framework) -allure report is beautiful;

Download allure.zip (compressed package);
unzip allure.zip to a file directory;
add the allure-2.13.3\bin path to the environment variable path;
pip install allure-pytest -------allure report itself is not very Beautiful, through the allure-pytest library, you can customize the report to make the report beautiful;
verify (cmd input allure);

Allure and pytest joint execution report generation: run two statements

Execute the pytest unit test, and the data required by the generated allure report exists in the /tmp directory

pytest -sq --alluredir=../report/tmp   #pytest把allure报告的生成的中间文件放到一个临时文件里面(pytets生成报告,需要数据,所以先把数据存起来)

All reports need data support, the data comes from the pytest framework itself, and the result data is stored in a file in the .../report/tmp folder;
tmp temporary files, generally in json format;

Execute commands to generate test reports

allure generate ../report/tmp -o ../report/report -clean     #allure指令生成对应报告

allure simulation code

import pytest
import os
class Test_login():  
	def setup_class(self):
		print("执行测试类之前,我需要执行操作")

	@pytest.mark.parametrize("a",[1,2,3])
	def test_login01(self,a):  
		print("---test_login01----")
		assert 1 + 1 == a

	@pytest.mark.parametrize("a,b", [(1,2),(3,4),(5,6)])
	def test_login02(self,a,b):
		 print("---test_login02----")
		 assert a + 1 == b

	def teardown_class(self):
		print("------该测试类的环境清除-----")

if __name__ == '__main__':
					#需要打印对应的信息,需要在列表里面加-s
					#1:--alluredir ---生成临时文件,测试用例的结果数据放到目录   --alluredir   存放目录
	pytest.main(["test_func01.py","-s","--alluredir","../report/tmp"])  #框架自己调用函数
					#通过--alluredir把allure需要的数据存到../report/tmp这个路径下面
					#../--所在路径的父级别目录是test_case的目录隔壁邻居report文件下tmp,专门放alluer报告生成的需要的数据源

					# 2:临时数据没有报告的,allure generate allure才会生成报告   -----allure生成器生成allure报告--generate allure生成器,cmd指令
					#需要os模块os.system()调用指令可以在local的cmd里面敲
	os.system("allure generate ../report/tmp -o ../report/report --clean")
					#os.system("allure generate 报告需要的数据 -o 报告存放目录 --clean")
					#-o生成
					#allure generate生成报告指令,把../report/tmp 的文件-o生成报告out out一下,生成的报告放在../report/report
				#--clean把上次报告清除一下用--clean                 #allure报告生成的是一个服务,(本地服务)和jinkins结合,放在整个里面去集成,放到公共服务器里面

Optimization of allure reports

import pytest
import os
import allure       
@allure.feature("登录模块")                                                      #一级标题,大模块标题(类标签)
class Test_login():                                                              
	def setup_class(self):                                                                  
		print("执行测试类之前,我需要执行操作")

	@allure.story("登录login01")                                                  # 二级标签(每个接口的标签)
	@allure.title("login01")                                                     # 标题,每个用例带个标题(报告体现在每个测试用例)(一个接口有几个用例,title用例的标签)
	@pytest.mark.parametrize("a",[1,2,3])                                      
	def test_login01(self,a):                                                      
		print("---test_login01----")
		assert 1 + 1 == a

	@allure.story("登录login02")                                                  # 二级标签,定制allure报告层级
	@allure.title("login02")                                                     #标题,每个用例带个标题(报告体现在每个测试用例)
	@pytest.mark.parametrize("a,b", [(1,2),(3,4),(5,6)])                      
	def test_login02(self,a,b):
		 print("---test_login02----")
		 assert a + 1 == b

	def teardown_class(self):                                               
		print("------该测试类的环境清除-----")


@allure.feature("购物模块")
class Test_Shopping():
	@allure.story("shopping")
	@allure.title("shopping01")
	@pytest.mark.parametrize("a,b", [(1, 2), (3, 4), (5, 6)])
	def test_shopping(self, a, b):
		print("---test_login02----")
		assert a + 1 == b
if __name__ == '__main__':
	pytest.main(["test_func01.py","-s","--alluredir","../report/tmp"])    
	os.system("allure generate ../report/tmp -o ../report/report --clean")
	#allure报告生成的是一个服务,(本地服务)和jinkins结合,放在整个里面去集成,放到公共服务器里面

Other knowledge points:
test cases are generally written in excel table files, and the data is separated (just maintain the excel);
pytest-send emails from beginning to end to report execution;
dictionary is a storage type, json is a format (completely different) ;

4. pytest parameter analysis

pytest.main([‘test_boss.py’,‘-s’,‘-k test_modify_psw’,‘–alluredir=tmp/my_allure_results’])

Description:
test_boss.py: specifies the test case file;
-s: displays the print statement;
-k test_modify_psw: specifies a test case;
-n: indicates that two processes are used to start the test script

Generate a report cache file: –alluredir=tmp/my_allure_results
os.system('allure serve tmp/my_allure_results'): Open the test report, the command line needs to call the os module of python

5. Initialization and clearing of pytest

import pytest
#假设启动被测app的时候需要去填写配置项信息,每个的端口号不同,多终端需要两个appim server
#这时候setup_module和teardown_module不能传参,搞不定,需要换一种方法做测试用例的初始化和清除,

				#setup_module以模块为作用域,不写module以测试用例(测试函数)为作用域
# def setup_module():    #测试用例之前执行,原始的setup和teardown有个缺陷,里面不能传参数,
#                      #默认test级别,每个测试用例执行的时候都会执行一次,希望当前某个模块执行的时候只执行一次(不管里面用例执行多少次)
#                      #setup初始化和tear_down升个级,升级成module模块级别的
#     print("启动被测app")
#     print('连接appium服务')
#
# def teardown_module():
#     print('关闭被测app')
#     print('断开appium服务')

#定义个函数,名字随便取  使用@pytest.fixture装饰器把这个函数装饰成初始化清除函数
@pytest.fixture(scope='module')    #作用域默认test,初始化,加装饰器,初始化清除函数,autouse=True(自动执行)这种方法不建议使用                               #
def before_test():                   #初始化函数升级作用域到module模块级别
	print("启动被测app")
	print('连接appium服务')
	yield   #后面写清除动作,
	after_test()

#清除函数,清除函数并不会直接被初始化函数使用,我们必须放在初始化函数yiled后面才能回被调用
def after_test():
	print('关闭被测app')
	print('断开appium服务')
#目前一共有两个port,需要测试两个手机,两个多终端,before_test需要装饰器标记

#测试用例的参数化
@pytest.mark.usefixtures('before_test')                        #这表示调用某个自定义的初始化函数,括号里面的字符串写被调用函数的名字
@pytest.mark.parametrize('psw',['boss123','boss456'])
def test_app(psw):                        #测试用例,可能涉及到其他参数,比如需要一些配置信息,测试用例涉及到参数,                              #多组参数需要使用装饰器pytest.mark.parametrize(数据驱动),psw传参和形参名字对应的
	print('测试boss app')
	print(f'登录测试账号{
      
      psw}')

if __name__ == '__main__':
	pytest.main(['pytest_ywt.py','-s'])
The following is the most complete software test engineer learning knowledge architecture system diagram in 2023 that I compiled

1. From entry to mastery of Python programming

Please add a picture description

2. Interface automation project actual combat

Please add a picture description

3. Actual Combat of Web Automation Project

Please add a picture description

4. Actual Combat of App Automation Project

Please add a picture description

5. Resume of first-tier manufacturers

Please add a picture description

6. Test and develop DevOps system

Please add a picture description

7. Commonly used automated testing tools

Please add a picture description

Eight, JMeter performance test

Please add a picture description

9. Summary (little surprise at the end)

Steel is made through hard work, and brilliance is made with passion. Struggle is the journey of chasing dreams, and every effort is laying a solid foundation for success. Never give up, go forward bravely, water the flowers of hope with sweat, and you will eventually bloom your own brilliant life.

Life is like a blooming flower, only through the baptism of wind and rain can it bloom with dazzling beauty. Stick to your dreams, chase them bravely, and keep struggling, and you will eventually achieve brilliant achievements, because hard work is the key to changing your destiny.

Life is like a star in the sky, only with persistent efforts can it shine brightly. Not afraid of difficulties and difficulties, perseveringly pursuing dreams, the power of struggle will lead you to surpass yourself and sail to the other side of glory. Believe in yourself, go forward bravely, and success will surely belong to you.

Guess you like

Origin blog.csdn.net/m0_70102063/article/details/132007357