【问题标题】:Creating custom 'test' command to run a test suite for a Flask application创建自定义“测试”命令以运行 Flask 应用程序的测试套件
【发布时间】:2018-09-06 13:38:23
【问题描述】:

我们正在使用一些自定义命令扩展 Flask-cli。命令test 就是其中之一:

# run.py: specified by FLASK_APP
# This is the Flask application object
app = create_app(os.getenv('FLASK_ENV') or 'default')

@app.cli.command()
def test():
    """Run the unit tests."""
        
    tests = unittest.TestLoader().discover('tests')

    test_runner = unittest.TextTestRunner()
    test_runner.run(tests)

然而,一个典型的测试(使用 Python 的内置 unittest 模块)看起来像 这是基于here 描述的样式。

# some-tests.py: unittest-based test case.
class SomeTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app('testing')
        self.app_context = self.app.app_context()
        self.app_context.push()

    def tearDown(self):
        self.app_context.pop()

    def test_load(self):
        pass

我显然在这里遇到了一个反模式:我已经使用默认 (development) 配置初始化了一个烧瓶对象,因为我需要它用于 @app.cli.command() 装饰器,这一切都发生在 run.py 中。但是,一旦我在some-tests.py 中运行测试设置函数,我就必须以某种方式使用testing 配置获取一个 Flask 对象,例如通过使用 testing 配置重新创建一个 Flask 应用程序,就像现在发生的那样。

我想知道如何实现flask-cli 测试命令,其中只创建一个Flask 对象,该对象在各种测试用例中重复使用,而无需明确地将环境设置为testing 在我在命令行上运行 flask test 之前。

【问题讨论】:

    标签: python-3.x testing flask flask-cli


    【解决方案1】:

    我不确定这个答案是否符合您的要求,但这就是我尝试解决这个问题的方式。不幸的是,如果你想在 Flask 中使用默认的 CLI 界面,那么你需要调用 create_app 来调用 flask test 命令。您可以尝试使用pytest。它允许您创建可以跨多个测试用例使用的夹具。例如,在您的 tests 包中创建名为 conftest.py 的文件并声明一些默认的固定装置,如下所示:

    @pytest.fixture
    def app():
        return create_app('testing')
    
    
    @pytest.fixture
    def client(app):
        return app.test_client()
    
    
    @pytest.fixture
    def database(app):
        _db.app = app
    
        with app.app_context():
            _db.create_all()
    
        yield _db
    
        _db.session.close()
        _db.drop_all()
    
    

    然后在您的测试用例文件(例如 test_login.py)中,您可以像这样使用这些固定装置:

    # Notice argument names are the same as name of our fixtures
    # You don't need to import fixtures to this file - pytest will  
    # automatically recognize fixtures for you
    def test_registration(app, client):
        response = client.post(
            '/api/auth/login',
            json={
                'username': 'user1',
                'password': '$dwq3&jNYGu'
            })
        assert response.status_code == 200
        json_data = response.get_json()
        assert json_data['access_token']
        assert json_data['refresh_token']
    

    这种方法最好的一点是您不需要创建setUptearDown 方法。然后您可以为您的应用创建test cli 命令:

    import pytest
    
    @app.cli.command()
    def test():
        '''
        Run tests.
        '''
        pytest.main(['--rootdir', './tests'])
    

    然后这样称呼它flask test

    【讨论】:

    • 发现它很有用。小问题,您如何使用这种方法发布结果?例如类似 --junitxml results.xml
    • @RajatArora 我认为您应该查看 pytest 文档以查看是否有此标志。
    猜你喜欢
    • 2011-05-18
    • 2012-03-04
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 2015-11-25
    • 1970-01-01
    相关资源
    最近更新 更多