diff --git a/examples/data/sqlite.db b/examples/data/sqlite.db new file mode 100644 index 00000000..49485ef3 Binary files /dev/null and b/examples/data/sqlite.db differ diff --git a/examples/sql/test_sql_demo.py b/examples/sql/test_sql_demo.py new file mode 100644 index 00000000..b0ed6f5f --- /dev/null +++ b/examples/sql/test_sql_demo.py @@ -0,0 +1,36 @@ +import sys +from pathlib import Path + +from httprunner.database.engine import DBEngine + +sys.path.insert(0, str(Path(__file__).parent.parent)) + +from httprunner import HttpRunner, Config, Step, RunSqlRequest # noqa:E402 + + +class TestCaseDemoSqlite(HttpRunner): + config = Config("run sqlite demo") + + teststeps = [ + Step( + RunSqlRequest("执行一个sqlite demo") + .fetchmany("select* from student;", 5) + .extract() + .with_jmespath("[0].name", "name") + .validate() + .assert_equal( + "[0]", + { + "id": 1, + "name": "Jack", + "fullname": {"first_name": "Jack", "last_name": "Tomson"}, + }, + ) + .assert_equal("[0].fullname.first_name", "Jack") + ) + ] + + def test_start(self): + eg = DBEngine(db_uri="sqlite:///../data/sqlite.db") + self.with_db_engine(eg) + super().test_start() diff --git a/httprunner/database/engine.py b/httprunner/database/engine.py index 7919739c..9bddad1d 100644 --- a/httprunner/database/engine.py +++ b/httprunner/database/engine.py @@ -13,7 +13,7 @@ class DBEngine(object): """ engine = create_engine(db_uri) - self.session = sessionmaker(bind=engine)() + self.session = sessionmaker(bind=engine, autocommit=True)() @staticmethod def value_decode(row: dict): @@ -38,11 +38,12 @@ class DBEngine(object): def _fetch(self, query, size=-1, commit=True): result = self.session.execute(query) - self.session.commit() if commit else 0 if query.upper()[:6] == "SELECT": if size < 0: al = result.fetchall() al = [dict(el) for el in al] + for el in al: + self.value_decode(el) return al or None elif size == 1: on = dict(result.fetchone()) @@ -51,6 +52,8 @@ class DBEngine(object): else: mny = result.fetchmany(size) mny = [dict(el) for el in mny] + for el in mny: + self.value_decode(el) return mny or None elif query.upper()[:6] in ("UPDATE", "DELETE", "INSERT"): return {"rowcount": result.rowcount} @@ -75,4 +78,7 @@ class DBEngine(object): if __name__ == "__main__": - db = DBEngine(f"mysql+pymysql://xxxxx:xxxxx@10.0.0.1:3306/dbname?charset=utf8mb4") + # db = DBEngine(f"mysql+pymysql://xxxxx:xxxxx@10.0.0.1:3306/dbname?charset=utf8mb4") + db = DBEngine(f"sqlite:////Users/bytedance/HttpRunner/examples/data/sqlite.db") + print(db.fetchmany("select* from student", 5)) + print(db.fetchmany("select* from student", 5)) diff --git a/httprunner/step_sql_request.py b/httprunner/step_sql_request.py index ac90af58..128264d2 100644 --- a/httprunner/step_sql_request.py +++ b/httprunner/step_sql_request.py @@ -105,7 +105,12 @@ def run_step_sql_request(runner: HttpRunner, step: TStep) -> StepResult: if USE_ALLURE: import allure - allure.attach(sql_request_print, name="sql request details", attachment_type=allure.attachment_type.TEXT) + + allure.attach( + sql_request_print, + name="sql request details", + attachment_type=allure.attachment_type.TEXT, + ) logger.info(f"Executing SQL: {parsed_request_dict['sql']}") if step.sql_request.method == SqlMethodEnum.FETCHONE: sql_resp = runner.db_engine.fetchone(parsed_request_dict["sql"]) @@ -125,15 +130,31 @@ def run_step_sql_request(runner: HttpRunner, step: TStep) -> StepResult: raise SqlMethodNotSupport( f"step.sql_request.method {parsed_request_dict['method']} not support" ) + # log response sql_response_print = "====== sql response details ======\n" - for k, v in sql_resp.items(): - v = utils.omit_long_data(v) - sql_response_print += f"{k}: {repr(v)}\n" - + if isinstance(sql_resp, dict): + for k, v in sql_resp.items(): + v = utils.omit_long_data(v) + sql_response_print += f"{k}: {repr(v)}\n" + elif isinstance(sql_resp, list): + sql_response_print += f"count: {len(sql_resp)}\n" + sql_response_print += "-" * 34 + "\n" + for el in sql_resp: + for k, v in el.items(): + v = utils.omit_long_data(v) + sql_response_print += f"{k}: {repr(v)}\n" + sql_response_print += "-" * 34 + "\n" + elif sql_resp is None: + sql_response_print += "None\n" if USE_ALLURE: import allure - allure.attach(sql_request_print, name="sql response details", attachment_type=allure.attachment_type.TEXT) + + allure.attach( + sql_response_print, + name="sql response details", + attachment_type=allure.attachment_type.TEXT, + ) resp_obj = SqlResponseObject(sql_resp, parser=runner.parser) step_variables["sql_response"] = resp_obj