您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“如何使用Django進行測試驅(qū)動開發(fā)”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!
所謂測試驅(qū)動開發(fā)(TDD),就是先編寫測試用例,然后編寫代碼來滿足測試用例,具體包含以下步驟:
編寫測試用例。
編寫代碼滿足測試用例中的需求。
運行測試用例。
如果通過,說明代碼滿足了測試用例所定義的需求。
如果未通過,則需要重構(gòu)代碼,直到通過。
重復(fù)以上步驟,直到通過全部的測試用例。
通常情況下,我們都是先寫代碼,然后編寫測試用例,因此測試驅(qū)動開發(fā)是反直覺的,那為什么還要這么做呢?基于以下幾點原因:
TDD 可以被認為是根據(jù)測試用例來說明需求。此后編寫源代碼,重點是滿足這些要求。當(dāng)測試最終通過時,你可以確信已滿足要求。這種專注可以幫助開發(fā)人員避免范圍蔓延。
TDD 可以通過較短的開發(fā)周期提高開發(fā)效率。一次解決測試用例中的個別需求可以最大限度地減少干擾因素。重大更改將更容易跟蹤和解決,減少了調(diào)試工作,提高了效率,并且將更多時間花在開發(fā)上。
編寫測試時考慮到了需求。正因為如此,它們更有可能被寫成明確的,可以理解的。這樣的測試可以作為代碼庫的優(yōu)質(zhì)文檔。
先編寫測試用例可確保您的源代碼始終具有可測試性,它還保證隨著代碼庫的增長,測試覆蓋率始終保持在合理的百分比。
然而,測試驅(qū)動開發(fā)也不是銀彈,以下情形并不適合測試驅(qū)動開發(fā):
當(dāng)需求不明確時,有時續(xù)期會隨著開發(fā)的進行而逐漸明確,在這種情況下最初編寫的任何測試可能會過時。
開發(fā)的目的是為了證明某一概念時——例如在黑客馬拉松期間,測試通常不是優(yōu)先事項。
了解了測試驅(qū)動開發(fā)之后,我們用 Django 來演示一下測試驅(qū)動開發(fā)的過程。(Python 3.7 以上,Django 2.0 以上)
首先描述需求,我們要實現(xiàn)這樣一個單位換算功能的 Web 應(yīng)用,可以在厘米、米、英里直接互相轉(zhuǎn)換,Web 界面如圖所示:
首先,我們創(chuàng)建一個名字叫 convert 的項目:
pip install django django-admin startproject converter
此時 Django 已經(jīng)為我們生成了 converter 目錄及基本的項目文件:
converter/ converter/ __init__.py settings.py urls.py wsgi.py manage.py
然后,進入 converter 目錄,創(chuàng)建一個名字叫 length 的 app:
cd converter python manage.py startapp length
然后你會看到這樣的目錄結(jié)構(gòu):
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
修改 converter/settings.py,在 INSTALLED_APPS 里加入 lengh :
INSTALLED_APPS = [ . . . 'length', ]
然后在 length 目錄下新建 urls.py,寫入以下內(nèi)容:
from django.urls import path from length import views app_name = 'length' urlpatterns = [ path('convert/', views.convert, name='convert'), ]
最后在 converter/urls.py 中指向 length/urls.py:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('length/', include('length.urls')), ]
這樣一個沒有任何業(yè)務(wù)邏輯的項目就創(chuàng)建成功了,接下來編寫測試用例:
在 lengh 目錄下新建 tests.py,寫入以下內(nèi)容:
from django.test import TestCase, Client from django.urls import reverse class 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 代表厘米轉(zhuǎn)米的需求,而 test_centimetre_to_mile_conversion 代表厘米轉(zhuǎn)英里的需求。
這和 Django 開發(fā)沒什么兩樣,先編寫一個 forms.py,內(nèi)容如下:
from django import forms class 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,內(nèi)容如下:
<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="轉(zhuǎn)換為:"/> <div> {{ form.output_unit }} {{ form.output_value }} </div> </form> </body> </html>
然后編寫最重要的視圖函數(shù) views.py,內(nèi)容如下:
from django.shortcuts import render from length.forms import LengthConverterForm convert_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})
執(zhí)行策四并不需要啟動 django 的 runserver:
出現(xiàn) OK 說明測試通過,啟動 django:
python manage.py runserver
打開瀏覽器,訪問 http://localhost:8000/length/convert/ 即可看到界面:
“如何使用Django進行測試驅(qū)動開發(fā)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。