Python 2.7 python-Flask test_client()不';无法通过pytest获得request.authorization

Python 2.7 python-Flask test_client()不';无法通过pytest获得request.authorization,python-2.7,unit-testing,flask,pytest,werkzeug,Python 2.7,Unit Testing,Flask,Pytest,Werkzeug,使用pytest测试我的flask应用程序时出现问题。 应用程序需要基本身份验证,这是烧瓶中请求授权的参数。 但是对于pytest,flask.test\u client()没有request.authorization 以下是夹具的代码: @pytest.yield_fixture(scope='session') def app() app = create_app() # some setup code ctx = app.app_context() c

使用pytest测试我的flask应用程序时出现问题。
应用程序需要基本身份验证,这是烧瓶中请求授权的参数。
但是对于pytest,flask.test\u client()没有
request.authorization

以下是夹具的代码:

@pytest.yield_fixture(scope='session')
def app()
    app = create_app()

    # some setup code

    ctx = app.app_context()
    ctx.push()
    yield app
    ctx.pop()
    # some teadown code

@pytest.fixture
def test_client(app)
     return app.test_client()
以下是测试代码:

def test_index(test_client):
    res = test_client.get("/", headers={"Authorization": "Basic {user}".format(user=b64encode(b"test_user"))})
    assert res.status_code == 200
运行此测试时,出现以下错误:

E       assert 401 == 200
E        +  where 401 = <Response streamed [401 UNAUTHORIZED]>.status_code
E断言401==200
E+式中401=状态\代码
不仅身份验证失败,而且request.authorization没有任何值(无)。
为什么会这样?有什么解决办法吗


谢谢。

HTTP基本身份验证的凭据必须包含用户名和密码,并用冒号分隔。如果您仍在使用python 2,请尝试以下方法:

def测试索引(测试客户端):
凭证=B64编码(b“测试用户:测试密码”)
res=test_client.get(“/”,headers={“Authorization”:“Basic{}.format(credentials)})
assert res.status_code==200
Python3对数据健全性有点严格,因此在将字节发送到服务器之前,必须确保字节已正确解码:

def测试索引(测试客户端):
凭证=B64编码(b“测试用户:测试密码”)。解码('utf-8')
res=test_client.get(“/”,headers={“Authorization”:f“Basic{credentials}”)
assert res.status_code==200

我找到了这个解决方案。也许它可以帮助某人:

from requests.auth import _basic_auth_str
headers = {
   'Authorization': _basic_auth_str(username, password),
}
您只需使用库“请求”

from requests.auth import _basic_auth_str
headers = {
   'Authorization': _basic_auth_str(username, password)
}
这在python 3.6和2.7上都适用,而以下仅在2.7上适用:

res = test_client.get("/", headers={"Authorization": "Basic {user}".format(user=b64encode(b"test_user:test_password"))})

如果您使用的是新版本的python(在我的例子中是3.7),那么应该解码base64字符串。它返回字节,在stringify之后 b'basestring'不正确

>base64.b64encode(b“用户:密码”)
b'dXNlcjpwYXNzd29yZA=='
>>>base64.b64encode(b“用户:密码”).decode()
'dXNlcjpwYXNzd29yZA=='
所以,现在我的测试看起来像

类TestServer(unittest.TestCase):
def设置(自身)->无:
self.client=app.test_client()
user_credentials=base64.b64编码(b“用户:密码”).decode()
self.headers={“授权”:“基本{}.format(用户凭证)}

以下是我如何为需要使用自定义令牌进行身份验证的API编写单元测试的方法

在conftest.py文件中,使用以下方法 来自connexion import FlaskApp logging.basicConfig(级别=logging.DEBUG) API_FOLDER=pathlib.Path(_file_uuu).parent/'..' @pytest.fixture(scope=“session”) def unsecure_client():#这用于不需要授权的路由测试。 cxn_app=烧瓶app, 端口=5001, 规范\u目录=API\u文件夹, debug=True, 选项={“调试”:True,“招摇过市”:False}) cxn_app.add_api('your_api.yaml',resolver=RestyPlusResolver('api.routes')) cxn_app._spec_file='your_api.yaml' #连接将Flask应用程序存储在app cxn_app.app.config['SOME_KEY']=config.config['SOME_KEY'] 烧瓶_jwt.jwt(cxn_app.app,无,无) 烧瓶容器容器(cxn容器应用程序) cxn_app.app.app_context() 返回cxn_app.app.test_client() @pytest.fixture(scope=“session”) def secure_client():#这用于需要授权的路由测试。 cxn_app=烧瓶app, 端口=5001, 规范\u目录=API\u文件夹, debug=True, 选项={“调试”:True,“招摇过市”:False}) cxn_app.add_api('open_api.yaml',解析器=RestyPlusResolver('api.routes')) cxn_app._spec_file='openapi.yaml' #连接将Flask应用程序存储在app cxn_app.app.config['SOME_KEY']=config.config['SOME_KEY'] 烧瓶_jwt.jwt(cxn_app.app,无,无) 烧瓶容器容器(cxn容器应用程序) cxn_app.app.app_context() client=cxn_app.app.test_client() json_dict={'user':'your_username','password':'your_pwd'} #调用auth以获取令牌,该令牌可用于需要身份验证的API调用。 #有关如何在路由的pytest中使用此选项,请参见下文。 response=client.post('/auth',data=json.dumps(json_dict),content_type='application/json') data=json\u的响应(响应) setattr(客户端“_令牌”,数据[“令牌]) 返回客户端 def post_json(客户端、url、json目录): “”“将字典json作为json发送到指定的url”“” 返回client.post(url,data=json.dumps(json\u dict),content\u type='application/json') def json_的_响应(响应): “”“从响应中解码json”“” 返回json.load(response.data.decode('utf8')) ###需要身份验证的API的Pytest示例。 def测试我的帖子(模拟、安全客户端): json_dict={'id':'TEST_01','phone':'phone_02'} mocker.patch('yourapi.services.User.create_User',返回_值=(“Success”,201)) response=secure\u client.post('/user',data=json.dumps(json\u dict),content\u type='application/json',headers={'X-Auth':secure\u client.\u token}) data=json\u的响应(响应) assert response.status_code==201
assert data==“Success”您好,谢谢。现在它工作正常,我可以看到带有用户名和密码的
request.authorization