Flask+ Dependency-injecter+pytest 写测试类

这篇具有很好参考价值的文章主要介绍了Flask+ Dependency-injecter+pytest 写测试类。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在使用这几个在做项目,因为第一次用这个,所以不免有些问题。总结下踩的坑

1.测试类位置

Flask+ Dependency-injecter+pytest 写测试类,Python,pytest

首先测试类约定会放在tests里面,不然有可能发生引入包的问题,会报错某些包找不到。

2. 测试类依赖注入

这里我就用的真实的数据库操作,但是我用了一个专门为测试写的事务管理,所有操作都不会commit而是会rollback,相当于一个内存数据库了,只会在内存里面,不会提交,你也可以直接用内存数据库或者mock,

# tests/test_app.py
import pytest
from main.application import create_app
from main.config.database_config import DatabaseConfig
from main.containers import Container
from dependency_injector.wiring import inject, Provide
from main.services.common_service.db_access.domain.user import User
from main.services.common_service.db_access.service.user_service import UserService
from dependency_injector.providers import Factory
from main.services.common_service.db_access.repository.impl.user_repository_impl import UserRepositoryImpl

#获取app
@pytest.fixture
def app():
    app = create_app()
    with app.app_context():
        yield app
#获取user_service
@pytest.fixture
def user_service(app):
    with app.app_context():
        user_repo=UserRepositoryImpl()
        db=app.container.db()
        yield UserService(user_repository=user_repo,session_factory=db.force_rowback_session)
        
#测试方法,需要传入user_serivice,会从上面加了@pytest.fixture注解获取同名方法进行注入
def test_create_user(user_service):
    user=user_service.create_user()
    assert user is not None

我的userservice需要传入两个参数,一个是repo的实现类,一个是sqla的session

"""Containers module."""

import os
from dependency_injector import containers, providers

from main.config.database_config import DatabaseConfig



class Container(containers.DeclarativeContainer):
  
    # wiring_config = containers.WiringConfiguration(auto_wire=True)
    wiring_config = containers.WiringConfiguration(packages=[
        "main.config", 
        "main.web.controller",
        "main"
    ])
    config_path = os.path.join(os.path.dirname(__file__), "../config.yml")
    config = providers.Configuration(yaml_files=[config_path])
    
    db=providers.Singleton(DatabaseConfig,db_url=config.db.url)

有个很重要的一点就是
这里如果写成这样过的话,启动项目是没有什么问题。但是测试类的时候就会加载不到,就会导致需要config的类加载不到你需要的配置。

config = providers.Configuration(yaml_files=['config.yml'])

所以必须写成这样

config_path = os.path.join(os.path.dirname(__file__), "../config.yml")
config = providers.Configuration(yaml_files=[config_path])

事务控制 

"""Database module."""

from contextlib import contextmanager, AbstractContextManager
from typing import Callable

from sqlalchemy import create_engine, orm,event
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from datetime import datetime

from main.services.common_service.db_access.domain.common_field_entity import CommonEntity
Base = declarative_base()

class DatabaseConfig:

    def __init__(self, db_url: str) -> None:
        self._engine = create_engine(db_url, echo=True)
        self._session_factory = orm.scoped_session(
            orm.sessionmaker(
                autocommit=False,
                autoflush=False,
                expire_on_commit=False,
                bind=self._engine,
            ),
        )

    def create_database(self) -> None:
        Base.metadata.create_all(self._engine)


    @contextmanager
    def session(self) -> Callable[..., AbstractContextManager[Session]]:
        session: Session = self._session_factory()
        try:
            yield session
        except Exception:
            session.rollback()
            raise
        else:
            if session._transaction.is_active:
                session.commit()
            session.close()
            
    @contextmanager
    #专门负责测试类的回滚操作,不论任何情况,都进行回滚操作
    def force_rowback_session(self) -> Callable[..., AbstractContextManager[Session]]:
        session: Session = self._session_factory()
        try:
            yield session
        except Exception:
            session.rollback()
            raise
        else:
            session.rollback()
            #rollback之后就不能再close了,否则就会报错
            #session.close()

    @event.listens_for(CommonEntity, 'before_insert', propagate=True)
    def before_insert_listener(self, mapper, target):
        # 在创建时自动更新 created_dt,version
        target.created_dt = datetime.now()
        target.created_by = 'MAAS'
        target.version = 1
        
    @event.listens_for(CommonEntity, 'before_update', propagate=True)
    def before_update_listener(self, mapper, target):
        # 在更新时自动更新 updated_dt,version
        target.updated_dt = datetime.now()
        target.updated_by = 'MAAS'
        target.version += 1

运行测试

就直接到文件目录,执行pytest命令就可以了,没有pytest就pip install 一下就行了文章来源地址https://www.toymoban.com/news/detail-813499.html

pytest xxx.py

到了这里,关于Flask+ Dependency-injecter+pytest 写测试类的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ASP.NET Core 中的 Dependency injection

    依赖注入 (Dependency Injection,简称DI)是为了实现 各个类之间的依赖 的 控制反转 (Inversion of Control,简称IoC )。 ASP.NET Core 中的Controller 和 Service 或者其他类都支持依赖注入。 依赖注入术语中, Service 是一个为其他对象提供服务的类 **。 Service 不是一个Web Service,与Web Serv

    2024年02月11日
    浏览(39)
  • Angular 17+ 高级教程 – Dependency Injection 依赖注入

    本来是想先介绍 Angular Component 的,但 Component 里面会涉及到一些 Dependency Injection (简称 DI) 的概念,所以还是先介绍 DI 吧。 温馨提醒:如果你对 JS class、prototype 不太熟悉的话,建议你先看这篇 JavaScript – 理解 Object, Class, This, Prototype, Function, Mixins   首先我们有一个 class Ser

    2024年03月09日
    浏览(64)
  • Go 开源库运行时依赖注入框架 Dependency injection

    一个Go编程语言的运行依赖注入库。依赖注入是更广泛的控制反转技术的一种形式。它用于增加程序的模块化并使其具有可扩展性。 依赖注入是更广泛的控制反转技术的一种形式。它用于增加程序的模块化并使其具有可扩展性。 Providing Extraction Invocation Lazy-loading Interfaces Gro

    2024年02月07日
    浏览(53)
  • Angular(二) Understanding Dependency Injection for angular

    Angular https://angular.io/guide/dependency-injection Denpendency Injection,  or DI, is one of fundamental concepts for angular, DI is writed by angular framework and allows classes with  Angular decorators,  such as Components, directives, Piples and Injectables , to configure dependencies that they need.  Two main roles exists in DI system: dependency

    2024年02月09日
    浏览(39)
  • Angular 17+ 高级教程 – Component 组件 の Dependency Injection & NodeInjector

    在 Dependency Injection 依赖注入 文章中,我们学习了 50% 的 Angular DI 知识,由于当时还不具备组件知识,所以我们无法完成另外 50% 的学习。 经过了几篇组件教程后,现在我们已经具备了基础的组件知识,那这一篇我们便来完成 Angular DI 所有内容吧。   Angular in Depth – A Deep

    2024年03月09日
    浏览(44)
  • Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC

    Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的 反射机制 。简单来说, 反射机制指的是程序在运行时能够获取自身

    2024年02月09日
    浏览(62)
  • Python+Pytest压力测试

    在现代Web应用程序中,性能是至关重要的。为了确保应用程序能够在高负载下正常运行,我们需要进行性能测试。 今天,应小伙伴的提问, 老向老师来写一个Pytest进行压力测试的简单案例。 这个案例的测试网站我们就隐藏了,不过网站的基本情况是: 阿里框架:FastAdmin.n

    2024年02月12日
    浏览(93)
  • Python测试之Pytest详解

    当涉及到 python 的测试框架时, pytest 是一个功能强大且广泛应用的第三方库。它提供简洁而灵活的方式来编写和执行测试用例,并具有广泛的应用场景。下面是 pytest 的介绍和详细使用说明: pytest 是一个用于 python 单元测试的框架,它建立在标准的 unittest 模块之上,并提供

    2024年02月05日
    浏览(33)
  • Python测试框架 Pytest —— mock使用(pytest-mock)

    安装:pip install pytest-mock 这里的mock和unittest的mock基本上都是一样的,唯一的区别在于pytest.mock需要导入mock对象的详细路径。 先将需要模拟的天气接口,以及需要模拟的场景的代码写好,然后在进行遵循pytest的用例规范进行书写关于mock的测试用例 通过上述代码,提供pytest中

    2024年02月09日
    浏览(46)
  • pytest上一个用例失败后,跳过下一个用例(用例a失败,跳过与之关联的b用例)。pytest.mark.dependency用例依赖。

    实际写代码的时候会遇到这样的问题,以登录登出为例,登录失败后我们怎么跳过登出的用例,因为登录失败后测试登出没有意义结果里的报错也没有意义。 这里使用到了pytest的三方插件,dependency方法。官方文档大家可以参考下:Using pytest-dependency — pytest-dependency 注: 此方

    2023年04月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包