代碼測試用例指南

原文連接: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指南-測試你的代碼

相關文章
相關標籤/搜索