Code前端首页关于Code前端联系我们

如何在Web项目中进行单元测试?

terry 2年前 (2023-09-25) 阅读数 47 #后端开发

可以使用单元测试框架,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前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门