Pytest tutorial for Python automated testing framework

愿你我相遇,皆有所获! 欢迎关注微信公众号:【伤心的辣条】 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!

Pytest

  • pytest is a very mature and full-featured Python testing framework with the following features:
  • Simple and flexible, easy to use
  • Support parameterization
  • It can support simple unit tests and complex functional tests, and can also be used to do selenium/appnium and other automated tests and interface automated tests (pytest+requests)
  • Pytest has many third-party plug-ins, and can be customized extensions, such as pytest-selenium (integrated selenium), pytest-html (perfect html test report generation), pytest-rerunfailures (repeated execution of failed cases), pytest-xdist (Multi-CPU distribution) etc.
  • Skip and xfail processing of test cases
  • Can be well integrated with jenkins
  • report framework----allure also supports pytest

Install Pytest

  • pip install -U pytest

Pytest use case design principles

The test class starts with Test and cannot have an init method

Functions starting with test_

Classes beginning with Test

All packages pakege must have __init__.py file

Assert using assert

Two ways to run Pytest

Code running in Pycharm

pytest.main(["test.py"])
  • Command line operation mode
pytest test.py
# 运行指定类下的指定方法
pytest 文件名::类名::方法名

Pytest parameter description

  • -v Description: You can output more detailed execution information of the use case, such as the file where the use case is located and the name of the use case, etc.

  • -s Description: Enter the tuning information in our use case, such as print information, etc.

  • -x: Use case with error, exit execution immediately, and output the result

  • -v: means to view detailed report content

  • -collect-only: Indicates that all the use cases to be executed are displayed

  • -lf: Only execute the use case that failed last time

  • -vv: Display detailed test results

  • -tb=no: Do ​​not display the error details of the use case failure

  • -tb=line: show the specific number of lines of code where the use case failed

  • -tb=short: display more detailed error information

  • -k "Keywords" Description: execute use cases that contain "keywords"

  • -q Description: Simplify the console output, you can see that the output information is different from the above result. There are two dots in the figure below instead of the pass result

  • -maxfail=num When the use case error reaches the specified number, stop the test

  • m Description: Execute specific test cases. Let's modify our use case again and add a new use case

# 如果要运行多个标识的话,用表达式,如下
pytest -m "slow or faster" test_1.py  运行有slow标识或 faster标识用例
pytest -m "slow and faster" test_1.py 运行有slow和faster标识的用例
pytest -m "slow and not faster" test_1.py 运行有slow和没有faster标识的用例

Note: "" (single quotation mark) cannot be followed by -m, only "" (double quotation mark) can be used, otherwise it will not be recognized

ini configuration file

  • Create pytest.ini file (fixed writing)
[pytest];固定写法

;变量名不能错
addopts=-vv -s ;多个参数中间空格
testpaths=../HC/huace ;多个目录中间空格
python_files=test*.py ;python文件前缀,可自定义
python_classes=huace ;指定类名
python_functions=test* ;指定方法名,可自定义

Skip test function

  • Skip test function: According to specific conditions, the identified test function is not executed
# -*- coding: utf-8 -*-

import pytest

class Test():
   def test(self):
       print("执行的是testcase的用例")

@pytest.mark.skipif(condition=1<2,reason="1不大于2,所以不执行")
class huace():
   def haha(self):
       print("执行的是haha方法里面的用例")

Pytest之fixture

  • Both unittest and nose support fixtures, but fixtures are more flexible to use in pytest. It's also a highlight of pytest
  • It can be understood as something similar to the front and back of setup and teardown. But much more powerful and flexible than them

fixtur passed in as a parameter

# -*- coding: utf-8 -*-

import pytest

@pytest.fixture()
def login():
   print('登录系统')

# 直接使用函数名做为参数传入
def test_01(login):
   print('测试用例一')

def test_02():
   print('测试用例2')

def test03():
   print('测试用例3')

operation result

  • Only tes_01 called login
  • Here comes the remaining question, what if I have 10 methods or more? Do I need to call the login method? Continue to look at the fixture parameters below
testcase.py::test_01 登录系统
测试用例一
PASSED
testcase.py::test_02 测试用例2
PASSED
testcase.py::test03 测试用例3
PASSED

fixture syntax

# scope有4个作用范围:function(不填则默认)、class、module、session
fixture(scope='function', params=None, autouse=False, ids=None, name=None)

Parameter Description

  • Scope: the scope, function" (default), "class", "module", "session" four

  • params: Optional parameter list, it will cause multiple parameters to call the fixture function and all tests use it.

  • autouse: Default: False, the fixture needs to be manually called by the use case; if it is True, all test cases in the scope will automatically call the fixture

  • ids: part of the params test ID. If not, it will be automatically generated from params.

  • name: Default: the name of the decorator. It is recommended to write a different name for fixtures of the same module.

  • The scope of the session: the entire test session, that is, from the beginning of pytest execution to the end of the test, the scope parameter controls the scope of the fixture: session>module>class>function

autouse

  • The parameter is set to False by default, you need to manually call the decorator
# -*- coding: utf-8 -*-

import pytest

# 当前就算定义了装饰器,也不会调用Login
@pytest.fixture()
def login():
   print("打开浏览器")

def test1():
   print("test1里的用例")

def test2():
   print("test2里的用例")

Calling method 1

# -*- coding: utf-8 -*-

import pytest

@pytest.fixture()
def login():
   print("打开浏览器")

# 直接传入函数名
def test1(login):
   print("test1里的用例")
   
def test2(login):
   print("test2里的用例")

Calling method 2

# -*- coding: utf-8 -*-

import pytest

# autouse设为True,就能自动调用login的装饰器
@pytest.fixture(autouse=True)
def login():
   print("打开浏览器")

# 直接传入函数名
def test1():
   print("test1里的用例")

def test2():
   print("test2里的用例")

function

  • function: The scope is a function
  • All methods call login
# -*- coding: utf-8 -*-

import pytest

@pytest.fixture(scope='function', autouse=True)
def login():
   print('登录系统')

def test_01():
   print('测试用例一')

def test_02():
   print('测试用例2')

def test03():
   print('测试用例3')

operation result

  • The decorator will be called if it matches the use case name design
  • login does not match so it will not be called
testcase.py::test_01 登录系统
测试用例一
PASSED
testcase.py::test_02 登录系统
测试用例2
PASSED
testcase.py::test03 登录系统
测试用例3
PASSED

class

  • class: Scope is class
  • So both TestCase1 and TestCase2 will execute login
# -*- coding: utf-8 -*-

# @Time : 2021/1/14 21:05
# @Author : 程序员一凡

import pytest

@pytest.fixture(scope='class', autouse=True)
def login():
   print('登录系统')


def test_01():
   print('这个是类外面的用例')

class TestCase1:
   def test_02(self):
       print('测试用例2')
   def test03(self):
       print('测试用例3')

class TestCase2:
   def test_04(self):
       print('测试用例4')
   def test05(self):
       print('测试用例5')

operation result

  • The method in the class will only be called once
  • pytest mechanism, because the method starts with test, it will also call
testcase.py::test_01 登录系统
这个是类外面的用例
PASSED
testcase.py::TestCase1::test_02 登录系统
测试用例2
PASSED
testcase.py::TestCase1::test03 测试用例3
PASSED
testcase.py::TestCase2::test_04 登录系统
测试用例4
PASSED
testcase.py::TestCase2::test05 测试用例5
PASSED

module

  • module: execute only once before the start of all use cases in the current .py script
  • As long as it meets the design requirements of the use case, both inside and outside the class will be called
# -*- coding: utf-8 -*-

import pytest

@pytest.fixture(scope='class', autouse=True)
def open():
   print("打开浏览器,并且打开百度首页")

def test_s1():
   print("用例1:搜索python-1")

class TestCase():
   def test_s2(self):
       print("用例2:搜索python-2")

   def test_s3(self):
       print("用例3:搜索python-3")

operation result

  • The use cases in the current file call the decorator
  • If the class name does not start with Test, try to see if the decorator will be called?
testcase.py::test_s1 打开浏览器,并且打开百度首页
用例1:搜索python-1
PASSED
testcase.py::TestCase::test_s2 打开浏览器,并且打开百度首页
用例2:搜索python-2
PASSED
testcase.py::TestCase::test_s3 用例3:搜索python-3
PASSED

session

  • Fixture is session level and can be called across .py modules

  • When we have multiple use cases of .py files, if multiple use cases only need to call the fixture once, then it can be set to scope="session" and written to the conftest.py file

  • The name of the conftest.py file is fixed, and pytest will automatically recognize the file. Put it in the root directory of the project, you can call it globally

  • If it is placed in a package, it will only be valid in that package

# -*- coding: utf-8 -*-

# conftest文件内容
import pytest

@pytest.fixture(scope="session", autouse=True)
def login():
   print("调用conftest文件的里的方法")

Two use case files

# -*- coding: utf-8 -*-
# testcase1.py 

import pytest

def test1():
   print("test1里的用例")

def test2():
   print("test2里的用例")
   
# -*- coding: utf-8 -*-
# testcase1.py  
import pytest
def test3():
   print("test3里的用例")

def test4():
   print("test4里的用例")

operation result

  • The use cases of the two files only testcase files have adjusted the methods in conftest
testcase.py::test1 调用conftest文件的里的方法
test1里的用例
PASSED
testcase.py::test2 test2里的用例
PASSED
testcase1.py::test3 test3里的用例
PASSED
testcase1.py::test4 test4里的用例
PASSED

pytest-allure generates test reports

  • Install the module: pip install allure-pytest
# 第一步:生成xml数据
pytest --alluredir=./report/xml testcase.py
# 第二步:生成html文件
allure generate --clean ./report/xml -o ./result/html

Add screenshots to the report

  • allure.attach(f,'picture name', allure.attachment_type.JPG)
# -*- coding: utf-8 -*-

from selenium import webdriver
import allure

browser=webdriver.Chrome()
browser.get("https://www.baidu.com")
try:
   browser.find_element_by_id("zhiyi").send_keys('test123456')  # 输入密码,
except Exception as e:
   file_name = './test.jpg'
   browser.save_screenshot(file_name)  # 截图函数
   '''allure添加截图附件'''
   with open(file_name, mode='rb') as file:
 **加粗样式**      # 读取文件,将读取的结果作为参数传给allure
       f = file.read()  
   # 把图片添加到allure操作步骤里
   allure.attach(f, 'login', allure.attachment_type.JPG)  
   raise e

The difference and similarities between yield and return in pytest

Common ground

  • Both return and yield can return values

the difference

  • After yield returns the value, the code behind will continue to run
  • After the return value is returned, the following code will not continue to run
# -*- coding: utf-8 -*-

import pytest

@pytest.fixture()
def openbrower():
   print("打开浏览器")
   yield "返回浏览器"
   print("关闭浏览器")

def test01(openbrower):
   print(openbrower)

operation result

  • Prove that the code behind yield is still executed
testcase.py::test01 打开浏览器
# 返回值
返回浏览器
PASSED关闭浏览器

The difference between usefixtures and passing fixtures

  • If the fixture has a return value, then usefixture cannot get the return value. This is the difference between the usefixture decorator and the fixture parameter directly passed by the use case.
  • When the fixture needs to use the return parameter, only the parameter name can be directly passed in as the parameter. When the return parameter is not needed, both methods can be used.
  • @pytest.mark.usefixtures("decorator name")

Commonly used plugins for Pytest

  • pytest-selenium   集成 selenium

  • pip install allure-pytest generates a beautiful allure test report

  • pip install pytest-sugar optimizes the running effect

  • pip install pytest-rerunfailures rerun after the execution of the use case fails

  • pip install pytest-xdist multi-threaded parallel and distributed execution

  • pip install pytest-assume multiple assertions are still executed after an error is reported

  • pip install pytest-cover test coverage

Install multiple modules with one click

  • Create a requirement.txt file
selenium==3.0
requests
  • pip install -r requirement.txt

Finally: test the welfare

In the technology industry, you must improve your technical skills and enrich your practical experience in automation projects. This will be very helpful for your career planning in the next few years and the depth of your testing technology.

In the interview season of the Golden 9th and the Silver 10th, the job-hopping season, organizing interview questions has become my habit for many years! The following is my collection and sorting in recent years, the whole is organized around [software testing], the main content includes: python automation test exclusive video, Python automation details, a full set of interview questions and other knowledge content.


For software testing friends, it should be the most comprehensive and complete interview preparation warehouse. In order to better organize each module, I also refer to many high-quality blog posts and projects on the Internet, and strive not to miss every knowledge point. Friends relied on these contents to review and got offers from big factories such as BATJ. This warehouse has also helped many learners of software testing, and I hope it can help you too!

May you and I meet and you will find something! Welcome to follow the WeChat public account: [Sad Spicy Article] Receive a 216-page software test engineer interview book for free. And the corresponding video learning tutorials are free to share!

Guess you like

Origin blog.csdn.net/weixin_50829653/article/details/112850488