> For the complete documentation index, see [llms.txt](https://huataihuang.gitbook.io/cloud-atlas-draft/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://huataihuang.gitbook.io/cloud-atlas-draft/develop/python/django/tdd_unit_test_simple_homepage.md).

# TTD(测试驱动):使用单元测试测试简单首页

Django建议以"应用"形式组织代码，这样，一个项目中可以放多个应用，而且可以使用其他人开发的第三方应用，也可以重用自己在其他项目中开发的应用。

在代办事项清单中创建一个用用；

```
python3 manage.py startapp lists
```

该命令会在`superlists`文件夹中创建子文件夹`lists`，并与`superlists`子文件夹并列。

单元测试和功能测试的区别：

* 功能测试站在用户的角度从外部测试应用，单元测试则站在程序员的角度从内部测试应用。
* 功能测试的作用是帮助你开发具有所需功能的应用，还能保证你不会无意中破坏这些功能。单元测试的作用是帮助你编写简洁无错的代码。

## Django中的单元测试

在新生成的文件 `lists/tests.py` 中

```
from django.test import TestCase

# Create your tests here.
```

Django提供了TestCase的一个特殊版本，是标准版`unittest.TestCase`的增强版，添加了一些Django专用的功能。

这里我们先创建一个测试的故意错误的单元测试`lists/tests.py`

```
from django.test import TestCase

class SmokeTest(TestCase):
    def test_bad_maths(self):
        self.assertEqual(1 + 1, 3)
```

然后执行

```
python3 manage.py test
```

则提示输出

```
Creating test database for alias 'default'...
F
======================================================================
FAIL: test_bad_maths (lists.tests.SmokeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/huatai/Dropbox/works/tdd-python/superlists/lists/tests.py", line 5, in test_bad_maths
    self.assertEqual(1 + 1, 3)
AssertionError: 2 != 3

----------------------------------------------------------------------
Ran 1 test in 0.001s

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

可以看到单元测试检验出了错误的计算逻辑

## Django的MVC、URL和视图函数

Django采用了经典的"模型-视图-控制器"（Model-View-Controller，MVC）模式，但是没有严格遵守。Django有模型，但是视图更像是控制器，模板其实才是视图。

现在先准备一个测试，也就是先修正前面的`lists/tests.py`

```
from django.core.urlresolvers import resolve
from django.test import TestCase
from lists.views import home_page

class HomePageTest(TestCase):
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve('/')
        self.assertEqual(found.func, home_page)
```

`resolve`是Django内部使用的函数，用于解析URL，并将其映射到响应的视图函数上。检查解析网站根路径"/"，是否能找到名为`home_page`的函数。

此时执行`python3 manage.py test`会看到报错显示无法`import ‘home_page'函数`

```
ImportError: cannot import name 'home_page'
```

> 在使用TDD时要注意，每次少量修改代码，让失败的测试通过即可。

由于上述测试显示缺少`home_page`函数，所以我们现在在`lists.views.py`中添加如下代码

```
from django.shortcuts import render

# Create your views here.
# 实际上我们只添加了下面这行
home_page = None
```

虽然上述代码实际上没有用处，但是可以使得`python3 manage.py test`测试的错误输出个iabian，至少显示能够找到函数`home_page`了

```
...
  File "/Users/huatai/Dropbox/works/tdd-python/superlists/lists/tests.py", line 7, in test_root_url_resolves_to_home_page_view
    found = resolve('/')
...
django.urls.exceptions.Resolver404: {'tried': [[<RegexURLResolver <RegexURLPattern list> (admin:admin) ^admin/>]], 'path': ''}
....
```

上述`404`错误表示在尝试解析`/`时，Django抛出了404错误，也就是无法找到`/`的URL映射。

## `urls.py`

Django在`urls.py`文件中定义如何把URL映射到视图函数上。在文件夹`superlists/superlists`中有一个主`urls.py`文件，这个文件应用于整个网站。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/develop/python/django/tdd_unit_test_simple_homepage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
