51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 3105|回复: 2
打印 上一主题 下一主题

[讨论] Python单元测试框架之pytest---如何执行测试用例

[复制链接]
  • TA的每日心情
    郁闷
    2022-8-29 14:43
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2018-4-18 14:01:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    pytest是一个成熟的全功能的Python测试工具,可以帮助你写出更好的程序。

    适合从简单的单元到复杂的功能测试

    l 模块化parametrizeable装置(在2.3,持续改进)
    l 参数化测试函数(用例)
    l 标记测试功能与属性
    l Skip和xfail:处理不成功的测试用例(在2.4改进)
    l 通过xdist插件分发测试到多个CPU
    l 不断地重新运行失败的测试
    l 灵活约定的Python测试发现
    Home Page: http://pytest.org





    安装                                                                    

    >pip install -U pytest   # 通过pip安装

    >py.test --version        # 查看pytest版本

     This is pytest version 2.7.2, imported from C:\Python27\lib\site-packages\pytest.pyc





    简单的测试                                                           



      让我们创建第一个文件,对个简单的功能进行测试。

    复制代码
    #coding=utf-8

    # 功能
    def func(x):
        return x + 1

    # 测试用例
    def test_answer():
        assert func(3) == 5
    复制代码
    切换到测试文件所在的目录,通过“py.test”命令运行测试。

    >py.test

    执行结果如下图:





    ===================================================================

    在一个测试类中创建多个测试用例:

    复制代码
    #coding=utf-8

    class TestClass:

        def test_one(self):
            x = "this"
            assert "h" in x

        def test_two(self):
            x = "hello"
            assert x == "hi"
    复制代码
    运行测试:

    >py.test -q test_class.py



    -q  为quiet。表示在安静的模式输出报告诉。加不加这个参有什么区别呢? 读者可以对比一下两次输出的日志。
    其实,就是少了一些pytest的版本信息。



    ===================================================================



    从Python代码中调用pytest

    pytest中同样提供了main() 来函数来执行测试用例。

    pytest/

    ├── test_sample.py

    ├── test_class.py

    └── test_main.py

    此目录为我们练习的目录,打开test_mian.py

    复制代码
    import pytest

    def test_main():
        assert 5 != 5

    if __name__ == '__main__':
        pytest.main()
    复制代码
    直接运行该程序,sublime 中按Ctrl+B 运行。结果如下:

    复制代码
    ============================= test session starts =============================
    platform win32 -- Python 2.7.10 -- py-1.4.30 -- pytest-2.7.2
    rootdir: D:\pyse\pytest, inifile:
    collected 4 items

    test_class.py .F
    test_main.py F
    test_sample.py F

    ================================== FAILURES ===========================
    ========
    _____________________________ TestClass.test_two ______________________________

    self = <test_class.TestClass instance at 0x000000000304F548>

        def test_two(self):
                x = "hello"
    >           assert x == "hi"
    E           assert 'hello' == 'hi'
    E             - hello
    E             + hi

    test_class.py:11: AssertionError
    __________________________________ test_main __________________________________

        def test_main():
    >       assert 5 != 5
    E    assert 5 != 5

    test_main.py:4: AssertionError
    _________________________________ test_answer _________________________________

        def test_answer():
    >       assert func(3) == 5
    E    assert 4 == 5
    E     +  where 4 = func(3)

    test_sample.py:9: AssertionError
    ===================== 3 failed, 1 passed in 0.03 seconds ======================
    [Finished in 0.3s]
    复制代码


      从执行结果看到,main() 默认执行了当前文件所在的目录下的所有测试文件。

      那么,如果我们只想运行某个测试文件呢?可以向main()中添加参数,就像在cmd命令提示符下面一样:

    复制代码
    #coding=utf-8
    import pytest

    def test_main():
        assert 5 != 5

    if __name__ == '__main__':
        pytest.main("-q test_main.py")   # 指定测试文件
    复制代码
    运行结果:

    复制代码
    F
    ================================== FAILURES ===========================
    ========
    __________________________________ test_main __________________________________

        def test_main():
    >       assert 5 != 5
    E    assert 5 != 5

    test_main.py:4: AssertionError
    1 failed in 0.01 seconds
    复制代码


    那如果我想运行某个目录下的测试用例呢?指定测试目录即可。

    复制代码
    #coding=utf-8
    import pytest

    def test_main():
        assert 5 != 5

    if __name__ == '__main__':
        pytest.main("d:/pyse/pytest/")  # 指定测试目录
    复制代码




    创建运行测试脚本                                                  



      有时候我们的测试用例文件分散在不同的层级目录下,通过命令行的方式运行测试显示不太方便,如何
    编写一个运行所有测试用例的脚本呢? pytest可以自动帮我们生成这样的脚本。

    >py.test --genscript=runtests.py



    打开生成的测runtests.py文件:

    复制代码
    sources = """
    eNrsve2S3EiSIDa3+jhtnvZ293Ra6SSdCZMUF0AzK1nk9OzM1nV2L4dNznKnm6TxY6dX1XVJVAJV
    halMIAkgWVU3O2d6Ar3CPYQeQn/1QjKTf8UnAplZ7O6ZPTNxpiszgQiPCA8PD3cPD/f/449+9/5H
    yds/W99M58v6fDqfl1XZzefv/9nbvxuPxxE8Oy+r8+jRy2dREq+bOt8siqaNo6zKo3hRV+1mRb/h
    a1UsuiKPPpRZdFncXNVN3qYRABmN3v/R23+OLbRd/v6/ePOf/tmPflSu1nXTRe1NOxotllnbRq+7
    PKlPfwMw0qNR
    ……
    """

    import sys
    import base64
    import zlib

    class DictImporter(object):
        def __init__(self, sources):
            self.sources = sources

        def find_module(self, fullname, path=None):
            if fullname == "argparse" and sys.version_info >= (2,7):
                # we were generated with <python2.7 (which pulls in argparse)
                # but we are running now on a stdlib which has it, so use that.
                return None
            if fullname in self.sources:
                return self
            if fullname + '.__init__' in self.sources:
                return self
            return None

        def load_module(self, fullname):
            # print "load_module:",  fullname
            from types import ModuleType
            try:
                s = self.sources[fullname]
                is_pkg = False
            except KeyError:
                s = self.sources[fullname + '.__init__']
                is_pkg = True

            co = compile(s, fullname, 'exec')
            module = sys.modules.setdefault(fullname, ModuleType(fullname))
            module.__file__ = "%s/%s" % (__file__, fullname)
            module.__loader__ = self
            if is_pkg:
                module.__path__ = [fullname]

            do_exec(co, module.__dict__) # noqa
            return sys.modules[fullname]

        def get_source(self, name):
            res = self.sources.get(name)
            if res is None:
                res = self.sources.get(name + '.__init__')
            return res

    if __name__ == "__main__":
        if sys.version_info >= (3, 0):
            exec("def do_exec(co, loc): exec(co, loc)\n")
            import pickle
            sources = sources.encode("ascii") # ensure bytes
            sources = pickle.loads(zlib.decompress(base64.decodebytes(sources)))
        else:
            import cPickle as pickle
            exec("def do_exec(co, loc): exec co in loc\n")
            sources = pickle.loads(zlib.decompress(base64.decodestring(sources)))

        importer = DictImporter(sources)
        sys.meta_path.insert(0, importer)

        entry = "import pytest; raise SystemExit(pytest.cmdline.main())"
        do_exec(entry, locals()) # noqa
    复制代码
    好吧!其实, 我也不理解这段代码的含义,但是执行它的可运行测试用例了。

    pytest/

    ├── test_case/

    │   ├── test_sample.py

    │   ├── test_class.py

    │   ├── __init__.py

    │   └── test_case2/

    │          ├── test_main.py

    │          ├── test_time.py

    │          └── __init__.py

    └── runtests.py



    执行runtest.py文件。

    >python runtest.py



    当然,你也可以打开runtests.py 文件运行它。



    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-28 05:12 , Processed in 0.067603 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表