使用 pytest 单元测试 Flask-wtfoms

问题描述

这是对我的 previous question. 的跟进。我已经构建了表单和页面,并开始使用单元测试对其进行测试。但是,当我尝试使用新的 sqlite 数据库 test.db 运行单元测试时,它找不到其中的表,如果我使用主 data.db,则无法读取 homepage table

内容

在我的 unit_test.py 中,我有以下测试基础

from flask_testing import TestCase
from flask_sqlalchemy import sqlAlchemy
from flask import url_for
import os

from application import app,db
from application.models import Company,Frankendama
class TestBase(TestCase):
def create_app(self):

    app.config.update(
        sqlALCHEMY_DATABASE_URI="sqlite:///test.db",SECRET_KEY='TEST_SECRET_KEY',DEBUG=True,WTF_CSRF_ENABLED=False
    )

    return app

def set_up(self):
    db.create_all()

    frank1 = Frankendama(
        title="Taps",description="A combo of damas designed for taps",tama="SK x Cereal STIK",Sarado="Lomond Shape",sword="Lomond Shape",string="72",bearing="Yes"
    )

    company1 = Company(name = "CEREAL",frankendama_id = 1)
    company2 = Company(name = "SK",frankendama_id = 1)

    db.session.add(frank1)
    db.session.add(company1)
    db.session.add(company2)

    db.session.commit()

def tear_down(self):

    db.session.remove()
    db.drop_all()

在基础之后我还有 3 个测试类:

  • 测试读取
  • 测试更新
  • 测试删除

它们看起来像这样:

class TestRead(TestBase):

def test_home(self):
    response = self.client.get(
        url_for('home'),follow_redirects= True
        )

    assert "Taps" in response.data.decode()
    assert "Check updated task" in response.data.decode()
    assert "SK x Ceral STIK" in response.data.decode()
    assert "Lomond Shape" in response.data.decode()
    assert "Lomond Shape" in response.data.decode()
    assert "72" in response.data.decode()
    assert "Yes" in response.data.decode()
    assert "CEREAL" in response.data.decode()
    assert "SK" in response.data.decode()

class TestUpdate(TestBase):

def test_update(self):
    response = self.client.post(
        url_for('update',id=1),data={"description": "Check updated task"},follow_redirects= True
    )

    assert "Taps" in response.data.decode()
    assert "Check updated task" in response.data.decode()
    assert "SK x Ceral STIK" in response.data.decode()
    assert "Lomond Shape" in response.data.decode()
    assert "Lomond Shape" in response.data.decode()
    assert "72" in response.data.decode()
    assert "Yes" in response.data.decode()
    assert "CEREAL" in response.data.decode()
    assert "SK" in response.data.decode()

    assert "A combo of damas designed for taps" not in response.data.decode()


def test_update_companies(self):
    response = self.client.post(
        url_for('update',data={"companies": "SWEETS"},follow_redirects= True
    )

    assert "Taps" in response.data.decode()
    assert "A combo of damas designed for taps" in response.data.decode()
    assert "SK x Ceral STIK" in response.data.decode()
    assert "Lomond Shape" in response.data.decode()
    assert "Lomond Shape" in response.data.decode()
    assert "72" in response.data.decode()
    assert "Yes" in response.data.decode()
    assert "SWEETS" in response.data.decode()
    assert "SK" not in response.data.decode()
    assert "CEREAL" not in response.data.decode()

class TestDelete(TestBase):

def test_delete(self):
    response = self.client.get(
        url_for('delete',follow_redirects=True
    )

    assert "Taps" not in response.data.decode()
    assert "A combo of damas designed for taps" not in response.data.decode()
    assert "SK x Ceral STIK" not in response.data.decode()
    assert "Lomond Shape" not in response.data.decode()
    assert "Lomond Shape" not in response.data.decode()
    assert "72" not in response.data.decode()
    assert "Yes" not in response.data.decode()

每次我尝试运行 pytest --cov=app 以查看覆盖率时,我都会收到这些错误

  sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: frankendama
  ======== 6 Failed,1 passed,21 warnings in 5.72s =========
  

总的来说,我很难过,任何建议非常欢迎!

解决方法

我发现coverage不会导入模块,所以当我运行时: pytest tests/test_unit.py --cov=. 我得到了全面的覆盖并且我的所有测试都通过了。 我还从 test.db 中删除了 SQLALCHEMY_DATABASE_URI="sqlite:///test.db",这解决了我原来的问题。