代码测试用例指南

原文连接:http://blog.speedx.com/backend-test-guidehtml

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

测试的通用规则:git

  • 测试单元应该集中于小部分的功能,而且证实它是对的。github

  • 每一个测试单元应该彻底独立。web

  • 经过Mock去除依赖shell

  • 尽可能使测试单元快速运行。数据库

  • 实现钩子来持续集成json

咱们经过一个简单的python程序及unittest做为示例来为你们介绍如何进行测试,这里推荐你们使用python3来运行示例。vim

咱们先建立一个将会使用的测试目录api

mkdir /tmp/TestHookTest
cd /tmp/TestHookTest

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

下图为unittest包中包含的断言

咱们如今来写一个经过用户名得到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运行

每一个测试单元应该彻底独立

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

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

  • 经过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'])

尽可能使测试单元快速运行

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

实现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指南-测试你的代码

相关文章
相关标签/搜索