shiniei
shiniei
发布于 2025-06-17 / 0 阅读
0
0

12.测试代码

测试代码,就是尽可能在用户发现bug之前提前找到并修复bug

更新包

python -m pip install --upgrade package_name

更新pip包

python -m pip install --upgrade pip

安装三方包

--user参数指仅为当前用户安装,一般加不加都没多大影响

python -m pip install --user  package_name

安装pytest包

python -m pip install --user  pytest

测试代码

写好的代码(add.py)后,再新建一个前缀为test_ 或 以_test后缀的py文件(test_add.py),然后导入原先的代码

待测试函数

# add.py
def add_num(x , y):
    return x + y

编写测试代码

其中assert右边可以换成其他的运算符(只有结果是布尔值就没有问题)

# test_add.py
from add import add_num

def test_add_num():
    result = add_num(11, 45)
    assert result == 56

开始测试

后面这个这个test_add.py模块名字如果不加那就是测试当前目录下所有的以test_前缀 或 以_test后缀的py文件;如果加上就只测一个文件

python -m pytest test_add.py

测试完成

当你测试完成,你将看到一个进度值(100%)和一个. ,这个点表示测试成功,反之表示测试失败。关于这个进度条,如果你使用的是python -m pytest并且旁边还有一个测试文件,这个测试文件还有两个测试函数,那么第一个进度值一定是33%或者66%。

PS E:\Documents\code> python -m pytest                              
======================= test session starts =======================
platform win32 -- Python 3.13.1, pytest-8.4.0, pluggy-1.6.0
rootdir: E:\Documents\code
collected 3 items                                                  

test_add.py .                                                [ 33%]
test_survey.py ..                                            [100%]

======================== 3 passed in 0.06s ========================

待测试类

# survey.py
class AnonymousSurvey:
    """Collect anonymous answers to a survey question."""

    def __init__(self, question):
        """Store a question, and prepare to store responses."""
        self.question = question
        self.responses = []

    def show_question(self):
        """Show the survey question."""
        print(self.question)

    def store_response(self, new_response):
        """Store a single response to the survey."""
        self.responses.append(new_response)
        
    def show_results(self):
        """Show all the responses that have been given."""
        print("Survey results:")
        for response in self.responses:
            print(f"- {response}")

运行代码

# language_survey.py
from survey import AnonymousSurvey


# Define a question, and make a survey.
question = "What language did you first learn to speak?"
language_survey = AnonymousSurvey(question)

# Show the question, and store responses to the question.
language_survey.show_question()
print("Enter 'q' at any time to quit.\n")
while True:
    response = input("Language: ")
    if response == 'q':
        break
    language_survey.store_response(response)

# Show the survey results.
print("\nThank you to everyone who participated in the survey!")
language_survey.show_results()

测试代码

可以测试单个方法,也可以通过模仿单个方法来测试多个方法,不过可能有些操作比较繁杂,因为很多代码都是很低效重复的,所以我们要用额外的手段来尽可能减少重复代码。

测试单个函数

# test_survey.py
from survey import AnonymousSurvey
def test_store_single_response():
    """Test that a single response is stored properly."""
    question = "What language did you first learn to speak?"
    language_survey = AnonymousSurvey(question)
    language_survey.store_response('English')
    assert 'English' in language_survey.responses

然后运行

python -m pytest test_survey.py

测试多个函数

# test_survey.py
from survey import AnonymousSurvey

def test_store_single_response():
    """Test that a single response is stored properly."""
    question = "What language did you first learn to speak?"
    language_survey = AnonymousSurvey(question)
    language_survey.store_response('English')
    assert 'English' in language_survey.responses


def test_store_three_responses():
    """Test that three individual responses are stored properly."""
    question = "What language did you first learn to speak?"
    language_survey = AnonymousSurvey(question)
    responses = ['English', 'Spanish', 'Mandarin']
    for response in responses:
        language_survey.store_response(response)

    for response in responses:
        assert response in language_survey.responses

然后运行

python -m pytest test_survey.py

优化测试代码

首先我们要先学习一下装饰器

装饰器

我这定义了三个函数和使用了一下装饰器,首先我们先看上面的函数,假设我们运行这最上面的out_func函数并让它被赋值为a,执行之后它会先打印外层1,接着返回值in_func函数给a,所以现在a就相当于指向in_func函数,所以a后面接上个括号就能直接运行内层函数的代码。
而我们要说的装饰器就和这个原理非常像,其实下面的@out_func以及跟在定义函数后面的,约等于a = out_func(test_func),所以再给a后面接一个括号,就跟上面说的原理一模一样了。

# test.py
def out_func(func):
    print('外层1')
    def in_func():
        print('内层1')
        func()
        print('内层2') 
    return in_func

@out_func
def test_func():
    print('test_func')

test_func()

def test1_func(func):
    func() # 等价于运行test_func()而这个等价于运行in_func()

test1_func(test_func)
测试代码
# test_survey.py
import pytest
from survey import AnonymousSurvey


@pytest.fixture
def language_survey():
    """A survey that will be available to all test functions."""
    question = "What language did you first learn to speak?"
    language_survey = AnonymousSurvey(question)
    return language_survey

def test_store_single_response(language_survey):
    """Test that a single response is stored properly."""
    language_survey.store_response('English')
    assert 'English' in language_survey.responses

def test_store_three_responses(language_survey):
    """Test that three individual responses are stored properly."""
    responses = ['English', 'Spanish', 'Mandarin']
    for response in responses:
        language_survey.store_response(response)

    for response in responses:
        assert response in language_survey.responses

评论