Python Behave 框架写的自动化测试,有必要上 ORM 吗?
如题,最近在看 PonyORM,感觉测试的代码中加入 ORM 有很多不方便的地方啊,也可能是不会用,求教
Python Behave 框架写的自动化测试,有必要上 ORM 吗?
ORM 最大的好处是:摆脱了裸写 SQL 造成的对特定数据库方言的依赖,便于在不同数据库之间迁移或部署。
只有一两个表的情况用 ORM 没有太大意义体现不出来什么优势。大量的表和关系要管理时候用起来才值得。还有就是多人合作的项目中便于统一接口集中控制。
目前建议你用 sqlalchemy,这种冷门的 ORM 最好别学,大概率耽误功夫。
这问题挺实际的。我的看法是:通常没必要,但特定场景下可以考虑。
Behave做的是BDD验收测试,重点是验证业务行为,不是数据操作。大部分情况下,直接用数据库驱动(如psycopg2、pymysql)或者测试框架的数据夹具更直接。
什么时候可能需要ORM:
- 你的测试需要操作复杂的对象关系,手动拼SQL太麻烦
- 测试逻辑和产品代码共享同一个数据模型层
- 需要测试ORM层本身的逻辑
示例对比:
# 直接使用数据库驱动(推荐大多数情况)
import psycopg2
def insert_user_direct(db_config, name, email):
"""直接SQL插入"""
conn = psycopd2.connect(**db_config)
cursor = conn.cursor()
cursor.execute(
"INSERT INTO users (name, email) VALUES (%s, %s) RETURNING id",
(name, email)
)
user_id = cursor.fetchone()[0]
conn.commit()
cursor.close()
conn.close()
return user_id
# 使用ORM(如SQLAlchemy)
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
email = Column(String)
def insert_user_orm(db_url, name, email):
"""通过ORM插入"""
engine = create_engine(db_url)
Session = sessionmaker(bind=engine)
session = Session()
user = User(name=name, email=email)
session.add(user)
session.commit()
user_id = user.id
session.close()
return user_id
直接SQL的优点:
- 测试更接近真实查询
- 没有ORM的抽象开销
- 更容易控制数据库状态
- 依赖更少,运行更快
ORM的优点:
- 对象操作更符合业务思维
- 复用产品代码的模型定义
- 避免SQL语法错误
建议: 除非测试ORM本身,否则优先用直接数据库操作。
sqlalchemy 听说非常难用,PonyORM peewee 稍微简单点
要说 python 的 ORM 库里面 sqlacchemy 基本上是事实标准,你要是用的生产环境以后也有很多需求,非它莫数, 能很好地支持事务和分表就这两项其它的 ORM 就没的比。Pony 和 peewee 之类的只是小玩具。而且 sqlalchemy 在其它好几语言都有实现比如 golang 之类的。
另一个好用的 ORM 就算是 Django 内置带的那个了,其实是从 RoR 那里克隆来的用的 Active Record 方式,上手容易文档丰富,用起来比较直观,不象 sqlachemy 那么拧巴。因为 sqlachemy 用的 data mapper 实现,必须使用另外的持久层来保持与数据库的交互,好处是代码和数据库也是完全隔离的。

