pytest测试框架(二)


# !/usr/bin/env python
# -*- coding:utf-8 -*-

import pytest
'''
在单元测试的组件中,主要分为测试?例,测试固件,测试套件,测试执?以及测试报告
装饰器@pytest.fixture(),它是声明?个函数是fixture
如果测试函数的参数列表中包含了fixture,pytest执?时会检测到,并且在测试函数运?前执?该fixture
fixture可以完成任务,也可以返回数给测试函数
'''

@pytest.fixture()
def login(username='admin', password='admin'):
    if username == 'admin' and password == 'admin':
        return True
        # 返回值
    else:
        print('账户或密码错误')


def test_profile(login):
    # 测试函数test_profile的形式参数是login,同时该形式参数是fixture函数对象
    assert login == True


from selenium import webdriver


@pytest.fixture()
def driver():
    return webdriver.Chrome()


def test_baidu_title(driver):
    driver.get('https://www.baidu.com')
    assert driver.title == '百度一下,你就知道'


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

# !/usr/bin/env python
# -*- coding:utf-8 -*-

from selenium import webdriver
'''
selenium在Python中是插件需要导入
如果导入这个库,在执行时不需要--driver Chrome
没有导入selenium,就需要加上--driver Chrome
'''
import pytest
import time as t


@pytest.fixture()
def driver():
    return webdriver.Chrome()


@pytest.fixture()
def init(driver):
    # UI自动化固件测试
    driver.maximize_window()
    driver.get('https://www.baidu.com')
    yield
    # 测试步骤和断言
    driver.close()


def test_baidu_title(driver):
    assert driver.title == '百度一下,你就知道'


def test_baidu_so(driver):
    so = driver.find_element_by_id('kw')
    so.send_keys('admin')
    t.sleep(3)
    assert so.get_attribute('value') == 'admin'


'''
class TestBaidu(object):
    @pytest.fixture()
    def driver(self):
        return webdriver.Chrome()

    @pytest.fixture()
    def init(self, driver):
        # UI自动化固件测试
        driver.maximize_window()
        driver.get('https://www.baidu.com')
        yield
        # 测试步骤和断言
        driver.close()

    def test_baidu_title(self, init, driver):
        assert driver.title == '百度一下,你就知道'

    def test_baidu_so(self, init, driver):
        so = driver.find_element_by_id('kw')
        so.send_keys('admin')
        t.sleep(3)
        assert so.get_attribute('value') == 'admin'
'''

if __name__ == '__main__':
    pytest.main(["-v", "-s", "test_fixture_init.py"])
# !/usr/bin/env python
# -*- coding:utf-8 -*-

import pytest
import time as t


@pytest.fixture()
def init(selenium):
    # 自动化固件测试,打浏览器对应网页
    selenium.maximize_window()
    selenium.get('https://www.baidu.com')
    yield # 测试步骤和断言
    selenium.close()


def test_baidu_title(selenium):
    assert selenium.title == '百度一下,你就知道'


def test_baidu_so(selenium):
    so = selenium.find_element_by_id('kw')
    so.send_keys('admin')
    t.sleep(3)
    assert so.get_attribute('value') == 'admin'


if __name__ == '__main__':
    pytest.main(["-v", "-s", "--driver","Chrome","test_fixture_init.py"])
# !/usr/bin/env python
# -*- coding:utf-8 -*-

import pytest
from selenium import webdriver


@pytest.fixture()
def driver():
    return webdriver.Chrome()


@pytest.fixture()
def init(driver):
    driver.maximize_window()
    driver.get('https://file.qq.com/')
    yield
    driver.close()


'''
通过conftest.py可以共享fixture,可以解决测试固件的案例应?,依据它可编写多个案例
conftest.py是?个Python模块的?件,但是它是无法导?,必须在对应工程根目录下

在Conftest.py?件中主要使?scope的参数来控制fixture执?配置和销毁逻辑
Session:会话级别:针对?个项?中所有的模块,类,以及测试函数
Module:模块级别,主要是针对?个模块的范围
Class:针对类级别,主要是针对?个类的范围
Function:函数级别,主要是针对?个函数的
'''
#! /usr/bin/env pytho
# -*- coding:utf-8 -*-

import pytest
import time as t

def test_file_qq_001(init, driver):
    '''登录验证:校验点击注册跳转到注册的页面'''
    t.sleep(2)
    driver.switch_to.frame('login_frame1')
    driver.switch_to.frame('ptlogin_iframe')
    nowHandler = driver.current_window_handle
    driver.find_element_by_link_text('注册新帐号').click()
    allHandlers = driver.window_handles
    for handler in allHandlers:
        if nowHandler != handler:
            driver.switch_to.window(handler)
            t.sleep(2)
            assert driver.title == 'QQ注册'


def test_file_qq_002(init, driver):
    t.sleep(3)
    driver.switch_to.frame('login_frame1')
    driver.switch_to.frame('ptlogin_iframe')
    driver.find_element_by_link_text('帐号密码登录').click()
    t.sleep(1)
    username = driver.find_element_by_xpath('//*[@id="uin_tips"]')
    assert username.text == '支持QQ号/邮箱/手机号登录'


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

除conftest.py,还可以使用pytest.ini,它是Pytest测试框架的主配置文件可以改变Pytest默认行为

[pytest]
#指定执行时候的默认信息
addopts = -v -s

#注册标记
markers =
    login:执行标记为login的测试函数
    register:执行标记为register的测试函数
    logout:执行标记为logout的测试函数

#指定Pytest的最低版本号
minversion = 3.0

#指定忽略执行的目录
norecursedirs = .pytest_cache

#指定测试目录
testpaths = tests

#指定测试模块搜索的规则
python_files = test_*

#指定测试类搜索的规则
python_classes = Test*

#指定测试函数搜索规则
python_functions = test_*

;配置文件编码为GBK;与操作系统编码一致

Pytest-sugar 在执?的时候显示进度条,即使有失败的也会?刻显示

安装命令:ip3 install pytest-sugar

Pytest-html 在执?后?成给予html的测试报告,会在当前?录下?成 ?个report.html的?件

安装它的命令为:pip3 install pytest-html

命令:pytest -v -s --html=report.html 在当前目录下生成一个测试用例

  python -m pytest tests/ --html=report/index.html 会生成一个测试报告放在report下

Pytest-rerunfailures 对执?失败的再次执?

安装的命令为:pip3 install pytest-rerunfailures

--reruns --N N就是重试的次数

pytest -v -s --reruns N --html=report.html

Allure测试报告

安装库:pip3 install allure-pytest

第一种使用方法

(1)在命令控制台进入工程,输入:

(2)python -m pytest tests --alluredir=report/result ——> result下生成json的文件

(3)python -m pytest tests --alluredir=report/result ——> report下生成html的目录和html的测试报告

(4)allure serve report/result ——> 启动allure的服务,打开测试报告

第二种使用方法

在代码中以主函数形式调用

# !/usr/bin/env python
# -*- coding:utf-8 -*-

import pytest
import subprocess


def add(a, b):
    return a + b


def test_add_001():
    assert add(1, 2) == 2


def test_add_002():
    assert add('h', 'i') == 'hi'


def test_add_003():
    assert 2 == 3


def add_004():
    assert 2 == 3


class TestLogin(object):
    def test_login_001(self):
        pass

    def test_login_002(self):
        pass


# if __name__ == '__main__':
#     pytest.main(["-v", "-s", "test_add.py::TestLogin::test_login_002"])

if __name__ == '__main__':
    pytest.main(["-s", "-v", "test_add.py", "--alluredir", "./report/result"])
    subprocess.call('allure generate report/result/ -o report/html --clean', shell=True)
    subprocess.call('allure open -h 127.0.0.1 -p  8088 ./report/html', shell=True)

在python的单元测试框架unittest中,使?到的覆盖率?具是coverage

它属于第三?的库,安装的命令为:pip3 install coverage