diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 1f284dc..b036e63 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -12,12 +12,9 @@ jobs: fail-fast: false matrix: include: - - os: 'ubuntu-latest' - python-version: '3.7' - rf-version: '3.2.2' - os: 'ubuntu-latest' python-version: '3.8' - rf-version: '4.1.3' + rf-version: '5.0.1' - os: 'ubuntu-latest' python-version: '3.9' rf-version: '5.0.1' @@ -29,7 +26,7 @@ jobs: rf-version: '6.1.1' - os: 'ubuntu-latest' python-version: '3.12' - rf-version: '7.0a1' + rf-version: '7.0.1' runs-on: ${{ matrix.os }} steps: diff --git a/README.md b/README.md index 6ab6327..f59438a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It requires an appropriate **Python module to be installed separately** - depend The library consists of some keywords designed to perform different checks on your database. Here you can find the [keyword docs](http://marketsquare.github.io/Robotframework-Database-Library/). -Wath the [talk at Robocon 2024 about the Database Library update](https://youtu.be/A96NTUps8sU) +Wath the [talk at Robocon 2024 about the Database Library update](https://youtu.be/A96NTUps8sU). [![Talk at Robocon 2024 about the Database Library update](http://img.youtube.com/vi/A96NTUps8sU/0.jpg)](https://youtu.be/A96NTUps8sU) @@ -18,8 +18,7 @@ Wath the [talk at Robocon 2024 about the Database Library update](https://youtu. ``` pip install robotframework-databaselibrary ``` -# Usage examples -## Basic usage +# Basic usage examples ```RobotFramework *** Settings *** Library DatabaseLibrary @@ -29,25 +28,40 @@ Test Setup Connect To My Oracle DB Connect To My Oracle DB Connect To Database ... oracledb - ... dbName=db - ... dbUsername=my_user - ... dbPassword=my_pass - ... dbHost=127.0.0.1 - ... dbPort=1521 + ... db_name=db + ... db_user=my_user + ... db_password=my_pass + ... db_host=127.0.0.1 + ... db_port=1521 *** Test Cases *** +Get All Names + ${Rows}= Query select FIRST_NAME, LAST_NAME from person + Should Be Equal ${Rows}[0][0] Franz Allan + Should Be Equal ${Rows}[0][1] See + Should Be Equal ${Rows}[1][0] Jerry + Should Be Equal ${Rows}[1][1] Schneider + Person Table Contains Expected Records - ${output}= Query select LAST_NAME from person - Length Should Be ${output} 2 - Should Be Equal ${output}[0][0] See - Should Be Equal ${output}[1][0] Schneider + ${sql}= Catenate select LAST_NAME from person + Check Query Result ${sql} contains See + Check Query Result ${sql} equals Schneider row=1 + +Wait Until Table Gets New Record + ${sql}= Catenate select LAST_NAME from person + Check Row Count ${sql} > 2 retry_timeout=5s Person Table Contains No Joe ${sql}= Catenate SELECT id FROM person - ... WHERE FIRST_NAME= 'Joe' - Check If Not Exists In Database ${sql} + ... WHERE FIRST_NAME= 'Joe' + Check Row Count ${sql} == 0 ``` -## Handling multiple database connections +See more examples in the folder `tests`. + +# Handling multiple database connections +The library can handle multiple connections to different databases using *aliases*. +An alias is set while creating a connection and can be passed to library keywords in a corresponding argument. +## Example ```RobotFramework *** Settings *** Library DatabaseLibrary @@ -56,9 +70,21 @@ Test Teardown Disconnect From All Databases *** Keywords *** Connect To All Databases - Connect To Database psycopg2 db db_user pass 127.0.0.1 5432 + Connect To Database + ... psycopg2 + ... db_name=db + ... db_user=db_user + ... db_password=pass + ... db_host=127.0.0.1 + ... db_port=5432 ... alias=postgres - Connect To Database pymysql db db_user pass 127.0.0.1 3306 + Connect To Database + ... pymysql + ... db_name=db + ... db_user=db_user + ... db_password=pass + ... db_host=127.0.0.1 + ... db_port=3306 ... alias=mysql *** Test Cases *** @@ -73,7 +99,130 @@ Switching Default Alias Execute Sql String drop table XYZ ``` -See more examples in the folder `tests`. + + +# Using configuration file +The `Connect To Database` keyword allows providing the connection parameters in two ways: +- As keyword arguments +- In a configuration file - a simple list of _key=value_ pairs, set inside an _alias_ section. + +You can use only one way or you can combine them: +- The keyword arguments are taken by default +- If no keyword argument is provided, a parameter value is searched in the config file + +Along with commonly used connection parameters, named exactly as keyword arguments, a config file +can contain any other DB module specific parameters as key/value pairs. +If same custom parameter is provided both as a keyword argument *and* in config file, +the *keyword argument value takes precedence*. + +The path to the config file is set by default to `./resources/db.cfg`. +You can change it using an according parameter in the `Connect To Database` keyword. + +A config file *must* contain at least one section name - +the connection alias, if used (see [Handling multiple database connections](#handling-multiple-database-connections)), or +`[default]` if no aliases are used. + +## Config file examples +### Config file with default alias (equal to using no aliases at all) +``` +[default] +db_module=psycopg2 +db_name=yourdbname +db_user=yourusername +db_password=yourpassword +db_host=yourhost +db_port=yourport +``` +### Config file with a specific alias +``` +[myoracle] +db_module=oracledb +db_name=yourdbname +db_user=yourusername +db_password=yourpassword +db_host=yourhost +db_port=yourport +``` + +### Config file with some params only +``` +[default] +db_password=mysecret +``` +### Config file with some custom DB module specific params +``` +[default] +my_custom_param=value +``` + +# Inline assertions +Keywords, that accept arguments ``assertion_operator`` and ``expected_value``, +perform a check according to the specified condition - using the [Assertion Engine](https://github.com/MarketSquare/AssertionEngine). + +## Examples +```RobotFramework +Check Row Count SELECT id FROM person == 2 +Check Query Result SELECT first_name FROM person contains Allan +``` + +# Retry mechanism +Assertion keywords, that accept arguments ``retry_timeout`` and ``retry_pause``, support waiting for assertion to pass. + +Setting the ``retry_timeout`` argument enables the mechanism - +in this case the SQL request and the assertion are executed in a loop, +until the assertion is passed or the ``retry_timeout`` is reached. +The pause between the loop iterations is set using the ``retry_pause`` argument. + +The argument values are set in [Robot Framework time format](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#time-format) - e.g. ``5 seconds``. + +The retry mechanism is disabled by default - ``retry_timeout`` is set to ``0``. + +## Examples +```RobotFramework +${sql}= Catenate SELECT first_name FROM person +Check Row Count ${sql} == 2 retry_timeout=10 seconds +Check Query Result ${sql} contains Allan retry_timeout=5s retry_pause=1s +```` + +# Logging query results +Keywords, that fetch results of a SQL query, print the result rows as a table in RF log. +- A log head limit of *50 rows* is applied, other table rows are truncated in the log message. +- The limit and the logging in general can be adjusted any time in your tests using the Keyword `Set Logging Query Results`. + +You can also setup the limit or disable the logging during the library import. +## Examples +```RobotFramework +*** Settings *** +# Default behavior - logging of query results is enabled, log head is 50 rows. +Library DatabaseLibrary + +# Logging of query results is disabled, log head is 50 rows (default). +Library DatabaseLibrary log_query_results=False + +# Logging of query results is enabled (default), log head is 10 rows. +Library DatabaseLibrary log_query_results_head=10 + +# Logging of query results is enabled (default), log head limit is disabled (log all rows). +Library DatabaseLibrary log_query_results_head=0 +```` + +# Commit behavior +While creating a database connection, the library doesn't explicitly set the _autocommit_ behavior - +so the default value of the Python DB module is used. +According to Python DB API specification it should be disabled by default - +which means each SQL transaction must contain a dedicated commit statement, if necessary. + +The library manages it for you: +- Keywords like `Execute SQL String` perform automatically a commit after running the query - or a rollback in case of error +- Keywords like `Query` don't perform a commit, but also do a rollback in case of error + +You can turn off this automatic commit/rollback behavior using the ``no_transaction`` parameter. +See docs of a particular keyword. + +It's also possible to explicitly set the _autocommit_ behavior on the Python DB module level - +using the `Set Auto Commit` keyword. +This has no impact on the automatic commit/rollback behavior in library keywords (described above). + # Database modules compatibility The library is basically compatible with any [Python Database API Specification 2.0](https://peps.python.org/pep-0249/) module. @@ -83,7 +232,7 @@ Therefore there are some modules, which are "natively" supported in the library ## Python modules currently "natively" supported ### Oracle - [oracledb](https://oracle.github.io/python-oracledb/) - - Both thick and thin client modes are supported - you can select one using the `driverMode` parameter. + - Both thick and thin client modes are supported - you can select one using the `oracle_driver_mode` parameter. - However, due to current limitations of the oracledb module, **it's not possible to switch between thick and thin modes during a test execution session** - even in different suites. - [cx_Oracle](https://oracle.github.io/python-cx_Oracle/) ### MySQL diff --git a/doc/index.html b/doc/index.html index 3e685f3..f3450a3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -6,9 +6,9 @@ - + - - - - -