《python web开发 测试驱动方法》

第一部分 TDD和Django基础

第一章 使用功能测试协助安装Django
1.1 遵从测试山羊的教诲,没有测试什么也别做
  • 先编写功能测试,建立文件functional_test.py
python 复制代码
# -*- encoding: utf-8 -*-
from selenium import webdriver
browser = webdriver.Chrome()
browser.get("http://localhost:8000")
assert 'Django' in browser.title
  • 会发现报错
1.2 让Django运行起来
  • django-admin startproject superlists 创建项目

    C:\coding\python\tdd_learn\tdd_python_web\demo1>tree /f
    Folder PATH listing
    Volume serial number is 765E-FFBF
    C:.
    │ functional_tests.py
    │ geckodriver.log

    └─superlists
    manage.py

    └─superlists
    settings.py
    urls.py
    wsgi.py
    init.py

  • 启动Django:python manage.py runserver

  • 再开一个窗口,在其中再次尝试运行测试 python functional_tests.py

1.3 创建Git仓库
  • mv functional_tests.py superlists/

  • cd superlists/

  • git init .

    $ ls
    db.sqlite3 functional_tests.py manage.py* superlists/
    db.sqlite3是数据库文件,不想把这个纳入版本控制,因此要将其添加到一个特殊的文件.gitignore中,告诉Git将其忽略

  • echo "db.sqlite3" >> .gitignore

  • git add .

  • git status

  • git rm -r --cached superlists/__pycache__/

  • echo "__pycache__" >> .gitignore

  • echo ".pyc" >> .gitignore

  • git status

  • git commit

  • 在你自己的GitHub上建立一个仓库superlists,然后

    • git remote add origin https://github.com/Gin757306533/superlists.git
  • git push -u origin master

  • git push origin master

第2章 使用unittest模块扩展功能测试

2.1使用功能测试驱动开发一个最简可用的应用
2.2 python标准库中的unittest模块
  • C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\functional_tests.py
python 复制代码
# -*- encoding: utf-8 -*-
import unittest
from selenium import webdriver

class NewVisitorTest(unittest.TestCase):
    def setUp(self):
        self.browser = webdriver.Chrome()
        self.browser.implicitly_wait(3)
        # 隐式等待
    def tearDown(self):
        self.browser.quit()
    def test_can_start_a_list_and_retrieve_it_later(self):
        self.browser.get("http://localhost:8000")
        self.assertIn('To-Do' , self.browser.title)
        self.fail("Finish the test!")


if __name__ == '__main__':
    unittest.main(warnings='ignore')
2.3 隐式等待
2.4 提交
  • git status
  • git diff
  • git commit -a

第3章 使用单元测试测试简单的首页

3.1 第一个Django应用,第一个单元测试
  • python manage.py startapp lists

    C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists>tree /F
    Folder PATH listing
    Volume serial number is 765E-FFBF
    C:.
    │ .gitignore
    │ db.sqlite3
    │ functional_tests.py
    manage.py

    ├─lists
    │ │ admin.py
    │ │ apps.py
    │ │ models.py
    │ │ tests.py
    │ │ views.py
    │ │ init.py
    │ │
    │ └─migrations
    init.py

    └─superlists
    settings.py
    urls.py
    wsgi.py
    init.py

    └─pycache
    settings.cpython-36.pyc
    urls.cpython-36.pyc
    wsgi.cpython-36.pyc
    init.cpython-36.pyc

3.2 单元测试及其与功能测试的区别
  • 功能测试站在用户的角度从外部测试应用
  • 单元测试则站在程序员的角度从内部测试应用
  • 工作流程
    • 先写功能测试
    • 功能测试失败后,想办法编写代码让它通过
      • 此时,使用一个或多个单元测试定义希望代码实现的效果,保证为应用中的每一行代码编写一个单元测试
    • 单元测试失败后,编写最少量的应用代码,刚好让单元测试通过。
    • 再次运行功能测试,看是否能够通过,或者有没有进展
3.3 Django中的单元测试
  • django.test.TestCase是unittest.TestCase的增强版
  • C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\tests.py代码
python 复制代码
from django.test import TestCase

# Create your tests here.
class SmokeTest(TestCase):
    def test_bad_maths(self):
        self.assertEqual(1+1, 3)
  • 然后执行:python manage.py test,发现:

    Creating test database for alias 'default'...
    System check identified no issues (0 silenced).
    F

    FAIL: test_bad_maths (lists.tests.SmokeTest)

    Traceback (most recent call last):
    File "C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\tests.py", line 6, in test_bad_maths
    self.assertEqual(1+1, 3)
    AssertionError: 2 != 3


    Ran 1 test in 0.002s

    FAILED (failures=1)
    Destroying test database for alias 'default'...

  • git status

  • git add lists

  • git diff --staged

  • git commit -m "Add app for lists, with deliberately failing unit test"

3.4 Django 中的MVC,URL和视图函数
  • C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\tests.py修改如下:
python 复制代码
from django.test import TestCase
from django.urls import resolve
from lists.views import home_page
# Create your tests here.
class HomePageTest(TestCase):
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve('/')
        self.assertEqual(found.func, home_page)
# class SmokeTest(TestCase):
#     def test_bad_maths(self):
#         self.assertEqual(1+1, 3)
  • python manage.py test
    • 此时会报错,说无法导入home_page
3.5 终于可以编写一些应用代码了
  • 上面无法导入home_page函数,所以可以这么做:
  • C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\views.py
python 复制代码
from django.shortcuts import render

# Create your views here.
home_page = None
  • 然后再执行:python manage.py test
    • 会报错,说无法解析"/"
3.6 urls.py
  • C:\coding\python\Django_project\mysite\mysite\urls.py
python 复制代码
"""superlists URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from lists.views import home_page
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^$', home_page)
]
  • 然后执行,发现home_page不可调用
  • 再改:C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\views.py
python 复制代码
from django.shortcuts import render

# Create your views here.
def home_page():
    pass
  • 这次就会通过啦
  • git diff
  • git commit -am "First unit test and url mapping, dummy view"
3.7 为视图编写单元测试
  • C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\tests.py
python 复制代码
from django.test import TestCase
from django.urls import resolve
from lists.views import home_page
from django.http import HttpRequest
# Create your tests here.
class HomePageTest(TestCase):
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve('/')
        self.assertEqual(found.func, home_page)

    def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)
        self.assertTrue(response.content.startswith(b'<html>'))
        self.assertIn(b'<title>To-Do lists</title>', response.content)
        self.assertTrue(response.content.endswith(b"</html>"))
# class SmokeTest(TestCase):
#     def test_bad_maths(self):
#         self.assertEqual(1+1, 3)
  • C:\coding\python\tdd_learn\tdd_python_web\demo1\superlists\lists\views.py
python 复制代码
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def home_page(request):
    return HttpResponse('<html><title>To-Do lists</title></html>')
  • git diff
  • git commit -am "Basic view now returns minimal HTML"

第4章 编写这些测试有什么用

4.1 编程就像从井里面打水
4.2 使用Selenium 测试用户交互
  • python
相关推荐
IT=>小脑虎1 天前
2026年 Vue3 零基础小白入门知识点【基础完整版 · 通俗易懂 条理清晰】
前端·vue.js·状态模式
叫我:松哥1 天前
基于Flask框架开发的智能旅游推荐平台,采用复合推荐算法,支持管理员、导游、普通用户三种角色
python·自然语言处理·flask·旅游·数据可视化·推荐算法·关联规则
CSDN_RTKLIB1 天前
inline内联函数基础知识
开发语言·c++
No0d1es1 天前
2025年12月 GESP CCF编程能力等级认证Python四级真题
开发语言·python·青少年编程·等级考试·gesp·ccf
love530love1 天前
EPGF 新手教程 13在 PyCharm(中文版 GUI)中创建 Hatch 项目环境,并把 Hatch 做成“项目自包含”(工具本地化为必做环节)
开发语言·ide·人工智能·windows·python·pycharm·hatch
Ralph_Y1 天前
C++异常对象
开发语言·c++
baiduopenmap1 天前
【智图译站】GENREGION——高准确度、高可扩展的城市区域自动划分方法
开发语言·百度地图
蚰蜒螟1 天前
Redis网络层深度解析:数据如何写回客户端
java·开发语言·bootstrap
IT_陈寒1 天前
Python 3.12性能优化实战:5个让你的代码提速30%的新特性
前端·人工智能·后端