美文网首页一个程序员
代码测试用例指南

代码测试用例指南

作者: 张伯函 | 来源:发表于2018-12-28 19:19 被阅读7次

    将测试代码和运行代码一起写是一种非常好的习惯。聪明地使用这种方法将会帮助你更加精确地定义代码的含义,并且代码的耦合性更低。

    测试的通用规则:

    • 测试单元应该集中于小部分的功能,并且证明它是对的。
    • 每个测试单元应该完全独立。
    • 通过Mock去除依赖
    • 尽量使测试单元快速运行。
    • 实现钩子来持续集成

    我们通过一个简单的python程序及unittest作为示例来为大家介绍如何进行测试,这里推荐大家使用python3来运行示例。

    我们先创建一个将会使用的测试目录

    mkdir /tmp/TestHookTest
    cd /tmp/TestHookTest
    

    测试单元应该集中于小部分的功能,并且证明它是对的

    下图为unittest包中包含的断言

    image

    我们现在来写一个通过用户名获得github信息的一个函数,并对这个函数进行测试

    # test.py
    import unittest
    import json
    
    import requests
    
    def fetch_github_profile(username):
        response = requests.get('https://api.github.com/users/' + username)
        return response.json()
    
    class SaveDataTest(unittest.TestCase):
    
        def test_fetch_github_profile(self):
            username = 'ZhangBohan'
            data = fetch_github_profile('ZhangBohan')
            self.assertEqual(data['login'], username)
    
    

    通过python3 -m unittest test运行

    每个测试单元应该完全独立

    image
    • 每个都能够单独运行,除了调用的命令,都需在测试套件中。要想实现这个规则,测试单元应该加载最新的数据集,之后再做一些清理。

    • 如果有数据库依赖,在每次测试前创建测试数据库,结束后销毁该数据库,测试应该有单独的数据库,不要在生产和开发环境测试,避免数据变化引起的测试失败

    • 通过Mock去除依赖

    假设我们现在想把取得的用户数据保存到本地,并测试是否正确保存

    # test.py
    import unittest
    import json
    
    import requests
    
    def fetch_github_profile(username):
        response = requests.get('https://api.github.com/users/' + username)
        return response.json()
    
    def save_data(data):
        with open('data.json', 'w') as f:
            f.write(json.dumps(data))
    
    class SaveDataTest(unittest.TestCase):
    
        def test_fetch_github_profile(self):
            username = 'ZhangBohan'
            data = fetch_github_profile('ZhangBohan')
            self.assertEqual(data['login'], username)
    
        def test_save_data(self):
            data = fetch_github_profile('ZhangBohan')
            save_data(data)
    
            with open('data.json') as f:
                file_data = json.loads(f.read())
                self.assertIsNotNone(file_data)
                self.assertEqual(data['id'], file_data['id'])
    
    

    在这个测试中我们的test_save_data中的data依赖fetch_github_profile中的返回数据,现实情况中会遇到更为复杂的依赖,为了一个测试用例,我们可能需要构建大量的初始化数据。我们可以通过mock来解除这个依赖,让test_save_data专注于测试保存数据部分

    # test.py
    import unittest
    import json
    from unittest.mock import MagicMock
    
    import requests
    
    def fetch_github_profile(username):
        response = requests.get('https://api.github.com/users/' + username)
        return response.json()
    
    def save_data(data):
        with open('data.json', 'w') as f:
            f.write(json.dumps(data))
    
    
    FAKE_PROFILE_DATA = {
      "login": "ZhangBohan",
      "id": 2317407
    }
    
    class SaveDataTest(unittest.TestCase):
    
        def test_fetch_github_profile(self):
            username = 'ZhangBohan'
            data = fetch_github_profile('ZhangBohan')
            self.assertEqual(data['login'], username)
    
        def test_save_data(self):
            fetch_github_profile = MagicMock(return_value=FAKE_PROFILE_DATA)
            data = fetch_github_profile('ZhangBohan')
            save_data(data)
    
            with open('data.json') as f:
                file_data = json.loads(f.read())
                self.assertIsNotNone(file_data)
                self.assertEqual(data['id'], file_data['id'])
    
    

    尽量使测试单元快速运行

    image

    如果一个单独的测试单元需要较长的时间去运行,开发进度将会延迟,测试单元将不能如期常态性运行。有时候,因为测试单元需要复杂的数据结构,并且当它运行时每次都要加载,所以其运行时间较长。把运行吃力的测试单元放在单独的测试组件中,并且按照需要运行其它测试单元。

    实现hook来持续集成

    通过代码提交的本地hook或者webhook来持续集成测试你的代码。

    举个git本地hook的例子(这可假设你了解git hook的工作原理)。

    > git init
    > vim .git/hooks/pre-commit
    

    .git/hooks/pre-commit文件中写入

    #!/bin/sh
    
    cd /tmp/TestHookTest && python3 -m unittest test
    

    执行:

    > chmod +x .git/hooks/pre-commit
    
    > git add test.py
    > git commit -m "test hook"
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    OK
    [master (root-commit) b390117] test hook
     1 file changed, 9 insertions(+)
     create mode 100644 test.py
    

    在远程代码仓库部署的webhook能更好的测试全部代码。

    Python指南-测试你的代码

    相关文章

      网友评论

        本文标题:代码测试用例指南

        本文链接:https://www.haomeiwen.com/subject/vcgocqtx.html