【问题标题】:Why am I expecting a status code of 200 but got a status code of 404 while unit testing in python?为什么我期望状态代码为 200,但在 python 中进行单元测试时却得到状态代码 404?
【发布时间】:2020-10-08 05:21:54
【问题描述】:

我正在 python 中使用 unittest 和 pytest 为一个文件编写一个单元测试用例。在众多功能中,我无法理解为什么它不能作为成功通过的测试用例执行。 这是一个显示设置页面的函数,调用成功后会显示一个html页面。

@app.route('/settings', methods=['GET', 'POST'])
@login_required
def settings():
    global application_inst
    if request.method == 'POST':
        print("Setting changed")

    return render_template('settings.html', user=session['user'], application=application_inst)

函数的单元测试用例如下:

class MyApp(unittest.TestCase):
    def setUp(self):
        self.app = create_app(db)
        self.client = self.app.test_client(self)

        with self.app.app_context():
            # create all tables
            db.create_all()

    def tearDown(self):
        pass

    def test_settings_passed(self):
        response = self.client.get('/settings', follow_redirects=True)
        self.assertEqual(response.status_code, 200)

我在堆栈跟踪中得到的错误是:

test_app.py::MyApp::test_settings_passed FAILED                          [100%]ENV :default
############ INIT ############
############ INIT ############
############ INIT ############

 
200 != 404

Expected :404
Actual   :200
<Click to see difference>

请帮帮我。

【问题讨论】:

  • 您正在比较相同的状态代码两次,并期望第二次得到不同的输出?同样with pytest.raises(AssertionError) 在那一点上没有意义,也许你想做别的事情?顺便说一句 - 不要混合 unittest 和 pytest - 其中一些可能有效,有些则不会。改用其中之一。
  • 即使我在遇到相同错误时检查相同的状态代码。我想看看我对 /settings 的调用是否让我得到状态码 200。 @MrBeanBremen
  • 啊,好吧,您在assertEqual 中反转了预期和实际参数,我没有注意到。所以你期待 200,但得到 404。
  • 你是对的!为什么它会以它发生的方式发生? @MrBeanBremen
  • @SimeonNedkov RuntimeError:应用程序无法为请求独立的 URL 生成创建 URL 适配器。您可以通过设置 SERVER_NAME 配置变量来解决此问题。

标签: python unit-testing flask python-unittest


【解决方案1】:

尝试更改,以便 self.client 将在 app_context() 内执行,例如

class MyApp(unittest.TestCase):
    def setUp(self):
        self.app = create_app(db)
        self.client = self.app.test_client(self)

        with self.app.app_context():
            # create all tables
            db.create_all()

    def tearDown(self):
        pass

    def test_settings_passed(self):
        with self.app.app_context():
            response = self.client.get('/settings', follow_redirects=True)
            self.assertEqual(response.status_code, 200)

我创建了相同的场景,无论有无app_context,它都适用于我。我也使用这个命令来执行测试:

python -m unittest tests/test_the_test.py 

这还取决于您如何设置应用程序。 使用python3.7,例如下面的。

我的是这样的:

├── app.py
├── index
│   ├── __init__.py
│   └── routes.py
└── tests
    └── test_the_test.py

我的app.py是这样的:

from flask import Flask



def create_app():
    app = Flask(__name__)
    from index import bp
    app.register_blueprint(bp)
    return app

我的index/__init__.py 是这样的:

from flask import Blueprint

bp = Blueprint(__name__, '/')

from index import routes

我的index/routes.py 是这样的:

from index import bp
from flask import jsonify

@bp.route('/test')
def test():
    print('goes here?')
    return jsonify({'result': True})

我的tests/test_the_test.py 像这样:

import unittest

from app import create_app


class MyApp(unittest.TestCase):
    def setUp(self):
        self.app = create_app()
        self.client = self.app.test_client(self)

    def tearDown(self):
        pass

    def test_settings_passed(self):
        response = self.client.get('/test', follow_redirects=True)
        self.assertEqual(response.status_code, 200)

    def test_settings_failed(self):
        response = self.client.get('/test_not_exist', follow_redirects=True)
        self.assertEqual(response.status_code, 404)

执行这个命令:

python -m unittest tests/test_the_test.py 

我的设置工作正常,在端点存在和不存在时进行测试并给出正确的结果。

结果:

python -m unittest tests/test_the_test.py 
.goes here?
.
----------------------------------------------------------------------
Ran 2 tests in 0.006s

OK

【讨论】:

  • 感谢您为解决问题所做的努力,尽管我们的项目结构和代码方式相同(除了python版本(我的是3.6))我的问题仍然存在。不过我会接受你的回答。
  • 基本上404错误表示找不到页面,你确定'/settings'是一个正确的端点吗?因为如果self.client 无法访问该应用程序,您将收到不同的消息。也许端点 '/settings' 被错误地调用,也许它以不同的方式开始,例如'/some/structure/settings'?
  • @curious_guy,你试过我的例子吗?随便设置看看能不能用,那说明可能是你的app设置的问题,也可能是上面提到的endpoint问题?
  • 是的@simkus 我试过你的,它工作正常。我将不得不寻找我的应用程序是如何设置的,您的回答对我来说确实是一线希望,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 2021-10-23
  • 2022-01-17
  • 2017-01-20
  • 1970-01-01
相关资源
最近更新 更多