Fetching Data (reading data) is a key operation of Business Entities. While the SmartComponent Library based Business Entities provide a lot of (tested) functionality out of the box, the read operations should ideally also be unit tested by developers. There are three main criterias for successful Business Entity read operations:
- error free based on expected input (FetchDataRequest, Queries)
- the correct result
- correct number of records
- correct values in records including calculated fields
- acceptable performance
As the nature of FetchData operations are typically very similar, classic Unit Test classes would all contain a large number of almost identically code - for executing a request and asserting the result. The idea of using scenarios is to implement those tests based on a scenario definition in a JSON file rather than in source code. This allows developers to spend the majority of their time on writing those unit tests that are really specific to individual components.
Scenarios are typically defined as JSON files with a .scenario extension:
Defining Scenarios from the Business Entity Tester
The Business Entity Tester supports creating scenario definitions that match the current selection criteria:
Using the "Save Scenario" and "Open Scenario" developers can save and reopen scenarios in the Business Entity Designer.
Executing Scenarios in an ANT job
SmartUnit supports the execution of .scenario file based FetchData operations through an alternative test runner.
The following sample ANT script components demonstrate the usage of the Scenario based test runner.
The ScenarioRunner macro supports the following arguments:
|testSuite||A name for the current test suite|
|tests||Comma delimited list of Packages that contain the .scenario files to be executed|
|output||The file name of the JUnit result file (.xml)|
|services||Services file to load to initialize the environment|
|options||Options such as PROPATH and Database connections passed to the PCTRun|
Following is a sample invokation of the ScenarioRunner macro:
Executing Scenarios from other Unit Tests
The ScenarioRunner class can be invoked directly from unit test methods like shown in the sample below:
Defining assertions in the Scenario JSON file
Without the definition of assertions, the unit test runner would only return a failure in case of runtime errors caused by the Business Entity read operation. Through assertions defined in the .scenario file, developers can assert the result data in detail.
Developer can implement assertions directly in the .scenario file as a JSON array:
Within the Assertions array in the JSON document, the following sections are supported as Array Elements
The NumResults section contains a JSON object with an INT64 property per Buffer who's num results should be asserted. In the above example, we require exactly one record to be returned for the eCustomer and eItem table.
The CanFind section contains a JSON array of objects with a buffer, mode and where properties. This allows to test for records matching the given criteria. As the mode property, we support first and unique. Using the CanFind, developers can also assert for field values using a where criteria like
The CanNotFind section is similar to the CanFind section, just requiring that the specified criterias are not met by any record.
The MaxRuntime section contains an INT64 value specifying the maximum allowed runtiem for the Business Entity read operation.
The MaxReads section contains a JSON object with an INT64 property per database table. The MaxReads assertion will assert the maximum number of reads in the given database tables.
Using the Generic Mock Data Access factory
The .scenario JSON file may declare a MockDataAccess property. This property contains either a comma delimited list of Data Access mock JSON file names or a JSON Array of Data Access mock JSON file names.
Loading custom services for the unit test
The .scenario JSON file may declare a LoadServices property. The property may contain a JSON Array of service.xml file names. The services defined in these services.xml files will be loaded before the test is executed. The services are loaded into a custom ServiceContainer only valid for the execution of the unit test which is overloading the default ServiceContainer (Consultingwerk.Framework.FrameworkSettings:ServiceContainer). This allows to load mock services.