-
Notifications
You must be signed in to change notification settings - Fork 13
Unit Test
Tecture gives you ability to capture test data and to generate validation. The idea is to extract piece of business logic into unit test project, set up infrastructure using TectureBuilder
, do several "code-build-debug" cycles until feature is implemented and after that, capture final test data, generate validation and leave test method for further regression checks.
In playground I use typical unit test project with xUnit connected. Also I created several infrastructure classes which implement test data capturing, generate validation and write resulting files under the certain folder of tests project. Feel free to borrow them, but do not hesitate to create your own if you feel not comfortable with my setup.
- Create unit test class that inherits from
TectureTestBase
- Create test method that validates particular case
- Put the following line into it:
using var c = Case(out ITecture ctx);
- Call services, logic or queries using
ctx
variable - Run/debug unit test on local database
- If it succeeds - I receive
%TestName%_Validation.cs
and%TestName_TestData.cs
in the folder%TestName%
near the test class - I turn my initial using into
using var c = Case<%TestName%_TestData>(out ITecture ctx);
and append validation at the end:
c.Validate<%TestName%_Validation>();
As result, I get test like this one with the following test data and following validation.
Finally, I run test method again to ensure that it works fast enough and does not use database.
This approach validates several aspects of business logic at once and reports if something has been changed. To be exact, Tecture validates:
Such test data class reproduces all the responses sequentially, step by step. So test data retrieval will fail if query order is violated. This circumstance is used as part of business logic validation during tests. Keep in mind that test data relies on circumstance that particular logic do produce particular queries in particular order.
Example: you have changed the method DoBusiness
of service A
that is being used from method CreateOrder
in service B
. If there are properly composed Tecture unit tests validating logic of B.CreateOrder
and your modifications of method DoBusiness
break query order - then unit test for B.CreateOrder
will fail and rise the red flag of affected functionality. It allows you to keep track of functionality consistency across all of your application.
Test data entries contains hash of the query. It is being computed by aspect that was used to produce this query. Hash is needed to check query consistency itself (even if query order seems to be maintained).
Example: the same setup with services A
and B
but you changed some .Where
criterias. ORM aspect will compute the hash of expression and if it is different - test fails again because we cannot be sure that logic works correctly.
Basically Tecture ensures that commands in trace follows one after another and if validation says that after command of type Add
there must be command of type Save
(synthetic command that denotes that Save
/SaveAsync
call happened at this point of the trace). So if order is violated - Tecture throws meaningful exception.
Basic Tecture checks validate command annotation, so it should correspond to it's initial value. It can be disabled by removing .Basics
call from validation generator configuration (here).
Default checks for Add
and Delete
/DeletePk
commands validate the state of entity that is being added or deleted. Default checks for DirectSql validates SQL command checks and parameters... et cetera, et cetera.
So therefore we have plenty of check places that are basically enough to catch critical or ruining regression changes in business logic. The more tests you create - the more cases you cover - the more stability you have.
Pay attention.
- You can ignore particular test for a while. Not recommended.
- If you are sure that your modifications comply with requirements, you can remove old test data, re-run test and capture new test data. Recommended.
- You can rewrite this unit test or completely remove it if you consider requirements for underlying functionality completely changed.
(c) 2020, Pavel B. Novikov