pytest 教程

pytest

pytest是一个非常成熟的全功能的Python测试框架,主要特点有以下几点:

  1. 简单灵活,容易上手;
  2. 支持参数化;
  3. 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests);
  4. pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等;
  5. 测试用例的skip和xfail处理;
  6. 可以很好的和jenkins集成;
安装
  • 运行如下命令
    pip install -U pytest
  • 检查是否安装成功
    pytest --version
    # This is pytest version 4.5.0, imported from c:\python27\lib\site-packages\pytest.pyc
  • 查看帮助命令
    pytest -h
简单应用

创建一个test_class.py文件,输入以下代码:

    def test_add():
        x = 3
        y = 4
        assert x == y, "test failed because x=" + str(x) + " y=" + str(y)
    
    
    class TestClass(object):
        def test_one(self):
            x = "this"
            assert 'h' in x
    
        def three_test(self):
            x = "check"
            assert hasattr(x, 'check')
    
        def test_add(self):
            x = 3
            y = 4
            assert x == y, "test failed because x=" + str(x) + " y=" + str(y)

命令行进入到当前文件夹,运行以下命令:

  • pytest
  • py.test
  • python -m pytest

三个命令的作用一样,都是运行当前文件夹下的测试用例;还可以使用pytest.main()运行测试用例(当前文件夹内创建一个py文件,将该代码放入,直接运行该文件即可,此种方法和上边三种结果一样,只是以非命令行方式运行,还可以传递参数的方式运行: pytest.main(["-v", "-s"])pytest.main()会返回6种结果:

Exit code解释
0所有用例都被收集并且全部通过
1所有用例都被收集并且有失败的用例
2被用户暂停
3发生内部错误
4pytest命令行使用错误
5没有测试用例

你将会得到下边的输出:
在这里插入图片描述
在失败的部分你可以看到失败的方法和失败的行的信息

pytest识别测试文件和测试方法

默认下pytest只能识别以test_开头和_test结尾的.py文件,识别以test.开头的所有方法、类
查看有效无效的文件命名(tips:如果显式的运行testlogin.pylogintest.py还是可以的,pytest testlogin.py)

test_login.py - valid
login_test.py - valid
testlogin.py -invalid
logintest.py -invalid

查看有效无效的方法命名(tips:即使是显式的运行file1_method1()three_test(),也是不可以的)

def test_file1_method1(): - valid
def testfile1_method1(): - valid
def file1_method1(): - invalid	
def three_test(): - invaild
运行多个测试用例从单个文件和多个文件

如果当前文件夹下有多个文件,test_sample2.pytest_sample3.py 想要运行所有的测试用例,只需要运行命令:pytest就可以了
如果运行单个文件,则运行命令: pytest test_sample2.py

运行指定的测试用例

假如我们当前文件夹下有两个文件:

  • test_sample1.py
    • test_file1_answer1()
    • test_file1_answer2()
  • test_sample2.py
    • test_file2_answer1()
    • test_file2_answer2()

test_sample1.py内容:

def func(x):
    return x + 1


def test_file1_answer1():
    assert func(3) == 5


def test_file1_answer2():
    assert func(5) == 5
    

test_sample2.py内容:

 def func(x):
     return x + 1
         	
         	
 def test_file2_answer1():
     assert func(4) == 5
 
 
 def test_file2_answer2():
 	 assert func(6) == 5
  1. 运行测试用例通过子串匹配
    运行所有名字中含有的answer1的方法: py.test -k answer1 -v
    -k 用来匹配名字中包含表达式的方法
    -v 增加显示详细信息
    你将看到如下结果:
    在这里插入图片描述
    py.test -k method -v – 将会运行所有的方法(四个)
    py.test -k methods -v – 不会运行任何的方法

  2. 运行测试用例通过markers
    pytest允许为测试用例添加属性通过 pytest markers,@pytest.mark,定义方法: @pytest.mark.<name>
    更新代码test_sample1.py:

    import pytest
    
    
    def func(x):
        return x + 1
    
    
    @pytest.mark.case1
    def test_file1_answer1():
        assert func(3) == 5
    
    
    @pytest.mark.case2
    def test_file1_answer2():
        assert func(5) == 5
    

    更新代码test_sample2.py:

    import pytest
    
    
    def func(x):
        return x + 1
    
    
    @pytest.mark.case1
    def test_file2_answer1():
        assert func(4) == 5
    
    
    @pytest.mark.case1
    def test_file2_answer2():
        assert func(6) == 5
    

    运行通过marked的用例: py.test -m <name>
    -m 标记的名字
    py.test -m case1 将会运行test_file2_answer1()test_file2_answer2()test_file1_answer1()
    py.test -m case2 将会运行 test_file1_answer2()

参数化测试

参数化测试是用于一些测试流程一样,测试数据不同的测试用例,以此来简化代码。看下面的例子,传入两组测试数据。创建一个test_addtiton.py,写入以下代码:

   import pytest
    @pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
    def test_add(input1, input2, output):
    	assert input1+input2 == output,"failed"

运行 pytest -s -v test_addtiton.py,将得到跑了两个测试用例,结果如下:
在这里插入图片描述

Xfail / Skip 测试

总是有一些我们不想运行的测试,在这种场景,我们可以选择Xfail / Skip这些测试。Xfail标记的测试将会执行,但是不会被记入失败或成功中,如果失败了,也不会有任何追踪的信息,使用方法:@pytest.mark.xfail;Skip 则意味着直接跳过,不会执行,使用方法:@pytest.mark.skip
test_addtion.py代码修改如下

    import pytest
    
    
    @pytest.mark.skip
    def test_add_1():
        assert 100 + 200 == 400, "failed"
    
    
    @pytest.mark.skip
    def test_add_2():
        assert 100 + 200 == 300, "failed"
    
    
    @pytest.mark.xfail
    def test_add_3():
        assert 15 + 13 == 28, "failed"
    
    
    @pytest.mark.xfail
    def test_add_4():
        assert 15 + 13 == 100, "failed"
    
    
    def test_add_5():
        assert 3 + 2 == 5, "failed"
    
    
    def test_add_6():
        assert 3 + 2 == 6, "failed"

说明:

  • test_add_1 and test_add_2 直接被跳过.
  • test_add_3 and test_add_4 are xfailed. 将被执行xfailed(on test failure) or xpassed(on - test pass) tests. 失败时,没有失败信息.
  • test_add_5 and test_add_6 将被执行,test_add_6失败将会有失败的信息

运行pytest -s -v test_addtion.py,结果如下:

============================= test session starts =============================
platform win32 -- Python 2.7.15, pytest-4.5.0, py-1.8.0, pluggy-0.11.0 -- c:\python27\python.exe
cachedir: .pytest_cache
rootdir: C:\pytest, inifile: pytest.ini
collected 6 items                                                              

test_addtion.py::test_add_1 SKIPPED
test_addtion.py::test_add_2 SKIPPED
test_addtion.py::test_add_3 XPASS
test_addtion.py::test_add_4 XFAIL
test_addtion.py::test_add_5 PASSED
test_addtion.py::test_add_6 FAILED

================================== FAILURES ===================================
_________________________________ test_add_6 __________________________________

    def test_add_6():
>       assert 3 + 2 == 6, "failed"
E       AssertionError: failed
E       assert 5 == 6
E         -5
E         +6

test_addtion.py:36: AssertionError
===== 1 failed, 1 passed, 2 skipped, 1 xfailed, 1 xpassed in 0.14 seconds =====

并行运行测试

当测试用例比较多的时候,将会花费大量的时间来运行测试用例,因此pytest支持并行测试,来减少运行时间。想要并行运行,首先要安装插件pytest-xdist ,运行命令安装:
pip install pytest-xdist,然后直接运行pytest -n 4即可,-n <num> 表示运用多核,充分利用资源,上面的命令将会四个去运行测试用例。

生成HTML报告

想要HTML格式的报告首先安装插件:pip install pytest-html
运行命令:py.test -v -s --html=reportName.html
你将会在文件目录下生成reportName.html,用浏览器打开如下图(后续介绍Allure):
在这里插入图片描述

常用的命令参数
命令行解释
pytest --version显示版本信息
pytest --fixtures显示可用的内置函数
pytest -h | --help显示参数和配置的帮助信息
pytest --lf | --last-failed运行上一次运行失败的用例
pytest --ff | --failed-first先运行上一次失败的用例,然后运行其他的
pytest --last-failed --last-failed-no-failures all没有失败的默认运行所有的用例
pytest --last-failed --last-failed-no-failures none没有失败的不运行任何用例并退出
pytest --cache-show查看缓存内容
pytest --cache-clear运行前删除所有的缓存(一般不需要运行)
pytest -x | --exitfirst第一次失败后停止
pytest --maxfail=2第二(n)次失败后停止
pytest test_mod.py运行单个文件中的用例
pytest testing/运行文件夹下的用例
pytest -k "MyClass and not method"关键字表达式(文件名、类名、方法名)运行测试用例
(将运行TestMyClass.test_something 不运行TestMyClass.test_method_simple)
pytest test_mod.py::test_func运行模块内特指的方法
pytest test_mod.py::TestClass::test_method运行模块下类内特指的方法
pytest -m slowmarker运行测试用例(运行所有被装饰器标记@pytest.mark.slow的用例)
pytest --pyargs pkg.testing从包中运行测试用例(这将要导入import pkg.testing
pytest -ra运行测试用例(显示测试总的结果信息,输出信息的最后)
pytest -rp运行测试用例(显E示测试通过的结果信息,输出信息的最后)
pytest -rE运行测试用例(显示测试错误的结果信息,输出信息的最后)
pytest -rs运行测试用例(显示测试跳过的结果信息,输出信息的最后),也可以结合使用 -rfs – 显示跳过、失败的
pytest -v pytest1.py-v 用于显示每个测试函数的执行结果
pytest -q pytest1.py-q 只显示整体测试结果
pytest -s pytest1.py-s 用于显示测试函数中print()函数输出
pytest --durations=10获得最慢的10个测试持续时间表
pytest --junitxml=path生成一个结果集xml文件,可用于Jenkins 持续集成
pytest --pastebin=failed为每个失败的用例创建一个URL

参考:

扩展:

  • 10
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值