Testing SurrealDB

This page details a number of ways that SurrealDB is and can be tested.

SDKs

Database testing by users is most frequently done using an SDK, particularly for the languages in which SurrealDB can be used in embedded mode. This allows testing to be conducted in just a few lines of code.

use surrealdb::{
engine::any::connect,
types::{ToSql, Value},
};

#[tokio::test]
async fn test_db() {
let db = connect("memory").await.unwrap();
db.use_ns("test").use_db("test").await.unwrap();

let created = db
.query("CREATE ONLY person:one RETURN VALUE id")
.await
.unwrap()
.take::<Value>(0)
.unwrap()
.to_sql();
assert_eq!(created, "person:one");
}

For a larger example of a test suite made by a SurrealDB user, see this repo which tests hundreds of assertions using the Python SDK.

Testing via direct SurrealQL queries

Testing can also be done through direct SurrealQL queries to the database. While the CLI and Surrealist are the most convenient tools to use, sending in queries via the HTTP endpoints may be more convenient when needing to test output depending on certain environments such as queries as a record user vs. as a database-level system user or a root user.

Using manual transactions for testing

As failed transactions automatically roll back any changes made, a transaction with a final THROW statement can be used as a confirmation that no errors have taken place inside a group of queries.

Take the following example that creates a unique index and then inserts some records to make sure that the database logic is functioning as expected. However, as names are not necessarily unique, the index soon gives an error and cancels the transaction before THROW can be reached.

BEGIN TRANSACTION;
DEFINE INDEX unique_name ON TABLE person FIELDS name UNIQUE;

INSERT INTO person [
{ name: 'Agatha Christie', born: d'1890-09-15' },
{ name: 'Billy Billerson', born: d'1979-09-11' },
-- Pretend there are is 10,000 more objects here
{ name: 'Agatha Christie', born: d'1955-05-15' },
];

THROW "Reached the end";
COMMIT TRANSACTION;

The output is not the expected 'An error occurred: Reached the end' message, showing that not all queries were successful.

Output

"Database index `unique_name` already contains
'Agatha Christie', with record `person:qs4bpvl96sf9x40b3567`"

If the index is redefined to be less strict, the statements will work and the expected output will be reached, confirming that no errors occurred during the test.

BEGIN TRANSACTION;
DEFINE INDEX OVERWRITE unique_person ON TABLE person FIELDS name, born UNIQUE;

INSERT INTO person [
{ name: 'Agatha Christie', born: d'1890-09-15' },
{ name: 'Billy Billerson', born: d'1979-09-11' },
{ name: 'Agatha Christie', born: d'1955-05-15' },
];

THROW "Reached the end";
COMMIT TRANSACTION;

Expected output

'An error occurred: Reached the end'

Validating .surql files

One or more .surql files can be validated by the CLI using the surreal validate command.

SurrealDB internal testing

Each PR submitted to the SurrealDB repo runs a series of language tests that carries out thousands of assertions. As an internal tool, the language test suite is and will continue to be developed with only the needs of the SurrealDB developer team in mind. It is in no way meant to be a tool for community use.

That said, the suite is open source and SurrealDB users sometimes gravitate towards it due to the convenience of being able to run tests over multiple .surql files in a variety of situations without needing to recompile any code. If you are considering doing the same, be sure to note that these tests are unit tests with output that may differ slightly from that received as a response from a running database instance.