Categorygithub.com/viant/dsunit
modulepackage
0.11.0
Repository: https://github.com/viant/dsunit.git
Documentation: pkg.go.dev

# README

Datastore Testibility (dsunit)

Datastore testibility library for Go. GoDoc

This library is compatible with Go 1.10+

Please refer to CHANGELOG.md if you encounter breaking changes.

Introduction

Data focused testing belongs to blackbox group, where the main interest goes down to the initial and final state of the datastore.

To set the initial state of ta datastore, this framework provies utilities to either create empty datastore, or to prepare it with dataset data to test that application works correctly.

The final state testing focuses on checking that a dataset data matches an expected set of values after application logic run. In this case this library has ability to verify either complete or snapshot state of a datastore. While the first approach will be comparing all tables data with expected set of values, the latter will reduced verification to the range provided by expected dataset.

Motivation

This library has been design to provide easy and unified way of testing any datastore (SQL, NoSSQL,file logs) on any platform, language and on the cloud. It simplifies test organization by dataset auto discovery used for datastore preparation and verification. Dataset data can be loaded from various sources like: memory, local or remote csv, json files. All dataset support macro expression to dynamically evaluate value of data i.e <ds:sql ["SELECT CURRENT_DATE()"]> On top of that expected data, can also use predicate expressions to delegate verification of the data values i.e. <ds:between [11301, 11303]>. Finally a dataset like a view can be used to store data for many datastore sources in in just one dataset file.

Datastore initialization and dataset data verification can by managed locally or remotely on remote data store unit test server.

Usage

Data setup and verification
  1. With dedicated expected data folder
    
    import (
        "testing"
        "github.com/viant/dsunit"
        _ "github.com/go-sql-driver/mysql"
    )
    
    
    func Test_Usecase(t *testing.T) {
        parent := toolbox.CallerDirectory(3)
        if !dsunit.InitFromURL(t, path.Join(parent, "test", "config.yaml")) {
            return
        }
        
            ... business test logic comes here
    
        
        expectURL := path.Join(parent, "test/case1/data/expect")
        expectedData := dsunit.NewDatasetResource("db1", expectURL , "", "")
        dsunit.Expect(t, dsunit.NewExpectRequest(dsunit.FullTableDatasetCheckPolicy, expectedData))
    
    }
    
  2. With shared expected data folder
    func Test_Usecase(t *testing.T) {
        parent := toolbox.CallerDirectory(3)
        if !dsunit.InitFromURL(t, path.Join(parent, "test", "config.yaml")) {
            return
        }
        
        
        ... business test logic comes here
    
    
        baseDir := path.Join(parent, "test", "data")
        dsunit.ExpectFor(t, "db1", dsunit.FullTableDatasetCheckPolicy, baseDir, "use_case_1")
    }
    
Forcing table truncation before loading data

@table_x.json

[ {},
    {"id":1,"name":"name 1"},
    {"id":2,"name":"name 2"}
]

When pre-seeding table with data, if the first element is empty map, dsunit deletes all record from a table before inserting supplied dataset.

@table_x.json

[]

Empty array will with prepare method removes all record from a table.

Reverse engineer data setup and verification

	registerResponse := service.Register(dsunit.NewRegisterRequest("db1",
			&dsc.Config{
				DriverName: "sqlite3",
				Descriptor: "[url]",
				Parameters: map[string]interface{}{
					"url": filename,
				},
			}))
	if registerResponse.Stats != "ok" {
		log.Fatal(registerResponse.Error)
	}
    
	response := service.Freeze(&dsunit.FreezeRequest{
			Datastore:"db1",
			DestURL:"/tmp/dn1/expect/users.json",
			SQL:"SELECT * FROM users",
    })
	
Tester methods
Service MethodsDescriptionRequestResponse
Register(t *testing.T, request *RegisterRequest) boolregister database connectionRegisterRequestRegisterResponse
RegisterFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathRegisterRequestRegisterResponse
Recreate(t *testing.T, request *RecreateRequest) boolrecreate database/datastoreRecreateRequestRecreateResponse
RecreateFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathRecreateRequestRecreateResponse
RunSQL(t *testing.T, request *RunSQLRequest) boolrun SQL commandsRunSQLRequestRunSQLResponse
RunSQLFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathRunSQLRequestRunSQLResponse
RunScript(t *testing.T, request *RunScriptRequest) boolrun SQL scriptRunScriptRequestRunSQLResponse
RunScriptFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathRunScriptRequestRunSQLResponse
AddTableMapping(t *testing.T, request *MappingRequest) boolregister database table mapping (view),MappingRequestMappingResponse
AddTableMappingFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathMappingRequestMappingResponse
Init(t *testing.T, request *InitRequest) boolinitialize datastore (register, recreate, run sql, add mapping)InitRequestMappingResponse
InitFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathInitRequestMappingResponse
Prepare(t *testing.T, request *PrepareRequest) boolpopulate databstore with provided dataPrepareRequestMappingResponse
PrepareFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathPrepareRequestMappingResponse
PrepareDatastore(t *testing.T, datastore string) boolmatch to populate all data files that are in the same location as a test file, with the same test file prefix, followed by lowe camel case test namen/an/a
PrepareFor(t *testing.T, datastore string, baseDirectory string, method string) boolmatch to populate all data files that are located in baseDirectory with method namen/an/a
Expect(t *testing.T, request *ExpectRequest) boolverify databstore with provided dataExpectRequestMappingResponse
ExpectFromURL(t *testing.T, URL string) boolas above, where JSON request is fetched from URL/relative pathExpectRequestMappingResponse
ExpectDatasets(t *testing.T, datastore string, checkPolicy int) boolmatch to verify all data files that are in the same location as a test file, with the same test file prefix, followed by lowe camel case test namen/an/a
ExpectFor(t *testing.T, datastore string, checkPolicy int, baseDirectory string, method string) boolmatch to verify all dataset files that are located in the same directory as the test file with method namen/an/a
Freeze(request *FreezeRequest) *FreezeResponsematch to verify all dataset files that are located in the same directory as the test file with method namen/an/a
Dump(request *DumpRequest) *DumpResponsecreates a database schema from existing database for supplied tables, datastore, and target VendorDumpRequestDumpResponse
Compare(request *CompareRequest) *CompareResponsecompares data based on specified SQLs from various databasesCompareRequestCompareResponse

Validation

This library uses assertly as the underlying validation mechanism

Macros

The macro is an expression with parameters that expands original text value. The general format of macro: <ds:MACRO_NAME [json formated array of parameters]>

The following macro are build-in:

NameParametersDescriptionExample
sqlSQL expressionReturns value of SQL expression<ds:sql["SELECT CURRENT_DATE()"]>
seqname of sequence/table for autoicrementReturns value of Sequence<ds:seq["users"]>

Predicates

Predicate allows expected value to be evaluated with actual dataset value using custom predicate logic.

NameParametersDescriptionExample
betweenfrom, to valuesEvaluate actual value with between predicate<ds:between[1.888889, 1.88889]>
within_secbase time, delta, optional date formatEvaluate if actual time is within delta of the base time<ds:within_sec["now", 6, "yyyyMMdd HH:mm:ss"]>

Directives

Data preparation

Most SQL drivers provide meta data about autoincrement, primary key, however if this is not available or partial verification with SQL is used, the following directive come handy.

@autoincrement@

Allows specifying autoincrement field

[
  {"@autoincrement@":"id"},
  {"id":1, "username":"Dudi", "active":true, "salary":12400, "comments":"abc","last_access_time": "2016-03-01 03:10:00"},
  {"id":2, "username":"Rudi", "active":true, "salary":12600, "comments":"def","last_access_time": "2016-03-01 05:10:00"}
]

@indexBy@

(see also asserly indexBy directive usage, for nested data structe validation)

Allows specifying pk fields


[
  {"@indexBy@":["id"]},
  {"id":1, "username":"Dudi", "active":true, "salary":12400, "comments":"abc","last_access_time": "2016-03-01 03:10:00"},
  {"id":2, "username":"Rudi", "active":true, "salary":12600, "comments":"def","last_access_time": "2016-03-01 05:10:00"}
]

Data validation.

@fromQuery@

Allows specified query to fetch actual dataset to be validated against expected dataset

users.json

[
  {"@fromQuery@":"SELECT *  FROM users where id <= 2 ORDER BY id"},
  {"id":1, "username":"Dudi", "active":true, "salary":12400, "comments":"abc","last_access_time": "2016-03-01 03:10:00"},
  {"id":2, "username":"Rudi", "active":true, "salary":12600, "comments":"def","last_access_time": "2016-03-01 05:10:00"}
]

API Documentation

API documentation is available in the docs directory.

GoCover

GoCover

Examples

This project provide a various datasore dsunit integration examples (some with docker vi endly).

RDBMS

NoSQL

External projects::

License

The source code is made available under the terms of the Apache License, Version 2, as stated in the file LICENSE.

Individual files may be made available under their own specific license, all compatible with Apache License, Version 2. Please see individual files for details.

Credits and Acknowledgements

Library Author: Adrian Witas

Contributors: Sudhakaran Dharmaraj

# Packages

No description provided by the author
No description provided by the author
Package server - Remote testing dsunit server.
No description provided by the author
No description provided by the author

# Functions

AddTableMapping Add table mapping.
AddTableMappingFromURL Add table mapping, JSON request is fetched from URL.
Expect Verify datastore with supplied expected datasets.
ExpectDatasets matches all dataset files that are located in the same directory as the test file with method name toverify that all listed dataset values are present in datastore.
ExpectFor matches all dataset files that are located in baseDirectory with method name to verify that all listed dataset values are present in datastore Note the matchable dataset files in the base directory have the following naming: <lower_underscore method name>_expect_<table>.[json|csv] To prepare expected dataset table: 'users' and 'permissions' for test method ReadAll you would have you create the following files in the baseDirectory read_all_expect_users.json read_all_expect_permissions.json .
ExpectFromURL Verify datastore with supplied expected datasets, JSON request is fetched from URL.
ExpectWithURL Verify datastore with supplied expected datasets, JSON requests are fetched from files in directory.
GetDatastoreDialect return GetDatastoreDialect for supplied datastore and registry.
Init datastore, (register, recreated, run sql, add mapping).
InitFromURL Init datastore, (register, recreated, run sql, add mapping), JSON request is fetched from URL.
New creates new dsunit service.
No description provided by the author
No description provided by the author
NewCheckSchemaResponse returns new check schema response.
NewDatafileInfo returns new datafile info if supplied filedinfo matches prefix, postfix.
NewDataset creates a new dataset for supplied table and records.
No description provided by the author
NewDumpRequestFromURL create a request from url.
NewExpectRequest creates a new prepare request.
NewExpectRequestFromURL create a request from URL.
NewInitRequest creates a new database init request.
NewInitRequestFromURL create a request from URL.
No description provided by the author
NewMappingRequest creates new mapping request.
NewMappingRequestFromURL create a request from URL.
NewPrepareRequest creates a new prepare request.
NewPrepareRequestFromURL create a request from URL.
No description provided by the author
NewRecreateRequest create new recreate request.
NewRecreateRequestFromURL create a request from URL.
NewRegisterRequest create new register request.
No description provided by the author
NewRemoveTester creates a new remove tester.
NewRunScriptRequest creates new run script request.
NewRunScriptRequestFromURL create a request from URL.
NewRunSQLRequest creates new run SQL request.
NewRunSQLRequestFromURL create a request from URL.
No description provided by the author
NewServiceClient returns a new dsunit service client.
NewTester creates a new local tester.
Ping wait untill database is online or error.
PopulateWithURL Populate database with datasets, JSON requests are fetched from files in directory.
Prepare Populate database with datasets.
PrepareDatastore matches all dataset files that are in the same location as a test file, with the same test file prefix, followed by lowe camel case test name.
PrepareFor matches all dataset files that are located in baseDirectory with method name and populate datastore with all listed dataset Note the matchable dataset files in the base directory have the following naming: <lower_underscore method name>_populate_<table>.[json|csv] To prepare dataset to populate datastore table: 'users' and 'permissions' for test method ReadAll you would have you create the following files in the baseDirectory read_all_prepare_travelers2.json read_all_populate_permissions.json .
PrepareFromURL Populate database with datasets, JSON request is fetched from URL.
Recreate recreates datastore.
RecreateDatastore recreates target datastore from supplied admin datastore and registry.
RecreateFromURL Recreate recreates datastore, JSON request is fetched from URL.
Register registers new datastore connection.
RegisterFromURL Register registers new datastore connection, JSON request is fetched from URL.
RunScript runs supplied SQL scripts.
RunScriptFromURL RunScript runs supplied SQL scripts, JSON request is fetched from URL.
RunSQL runs supplied SQL.
RunSQLFromURL RunSQL runs supplied SQL, JSON request is fetched from URL.
StartServer start dsunit server.
UseRemoteTestServer enables remove testing mode.

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
FullTableDatasetCheckPolicy policy will drive comparison of all actual datastore data.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
SnapshotDatasetCheckPolicy policy will drive comparison of subset of actual datastore data that is is listed in expected dataset.
StatusOk represents ok status.

# Variables

No description provided by the author
SubstitutionMapKey if provided in context, it will be used to substitute/expand dataset.

# Structs

BaseResponse represent base response.
CheckSchemaRequest represents schema check request.
CheckSchemaResponse represents schema check response.
CompareRequest represent compare request.
CompareResponse represents compare response.
DatafileInfo represent data file.
Records represent data records.
DatasetResource represents a dataset resource.
ExpectRequest represents data validation.
DatastoreDatasets represents a collection of datastore datasets.
No description provided by the author
DumpRequest represent a request to create a database schema.
DumpResponse represents a dump response.
ExpectRequest represents verification datastore request.
ExpectResponse represents verification response.
FreezeRequest represent a request to create a data set from datastore for provided SQL and target path.
FreezeResponse response.
InitRequest represents datastore init request, it actual aggregates, registraction, recreation, mapping and run script request.
InitResponse represent init datastore response.
No description provided by the author
Mapping represents mapping.
MappingColumn represents column with its source definition.
MappingRequest represnet a mapping request.
MappingResponse represents mapping response.
MappingTable represents a table mapping, mapping allow to route data defined in only one table to many tables.
ModificationInfo represents a modification info.
No description provided by the author
PingRequest represents ping request.
PingResponse represents a ping response.
PrepareRequest represents a request to populate datastore with data resource.
PrepareResponse represents a prepare response.
QueryRequest represents get sequences request.
QueryResponse represents get sequences response.
RecreateRequest represent recreate datastore request.
RecreateResponse represents recreate datastore response.
RegisterRequest represent register request.
RegisterResponse represents register response.
RunScriptRequest represents run SQL Script request.
RunSQLRequest represents run SQL request.
RunSQLRequest represents run SQL response.
No description provided by the author
No description provided by the author
SequenceRequest represents get sequences request.
SequenceResponse represents get sequences response.

# Interfaces

Service represents test service.
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author
Records represents table records.