测试

1 自动化测试简介

测试有好几种,有些只关注某个细节(模型方法),有些检查一系列操作(用户输入)。手动测试需要花费大量时间。

为什么是现在?

你可能会觉得,和富有创造性和生产力的业务代码比起来,测试代码实在是太无聊了。毕竟我们的投票应用看起来已经完美工作了,自动测试并不能让它工作得更好。如果投票应用是你的唯一目标,那么确实没必要学写测试。但如果你还想尝试更复杂的项目,那么现在就是学习测试写法的最好时机了。

复杂应用程序的组件之间有多重交互。任一组件的改变,都可能造成意想不到的后果。这意味着,你需要完整地测试全部功能,才能确保你的小修改没有破坏整体。而自动化测试几秒钟之内就能帮你完成这件事,甚至找到错误代码的位置。测试不是开发的对立面。测试不仅能发现错误,而且能预防错误。

测试让代码的意图变得清晰。当你看自己以前写的代码时,往往也需要仔细研读才搞清它的作用。

也许你编写了一个超棒的软件,但是其他开发者看都不看一眼,因为它缺少测试,没有测试的代码不值得信任。其他开发者希望在正式使用你的代码前确认它已经通过了测试。测试的存在保证协作者不会不小心弄坏你的代码(也保证你不会不小心弄坏他们的代码)。

2 基础测试策略

新手倾向于先写代码再写测试。虽然先写测试更好,但是晚写起码比不写强。

3 开始写我们的第一个测试

首先得有个 Bug 。作者机智地预留了一个:当发布时间比当前时间晚时,判断“问题是不是最近发布的”函数返回了 True 。

Django 应用的测试应该写在应用的 tests.py 文件里。

# polls/tests.py
import datetime
from django.test import TestCase
from django.utils import timezone
from .models import Question

class QuestionModelTests(TestCase):
    def test_was_published_recently_with_future_question(self):
        """
        was_published_recently() returns False for questions whose pub_date
        is in the future.
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

运行测试 python manage.py test polls ,便能得知 AssertionError: True is not False 。将来我们的应用可能会出现其他的问题,但是肯定不会再次出现这个问题,这一小部分代码永远安全。

4 测试视图

Django 提供了一个 Client 来模拟用户和视图的交互。

>>> from django.test import Client
>>> client = Client()
>>> response = client.get('/')
>>> response.status_code

5 当需要测试的时候,测试用例越多越好

让测试代码继续肆意增长吧。

6 深入代码测试

世界上有很多工具来帮你完成这些(看起来没)有意义的事,了解一下。

  • Selenium <=> Django.LiveServerTestCase
  • CI(Continuous Integration)
  • coverage.py