当前位置:网站首页>Basic use of pytest

Basic use of pytest

2022-07-06 11:52:00 mb61037a3723f67



Catalog





One : Pytest Installation :


pip install -U pytest -i https://pypi.tuna.tsinghua.edu.cn/simple


Two : pytest A simple case of :


  • Pytest Able to identify test The first method and Test Initial class .
  • Do not print by default , You need to specify print : pytest.main([’-s’])
  • If the class does not Test start , Methods in a class even with test It will not be executed at the beginning .

       
import pytest

def test_01():
print(" I am a test_01")

def test_02():
print(" I am a test_02")

class Test_demo(object):

def test_03(self):
print(" I am a test_03")

def test_04(self):
print(" I am a test_04")

class Tsts_demo(object):
def test_05(self):
print(" I am a test_05")


if __name__ == '__main__':
pytest.main(['-s'])
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

Running results :

Pytest Basic use of _python

3、 ... and : Assertion


  • The assertion is python Self contained , No unitest Medium .
  • Classification of assertions : assert Assertion , Exception assertion , Warning assertion .

1: assert Assertion :

  • When the assertion prediction fails , The remarks will be in AssertionError Throw out , And output on the console .
    Case study :
       
import pytest

def test_1():
num = 1 + 1
assert num == 2, 'num==2 Condition not satisfied '

def test_2():
num = 1 + 1
assert num == 3, 'num==3 Condition not satisfied '

if __name__ == '__main__':
pytest.main(['-s'])
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

Running results :

Pytest Basic use of _ Abnormal information _02

2: Exception assertion


  • If a specified exception occurs, pass , If there is an exception that is not specified, an error is reported .
  • pytest.raises( Expected exception class ,match = Abnormal matching information )
  • with pytest.raises(TypeError) as Variable : This variable stores all the information of the exception .
  • Variable .__dict__ Get all the attributes of the variable .

Case study :

First, a function of leap year is given as the function to be tested :

       
# A function of whether it is a leap year
def is_leap_year(year):
# First judge year Is it an integer
if isinstance(year, int) is not True:
raise TypeError(" The parameter passed in is not an integer ")
elif year == 0:
raise ValueError(" The first year of A.D. began in A.D !!")
elif abs(year) != year:
raise ValueError(" The parameter passed in is not a positive integer ")
elif (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print("%d Year is a leap year " % year)
return True
else:
print("%d Year is not a leap year " % year)
return False
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

test : The exception thrown is consistent with the specified

       
class TestAssert(object):

def test_01(self):

with pytest.raises(TypeError):
# You pass in a string , It will be thrown out. TypeError It's abnormal , however pytest.raises The designated is TypeError So the test passed .
is_leap_year('2020')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

Pytest Basic use of _ Abnormal information _03

test : The exception thrown is inconsistent with the exception tested .

       
class TestAssert(object):

def test_01(self):

with pytest.raises(TypeError):
# What's coming in is 0, It will be thrown out. ValueError It's abnormal , however pytest.raises Specifies the TypeError So the test failed , Throw an exception .
is_leap_year(0)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

Pytest Basic use of _ Abnormal information _04

test : Store exception information in variables .

       
class TestAssert(object):

def test_01(self):

with pytest.raises(TypeError) as err_info:
# What's coming in is 0, It will be thrown out. ValueError It's abnormal , however pytest.raises Specifies the TypeError So the test failed , Throw an exception .
is_leap_year('2000')
print(" The type of exception that occurs is :", err_info.type)
print(" All abnormal information :", err_info.__dict__)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Pytest Basic use of _ Abnormal information _05

test : Capture exception content through exception content .

There must be parameters in the matching exception information , And the type is TypeError.

       
class TestAssert(object):

def test_01(self):

with pytest.raises(TypeError, match=" Parameters ") as err_info:
# What's coming in is 0, It will be thrown out. ValueError It's abnormal , however pytest.raises Specifies the TypeError So the test failed , Throw an exception .
is_leap_year('2000')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

Pytest Basic use of _ The test case _06

3: Warning assertion


  • The biggest difference between warning assertions is that variables can store multiple warnings .
  • pytest.warns()

Active and standby work : Customize three warning throwing functions :

       
def make_warn():
# Throw a version update warning
warnings.warn("deprecated", DeprecationWarning)

def not_warn():
# Don't throw any warnings
pass

def user_warn():
# Throw a compatibility warning
warnings.warn("user warn", UserWarning)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

Test warning assertions :

       
class TestWarns(object):
# The test exception is consistent with your own definition
def test_01(self):
with pytest.warns(DeprecationWarning):
make_warn()

# The test exception is inconsistent with your own
def test_02(self):
with pytest.warns(DeprecationWarning):
user_warn()

# The test is normal
def test_03(self):
with pytest.warns(DeprecationWarning):
not_warn()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

test result :

Pytest Basic use of _ Abnormal information _07

Write warning information to variables :

       
class TestWarns(object):
# The test exception is consistent with your own definition
def test_01(self):
with pytest.warns((DeprecationWarning, UserWarning )) as record:
make_warn()
user_warn()

print(" The length of the variable storing exception information :", len(record))
print(" Store the first information of the exception information variable :", record[0].message)
print(" Store the first exception type of the exception information variable :", record[0].category)
print(" All attributes of exception information ", record.__dict__)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

test result :

Pytest Basic use of _ The test case _08

Capture information through warning content

       
class TestWarns(object):
# The test exception is consistent with your own definition
def test_01(self):
with pytest.warns((DeprecationWarning), "user") as record:
make_warn()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

result : Because there is no user, So wrong reporting .

Pytest Basic use of _ The test case _09

Four :setup and teardown function

  • Function level :setup_function() teardown_function()


Scope of action : Only for those outside the class test Function in action , Each is executed once .


  • Class level : setup_class() teardown_class() setup_method() teardown_method()


setup_class() teardown_class(): Execute only once for the current class .
setup_method() teardown_method(): For methods in the current class , Execute every time .


  • Module level :setup_model() teardown_model()


Only execute the start and end of the current file once .


Case study : Verify function level

       
import pytest

def test_01():
print(" I'm a normal function 01")
def test_02():
print(" I'm a normal function 02")

def setup_function():
print(" I am the preposition function of ordinary function ")

def teardown_function():
print(" I am the post function of ordinary function ")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

Pytest Basic use of _python_10

Case study : Verify class level

       
import pytest

class Test_Demo(object):

def test_01(self):
print(" I am a function in class 01")

def test_02(self):
print(" I am a function in class 02")
@classmethod
def setup_class(self):
print(" I am a class pre function ")
@classmethod
def teardown_class(self):
print(" I am a class post function ")

def setup_method(self):
print(" I am the method preposition function in the class ")

def teardown_method(self):
print(" I am a method postposition function in class ")


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

Pytest Basic use of _python_11

Case study : Verify module level :

       
import pytest

def setup_module():
print(" I am a module pre function ")

def test_01():
print(" I'm a test function ")

def teardown_module():
print(" I am a module post function ")


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

Pytest Basic use of _python_12

5、 ... and :pytest.fixture Use

1: fixture Simple use :

Decorate it on ordinary functions , The name of the ordinary function passed in the test function , The name of ordinary function can be used inside the test function , Represents the return value of ordinary functions .

Case study : Be careful : Run the tested function before running it fixture Functions of decoration .

       
import pytest

@pytest.fixture()
def get_url():
print(" I'm just an ordinary function ")
return "http://www.baidu.com"


def test_web(get_url):
print(" Running test function ")
print(" Print get_url The return value of :", get_url)


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

Pytest Basic use of _python_13

2:conftest.py The use of documents

( The inside of this module is fixture Decorative functions can be used directly )


  • If the use case is used in multiple test files in the test The same fixture function , You can move it to conftest.py In file , The required fixture The object will be automatically pytest Find out , Instead of importing every time .
  • conftest.py Fixed file name
  • stay conftest.py File to achieve common fixture function

Case study :

1: newly build conftest.py: It defines a person who is @pytest.fixture() Decorate the function that only returns Baidu address .

       
import pytest

@pytest.fixture()
def get_baidu_url():
return "www.baidu.com"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

2: Another file can be used directly without importing packages conftest Function name in .

       
import pytest

def test_01_demo(get_baidu_url):
print(get_baidu_url)


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

3: Running results :

Pytest Basic use of _python_14

3:@pytest.mark.usefixtures decorate

effect : If I don't want to use the return value of the decorated function , But you need to call the decorated function before the function is executed , Then you can use ​​@pytest.mark.usefixtures(' Decorated function name ')​​ To deal with it .

Case study :

       
import pytest

@pytest.fixture()
def return_url():
print(" I'm Baidu address : www.baidu.com")
return "www.baidu.com"

@pytest.mark.usefixtures('return_url')
def test_demo():
print(" I'm a test function ")

if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Pytest Basic use of _python_15

6、 ... and :fixture Parameters

1: scope Parameters : Specify the marked function ( Method ) Scope of action


  • function : Each test case should be executed once .( Default )
  • class: Act on the whole class , Each class executes only once .
  • module : Scope the whole module ( file ), Each module is executed only once .
  • session : Scope the entire project , Each project is executed only once .

test function:

       
import pytest

@pytest.fixture(scope='function')
def foo():
print(" I am being fixture Modified function ")
return " Hello, hello ......."

def test_01(foo):
print(" I am a general test 01:")
print(foo)

def test_02(foo):
print(" I am a general test 02")
print(foo)

class Test_demo(object):
def test_03(self, foo):
print(" I am the test case in the class 03: ")
print(foo)

def test_04(self, foo):
print(" I am the test case in the class 04: ")
print(foo)

if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

Pytest Basic use of _python_16

test :class

Modify the code just now : become class, Running results : Be careful : Non class test cases or every test case should be called .

Pytest Basic use of _python_17

test : module:

Pytest Basic use of _python_18

2: params Parameters


  • params Parameters of the receiving list Parameters of type .
  • about param Each of these values ,fixture Functions will be traversed and executed once
  • Accordingly, it will be driven and used every time fixture The test function of the function executes once .
    test

       
import pytest

@pytest.fixture(params=['renshanwen', '15', '[email protected]'])
def username(request):
print(" I am being fixture Modified function ")
return request.param

def test_demo(username):
print(" I'm a test case ")
print(username)

if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Running results :

Pytest Basic use of _python_19

Because there are three decorators in the list , So the test case will be executed three times , Will call the decorated function three times .

3:autouse Parameters


  • pytest.fixture(autouse=False) Of autouse The parameter defaults to False, It doesn't automatically execute .
  • Set to True when , All currently running test functions will be executed before running fixture function .

demonstration :

       
import pytest


@pytest.fixture(autouse=True)
def before():
print(' No matter who you are , Call me first ')

def test_1():
print("test_1")

class Test2:
def test_2(self):
print('test_2')

def test_3(self):
print('test_3')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

Pytest Basic use of _ The test case _20

7、 ... and :mark Mark

1: pytest.mark.xfail()

1: Mark the test function as expected failure .

       
import pytest

@pytest.mark.xfail(reason = " Incomplete function ")
def test_1_demo():
print(" I'm just a decorated one ")

if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

Running results :

Pytest Basic use of _ The test case _21

2:pytest.mark.skip()

1: Unconditionally skip test cases :

       
import pytest

@pytest.mark.skip(reason = " Skip execution ")
def test_1_demo():
print(" I'm just a decorated one ")

if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

Pytest Basic use of _ The test case _22

3:pytest.mark.skipif()

1: Conditionally skip test functions .

       
import pytest

@pytest.mark.skipif(condition= True, reason = " skip ")
def test_1_demo():
print(" I'm just a decorated one 111111111111111")

@pytest.mark.skipif(condition= False, reason = " Don't skip ")
def test_2_demo():
print(" I'm just a decorated one 222222222222222")


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

2: Running results :

Pytest Basic use of _ Abnormal information _23

4: pytest.mark.parametrize()

Purpose : A parameterized Fixture Methods and test functions

       
import pytest

@pytest.mark.parametrize(['username', 'password'], [('renshanwen', '12345678'), ('niuniu', '87654321')])
def test_login(username, password):
print("\n")
print("username yes :", username)
print("password yes :", password)


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

Running results :

Pytest Basic use of _ Abnormal information _24

8、 ... and : The configuration file


  • Configuration file name , pytest.ini Fix .
  • The comments in the configuration file are ​​;​
  • addopts = -s test_20.py : Specify the command to run
  • testpaths = ./ : Specify the path of the test file
  • python_files = test*.py : Identify with test Opening file
  • python_classes = Test* : Identify with Test Initial class
  • python_functions = mike* : Identify with test Initial function
    Case study :

       
[pytest]
addopts = -s test_12.py test_13.py
testpaths = ./
python_files = test_*.py
python_classes = Test_*
python_functions = test_*
; stay ini The comment statement in the file starts with a semicolon , All comment statements, no matter how long, are exclusive until the end
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

Nine : Common plug-ins

1: Plug in installation


workon test_v7 # Enter the virtual environment
pip install pytest-html # Generate test reports
pip install pytest-ordering # Control the execution order of functions
pip install pytest-rerunfailures # Failure to retry


2: Generate test reports

1: Test code :

       
import pytest

def test_01():
print(" Test successful test cases ")
assert True

def test_02():
print(" Test cases that fail ")
assert False


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

2: Carry out orders :


pytest -s test17_port.py --html=./report.html


3: Report display :

Pytest Basic use of _ Abnormal information _25

3: Control the execution sequence of test cases

       
import pytest

@pytest.mark.run(order= 3)
def test_01():
print(" I am test case one ")


@pytest.mark.run(order=1)
def test_02():
print(" I am test case two ")


@pytest.mark.run(order=2)
def test_03():
print(" I am test case three ")

if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

Running results :

Pytest Basic use of _ Abnormal information _26

4: Failure to retry

1: Code :

       
import pytest

def test_01():
print(" Test successful test cases ")
assert True

def test_02():
print(" Test cases that fail ")
assert False


if __name__ == '__main__':
pytest.main()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

2: Carry out orders :


pytest -s test17_port.py --reruns 2


3: Running results :

Pytest Basic use of _python_27

5: Cancel plug-in


  • -p no:ordering : Unsort
  • -p no:html : Cancel generating test report
  • -p no:rerunfailures : Cancellation failed. Try again

Ten : Yaml

1:Yaml Grammatical rules


  • Case sensitive .
  • Use indentation to indicate hierarchy .
  • Indentation is not allowed tab key , Only Spaces are allowed .
  • The number of Spaces indented is not important , As long as the elements of the same level are aligned to the left .


Yaml Online editor address : http://old.qqe2.com/jsontool/yaml.php


2:Yaml The use of data structures

1: Yaml And python Transformation :

Be careful :Yaml The space after the colon of an object cannot be omitted .

Pytest Basic use of _python_28

2: Yaml In the array :

Pytest Basic use of _ Abnormal information _29

3: Yaml Anchors and references in :

Pytest Basic use of _ Abnormal information _30

3: Python Read Yaml File and write Yaml file

1: install PyYaml library :


pip3 install -U PyYAML


2: Read Yaml file :

Prepare test files test.yaml

       
Search_Data:
search_test_001:
value: 456
expect: [4,5,6]
search_test_002:
value: " Hello "
expect: {"value":" Hello "}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

yaml.read.py File read test.yaml Data in :

       
import yaml

with open("./test.yaml", "r") as f:
data = yaml.load(f, Loader=yaml.FullLoader)
print(data
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

Running results :

Pytest Basic use of _ The test case _31

3: Write content to Yaml file

1: yaml_write.py To write

       
import yaml
data={'Search_Data': {
'search_test_002': {'expect': {'value': ' Hello '}, 'value': ' Hello '},
'search_test_001': {'expect': [4, 5, 6], 'value': 456}
}
}
# To set the encoding format , Otherwise, there will be Chinese code disorder
with open('./yaml_hello.yaml', 'w', encoding='utf-8') as f:
yaml.dump(data, f,allow_unicode=True)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

2: Execution results :

Pytest Basic use of _ Abnormal information _32



原网站

版权声明
本文为[mb61037a3723f67]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202131611249998.html