如何在Web项目中进行单元测试?
可以使用单元测试框架,Python的unittest、pytest、Java的Junit、testNG等。
那么你能做单元测试吗?当然,这有什么难的呢?
test_demo.py
def inc(x):
return x + 1
def test_answer():
assert inc(3) == 4
inc()是一个被测试的函数,test_anserver()用于测试上面的代码。
通过pytest运行上面的代码:
> pytest test_demo.py
====================== test session starts ======================= platform win32 -- Python 3.7.1, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: D:\vipcn\demo
plugins: cov-2.7.1, forked-1.0.2, html-1.20.0, metadata-1.8.0, ordering-0.6, parallel-0.0.9, rerunfailures-7.0, xdist-1.28.0, seleniumbase-1.23.10
collected 1 item
test_demo.py . [100%]
==================== 1 passed in 0.08 seconds ====================
单元测试是不是这么简单?
那么如何在 Web 项目中运行单元测试呢?
我们以Django Web框架为例,MTV
开发模型。然后我们介绍如何在该模式下运行测试。
模型测试
- M是指用于定义ORM(即对象关系映射)的模型,它通过使用描述对象与数据库之间映射的元数据,将面向对象语言程序中的对象自动存储在关系数据库中。中间。
models.py中的代码如下:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(auto_now=True)
这里定义了两个类。这两个类没有输入参数,也没有返回值。如何测试呢?
测试代码如下:
from django.test import TestCase
from myapp.models import Question
class QuestionTestCase(TestCase):
def setUp(self):
Question.objects.create(id=1, question_text="你会做单元测试么?")
def test_question(self):
"""查询id=1的问题"""
question = Question.objects.get(id=1)
self.assertEqual(question.question_text, '你会做单元测试么?')
不知道这段代码你看懂了没有。 Django模型可以认为是一张数据库表,所以对表的操作就是增删改查,这里先创建一条数据,然后查询这条数据然后判断字段是否存在是正确的。
参考:https://docs.djangoproject.com/en/2.2/topics/testing/overview/
测试视图
- V指视图,用于接收来自前端的请求,必须调用数据库,处理相应的数据后,与HTML页面一起返回到前端。
views.py代码如下:
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
index()视图函数有输入参数。请求中包含客户信息,如请求方法、请求主机、请求头等,这些客户的数据是如何构造的? Return 返回一个 HTML 页面并请求数据库信息。如何为这些数据编写报表?
测试代码如下:
from django.test import TestCase
from myapp.models import Question
class IndexTestCase(TestCase):
def setUp(self):
Question.objects.create(id=1, question_text="你会做单元测试么?")
def test_index(self):
"""测试index视图"""
response = self.client.get("/index")
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "polls/index.html")
假设浏览器访问http://127.0.0.1:8000/index时,会显示index拨打电话并返回调查问卷页面。
self.client.get()可以模拟客户端浏览器发送GET请求。获取服务器的响应,判断状态码是否为200。 self.assertTemplateUsed() 证明返回的页面是否正确。
参考:https://docs.djangoproject.com/en/2.2/topics/testing/tools/
测试模板
- T指Teamplate,主要是HTML页面。用户在浏览器中输入URL地址,最终得到一个HTML页面。
index.html代码如下:
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a name="q" href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
这里的代码连方法都没有,更别说输入参数和返回值了。如何测试HTML代码?
我们确实没有办法直接测试HTML代码。但是,您可以使用 Selenium 运行自动化 UI 测试以确保页面的准确性。
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
class MySeleniumTests(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.selenium = webdriver.Chrome()
cls.selenium.implicitly_wait(10)
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super().tearDownClass()
def test_index_page(self):
self.selenium.get('%s%s' % (self.live_server_url, '/index'))
question_list = self.selenium.find_elements_by_name("q")
for q in question_list:
print(q.text)
Django 封装了StaticLiveServerTestCase,它允许您在运行 UI 测试时自动启动 Django 服务。因此,可以直接使用 self.live_server_url 来访问 django 启动的服务地址。
参考:https://docs.djangoproject.com/en/2.2/topics/testing/tools/
本文是否刷新了您对项目中单元测试的理解?那么问题来了:我上面写的代码哪一部分属于单元测试?
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。