如何使用Django进行测试驱动开发
本篇内容介绍了“如何使用Django进行测试驱动开发”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
所谓测试驱动开发(TDD),就是先编写测试用例,然后编写代码来满足测试用例,具体包含以下步骤:
编写测试用例。
编写代码满足测试用例中的需求。
运行测试用例。
如果通过,说明代码满足了测试用例所定义的需求。
如果未通过,则需要重构代码,直到通过。
重复以上步骤,直到通过全部的测试用例。
通常情况下,我们都是先写代码,然后编写测试用例,因此测试驱动开发是反直觉的,那为什么还要这么做呢?基于以下几点原因:
TDD 可以被认为是根据测试用例来说明需求。此后编写源代码,重点是满足这些要求。当测试最终通过时,你可以确信已满足要求。这种专注可以帮助开发人员避免范围蔓延。
TDD 可以通过较短的开发周期提高开发效率。一次解决测试用例中的个别需求可以最大限度地减少干扰因素。重大更改将更容易跟踪和解决,减少了调试工作,提高了效率,并且将更多时间花在开发上。
编写测试时考虑到了需求。正因为如此,它们更有可能被写成明确的,可以理解的。这样的测试可以作为代码库的优质文档。
先编写测试用例可确保您的源代码始终具有可测试性,它还保证随着代码库的增长,测试覆盖率始终保持在合理的百分比。
然而,测试驱动开发也不是银弹,以下情形并不适合测试驱动开发:
当需求不明确时,有时续期会随着开发的进行而逐渐明确,在这种情况下最初编写的任何测试可能会过时。
开发的目的是为了证明某一概念时——例如在黑客马拉松期间,测试通常不是优先事项。
了解了测试驱动开发之后,我们用 Django 来演示一下测试驱动开发的过程。(Python 3.7 以上,Django 2.0 以上)
首先描述需求,我们要实现这样一个单位换算功能的 Web 应用,可以在厘米、米、英里直接互相转换,Web 界面如图所示:
创建项目
首先,我们创建一个名字叫 convert 的项目:
pip install djangodjango-admin startproject converter
此时 Django 已经为我们生成了 converter 目录及基本的项目文件:
converter/ converter/ __init__.py settings.py urls.py wsgi.py manage.py
然后,进入 converter 目录,创建一个名字叫 length 的 app:
cd converterpython manage.py startapp length
然后你会看到这样的目录结构:
converter/ converter/ __init__.py settings.py urls.py wsgi.py length/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py manage.py
配置 app
修改 converter/settings.py,在 INSTALLED_APPS 里加入 lengh :
INSTALLED_APPS = [ . . . 'length',]
然后在 length 目录下新建 urls.py,写入以下内容:
from django.urls import pathfrom length import viewsapp_name = 'length'urlpatterns = [ path('convert/', views.convert, name='convert'),]
最后在 converter/urls.py 中指向 length/urls.py:
from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/', admin.site.urls), path('length/', include('length.urls')),]
这样一个没有任何业务逻辑的项目就创建成功了,接下来编写测试用例:
编写测试用例
在 lengh 目录下新建 tests.py,写入以下内容:
from django.test import TestCase, Clientfrom django.urls import reverseclass TestLengthConversion(TestCase): """ This class contains tests that convert measurements from one unit of measurement to another. """ def setUp(self): """ This method runs before the execution of each test case. """ self.client = Client() self.url = reverse("length:convert") def test_centimetre_to_metre_conversion(self): """ Tests conversion of centimetre measurements to metre. """ data = { "input_unit": "centimetre", "output_unit": "metre", "input_value": 8096.894 } response = self.client.get(self.url, data) self.assertContains(response, 80.96894) def test_centimetre_to_mile_conversion(self): data = { "input_unit": "centimetre", "output_unit": "mile", "input_value": round(985805791.3527409, 3) } response = self.client.get(self.url, data) self.assertContains(response, 6125.5113)
上述代码有两个测试用例,分别代表两个需求。test_centimetre_to_metre_conversion 代表厘米转米的需求,而 test_centimetre_to_mile_conversion 代表厘米转英里的需求。
编写代码
这和 Django 开发没什么两样,先编写一个 forms.py,内容如下:
from django import formsclass LengthConverterForm(forms.Form): MEASUREMENTS = ( ('centimetre', '厘米'), ('metre', '米'), ('mile', '英里') ) input_unit = forms.ChoiceField(choices=MEASUREMENTS) input_value = forms.DecimalField(decimal_places=3) output_unit = forms.ChoiceField(choices=MEASUREMENTS) output_value = forms.DecimalField(decimal_places=3, required=False)
然后编写 html,在 length 目录下新建 templates/length.html,内容如下:
<html lang="en"> <head> <title>Length Conversion</title> </head> <body> <form action={% url "length:convert" %} method="get"> <div> {{ form.input_unit }} {{ form.input_value }} </div> <input type="submit" value="转换为:"/> <div> {{ form.output_unit }} {{ form.output_value }} </div> </form> </body></html>
然后编写最重要的视图函数 views.py,内容如下:
from django.shortcuts import renderfrom length.forms import LengthConverterFormconvert_to_metre = { "centimetre": 0.01, "metre": 1.0, "mile": 1609.34}convert_from_metre = { "centimetre": 100, "metre": 1.0, "mile": 0.000621371}# Create your views here.def convert(request): form = LengthConverterForm() if request.GET: input_unit = request.GET['input_unit'] input_value = request.GET['input_value'] output_unit = request.GET['output_unit'] metres = convert_to_metre[input_unit] * float(input_value) print(f"{metres = }, {input_value = }") output_value = metres * convert_from_metre[output_unit] data = { "input_unit": input_unit, "input_value": input_value, "output_unit": output_unit, "output_value": round(output_value,5) } form = LengthConverterForm(initial=data) return render( request, "length.html", context={"form": form}) return render( request, "length.html", context={"form": form})
执行测试
执行策四并不需要启动 django 的 runserver:
出现 OK 说明测试通过,启动 django:
python manage.py runserver
打开浏览器,访问 http://localhost:8000/length/convert/ 即可看到界面:
“如何使用Django进行测试驱动开发”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341