Web项目如何做单元测试

2024软件测试面试刷题,这个小程序(永久刷题),靠它快速找到工作了!(刷题APP的天花板)【持续更新最新版】-CSDN博客

你可能会用单元测试框架,python的unittest、pytest,Java的Junit、testNG等。

那么你会做单元测试么!当然了,这有什么难的?

test_demo.py

python 复制代码
def inc(x):
    return x + 1


def test_answer():
    assert inc(3) == 4

inc() 是定义的一个被测函数,test_anserver() 用于测试上面的一段代码。

通过pytest运行上面的代码:

python 复制代码
> 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 指models,用于定义ORM,即对象关系映射,是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。

models.py 中的代码是这样的:

python 复制代码
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField(auto_now=True)

这里定义了两个类,这两个类即没有入参,也没有return返回值。如何测试呢?

测试代码如下:

python 复制代码
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模型我们可以看作是数据库表,那么对于表的操作就是增删改查,这里先创建一条数据,再查询出这条数据,然后判断其字段是否正确。

参考:Writing and running tests | Django documentation | Django

视图测试

  • V 指views,用于接收前端发来的请求,可能需要调用数据库,把对应的数据处理之后,和HTML页面一同返回给前端。

views.py 代码如下:

python 复制代码
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() 视图函数确实有入参,request包含的是客户端信息,比如请求的方法,请求的host,请求头Header等,这些客户端数据如何构造? return返回的是HTML页面,以及查询数据库的数据,如何针对这些数据写断言呢?

测试代码如下:

python 复制代码
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() 可以模拟客户端浏览器发送 request GET 请求。拿到服务端的response,判断状态码是否为 200。 self.assertTemplateUsed() 断言返回的页面是否正确。

参考:Testing tools | Django documentation | Django

模板测试

  • T 指Teamplate,主要是HTML页面。用户在浏览器中输入URL地址,最终会得到一个HTML页面。

index.html代码如下:

python 复制代码
{% 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自动化测试,从而保证页面的正确性。

python 复制代码
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启动的服务地址。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇5 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒5 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端