• pytest:开始使用


    最近一阶段有些懈怠了,导致文章没怎么更新,最近想把pytest+allure整理出一个合集文章。也更能方便资料的查询。

    安装pytest

    [ 安装pytest需要:python3.7+ 或者python3 ]

    在cmd中运行以下命令:

     pip install -U pytest # -U 是更新的意思
    
    • 1

    检查pytest是否安装成功:

    C:\Users>pytest --version
    
    pytest 7.1.2
    
    • 1
    • 2
    • 3

    第一个测试用例

    新建一个.py文件,并创建一个函数和一个测试:

    def function(x: int):
        return x + 1
    
    
    def test_function():
        assert function(5) == 5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    运行结果:

    ============================= test session starts =============================
    collecting ... collected 1 item
    
    sample_test.py::test_function FAILED                                     [100%]
    sample_test.py:12 (test_function)
    6 != 5
    
    Expected :5
    Actual   :6
    <Click to see difference>
    
    def test_function():
    >       assert function(5) == 5
    E       assert 6 == 5
    E        +  where 6 = function(5)
    
    sample_test.py:14: AssertionError
    
    
    ============================== 1 failed in 0.07s ==============================
    
    Process finished with exit code 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    [100%]是所有用例运行的总进度,FAILED是运行失败了吗,pytest会显示出具体失败原因,失败的原因是因为function(5)返回的不是5,和实际结果5不等于。

    运行多个测试

    pytest将在当前目录及其子目录中运行以 test_*.py 开头 或 *_test.py 结尾形式的所有.py文件。更一般地说,它遵循标准是测试发现规则。

    断言引发预期异常

    使用raises断言某些代码引发了的预期异常:

    import pytest
    
    
    def raise_func():
        raise SystemExit()
    
    
    def test_function():
        with pytest.raises(SystemExit):
            raise_func()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果

    PS E:\git_code\python-code\pytestProject\cases> pytest -q .\sample_test.py
    .                                                                                                                                                                                                        [100%]
    1 passed in 0.01s
    
    • 1
    • 2
    • 3

    如果预期异常满足SystemExit()就会安静执行。-q 则是以 .的形式显示运行是否通过(就是以简短形式运行并输出)。

    类中进行多个测试

    更多的时候我们希望一些测试用例放置在一组内。pytest也是可以创建一个包含多个测试的类:

    class TestSample:
    
        def test_sample_one(self):
            x = "one"
            assert "o" in x
    
        def test_sample_two(self):
            x = "hello"
            assert hasattr(x, "check")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    pytest根据 python 测试发现的约定发现所有测试,因此它会找到两个test_开头的测试函数。不需要进行初始化,只要确保在您的类前面加上Test前缀,否则该类将被跳过(hasattr用于判断对象是否包含对应的属性)。

    ============================= test session starts =============================
    collecting ... collected 2 items
    
    sample_class_test.py::TestSample::test_sample_one 
    sample_class_test.py::TestSample::test_sample_two PASSED                 [ 50%]FAILED                 [100%]
    sample_class_test.py:17 (TestSample.test_sample_two)
    self = <sample_class_test.TestSample object at 0x0000016B9D19FEB0>
    
        def test_sample_two(self):
            x = "hello"
    >       assert hasattr(x, "check")
    E       AssertionError: assert False
    E        +  where False = hasattr('hello', 'check')
    
    sample_class_test.py:20: AssertionError
    
    
    
    
    ========================= 1 failed, 1 passed in 0.07s =========================
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    从上述结果可以看到,第一个测试用例运行通过,第二个测试用例运行失败,通过抛出的断言异常信息,可以清晰定位到问题出现在哪里。

    将测试用例放置在一个类中的优点是:

    测试用例可以共享用于类中的一些固定装置(如:前置条件、变量等)。

    能更好的管理和维护一个模块的测试用例。

    在类中进行多个测试时需要注意的是,每个测试都有一个唯一的类实例。就像下面这样:

    class TestDemo:
        value = 0
    
        def test_sample_one(self):
            self.value = 1
            print("\ntest_sample_one实例",self)
            # assert self.value == 1
    
        def test_sample_two(self):
            print("\ntest_sample_two实例", self)
            # assert self.value == 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果

    ============================= test session starts =============================
    collecting ... collected 2 items
    
    sample_demo_test.py::TestDemo::test_sample_one PASSED                    [ 50%]
    test_sample_one实例 <sample_demo_test.TestDemo object at 0x0000012836F6FD60>
    
    sample_demo_test.py::TestDemo::test_sample_two PASSED                    [100%]
    test_sample_two实例 <sample_demo_test.TestDemo object at 0x0000012836F6FA00>
    
    
    ============================== 2 passed in 0.01s ==============================
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    从结果可以看到,每个测试都对应一个实例地址,而两个测试是共享类属性(value=0),但是为了保证测试的独立性,尽可能的做数据隔离操作(最好不要共享数据,避免无效排查异常)。

    请求一个唯一的临时目录

    有些时候可能使用的是临时测试数据,就可以利用临时目录文件来处理。就像下面这样:

    content = "哈哈哈哈......呵呵呵呵"
    
    
    def test_sample_needsfiles(tmp_path):
        d = tmp_path.joinpath("sub")
        d.mkdir()
        d = d.joinpath("hello.txt")
        print("\n文件路径:", d)
        d.write_text(content)
        print(d.read_text())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    tmp_path是pytest提供的内置装置,返回的是pathlib类,针对pathlib模块提供的方法均可调用。
    joinpath(“sub”)是拼接路径后赋值给d,d.mkdir是创建临时目录。

    joinpath(“hello.txt”)是拼接文件,并重新赋值给d,不再次赋值,直接使用变量d的话会抛出文件没权限。
    write_text是往文件写入数据,read_text是把文件的数据读取出来。

    ============================= test session starts =============================
    collecting ... collected 1 item
    
    sample_needsfiles_test.py::test_sample_needsfiles PASSED                 [100%]
    文件路径:C:\Users\lifeng01\AppData\Local\Temp\pytest-of-lifeng01\pytest-46\test_sample_needsfiles0\sub\hello.txt
    哈哈哈哈......呵呵呵呵
    
    
    ============================== 1 passed in 0.02s ==============================
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    为保证临时目录的唯一性,这里的“pytest-46”每运行一次就会变化一次,此刻是46,,再次运行时就是47了。

    今天先聊到这里吧,以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你

    现在我邀请你进入我们的软件测试学习交流群:746506216】,备注“入群”, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路。

    喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一 键三连哦!
    在这里插入图片描述

  • 相关阅读:
    使用Python中的pytesseract模块实现抓取图片中文字
    GRPC 和 http
    Kubernetes基础服务安装
    蓝桥杯单片机第六届省赛题详细讲解(简易温度采集和控制装置)
    org.springframework.core.annotation.AnnotationUtils.clearCache()V 错误解决(SSM项目)
    Scala面向对象编程(高级部分)
    【图论】图的遍历 - 构建领接表(无向图)
    数学知识—不同数据范围求组合数,例题、思路、代码实现
    中台建设:中台有效落地的6脉神剑
    从0开始学习JavaScript--JavaScript类型化数组进阶
  • 原文地址:https://blog.csdn.net/wx17343624830/article/details/126077752