How to implement test cases - Ag2S/Tasty GitHub Wiki
Tasty restricts test cases to be described in a predefined way via inheritance.
To implement a test case group, one should inherit one of the four Tests classes:
- Tests
- UnitTests
- SubjectBasedTests<T>
- WebsiteIntegrationTests
Classes listed above provides functionalities to facilitate test implementation and will be introduced below.
-
Tests class provides a simple skeleton of a test case, and has three states, namely, arrangement, executing, and validation.
- First of all, data must be set up, or arranged, for the next executing operation.
- Next step is to execute the test statement and to store the results of execution.
- Finally, the results should be validated.
It also provides a test data container "TestData" to hold test data.
- UnitTests class bases on Tests, and provides "Mock" property, a Mock object container to hold mock objects. To use UnitTests, developers should implement IMockFactory interface for every UnitTests instances. IMockFactory isolates mock library, so you can use your own.
- SubjectBasedTests<T> is a generic class which extends UnitTests and provides not only what UnitTests has but also encapsulates the test subject creation process. The default overridable implementation uses reflection to create a subject instance, passing mock object hold by Mock for reference type and default value for value type.
-
WebsiteIntegrationTests is not based on UnitTests but Tests. It is for purpose of integration test, so there is no Mock property, but there are DatabaseRestorer, MockServer and StandAloneServer instead.
- DatabaseRestorer is responsible for DB snapshot creation, keeping DB invariant after the integration test occurs.
- MockServer holds fake external services. For example, payment service and SMS. These service charges for each request, so, for a integration test, it is better to hold fake services.
- StandAloneServer starts your subject website to be tested without the HTTP server used in production environment.
Tests is the base of all Tests class. It defines those operations as methods which accept a delegate and, moreover, provides overridable initialization and cleanup methods for customization.
Example using MSTest:
[TestClass]
public class AdditionTests : Tests
{
[TestInitialize]
public void Initialize()
{
InitializeTest();
}
[TestCleanUp]
public void Initialize()
{
CleanUpTest();
}
[TestMethod]
public void AdditionTest()
{
Arrange(() =>
{
TestData.Of<int>("x").Value = 1;
TestData.Of<int>("y").Value = 2;
});
Test(() =>
{
TestData.Of<int>("z").Value = TestData.Of<int>("x").Value + TestData.Of<int>("y").Value;
});
Validate(() =>
{
Assert.AreEqual(3, TestData.Of<int>("z").Value);
});
}
}
to be continued...