In-Kernel Tests
In-Kernel tests are facilitated using the Ensemble.Testing library. All In-Kernel tests must be placed in the Ensemble.Kernel.Tests library.
Declaring a Test Class
Every test class must be public, and must be attributed using Ensemble.Testing.TestFixtureAttribute. For example:
[TestFixture]
public class MathTests
{
// Test Code.
}
A constructor should perform the test initialization and the Dispose method should perform the test teardown. For example:
[TestFixture]
public class MathTests : IDisposable
{
private List<int> testNumbers1;
private List<int> testNumbers2;
private List<int> expectedAddResults;
public MathTests()
{
testNumbers1 = new List<int>();
testNumbers2 = new List<int>();
expectedAddResults = new List<int>();
// Fill tests.
}
public void Dispose()
{
// Destroy some objects.
}
// Test Code.
}
Furthermore, some tests require individual setups and teardowns. Ensemble uses a generic interleave method. For example:
[TestFixture]
public class MathTests : IDisposable, ITestInterleave
{
private List<int> testNumbers1;
private List<int> testNumbers2;
private List<int> expectedAddResults;
public MathTests()
{
testNumbers1 = new List<int>();
testNumbers2 = new List<int>();
expectedAddResults = new List<int>();
// Fill tests.
}
void ITestInterleave.Interleave()
{
// Destroy old test.
// Set up new test.
}
public void Dispose()
{
// Destroy some objects.
}
// Test Code.
}
Declaring Individual Steps
Finally each test should be marked with the Ensemble.Testing.TestAttribute attribute:
[TestFixture]
public class MathTests : IDisposable, ITestInterleave
{
private List<int> testNumbers1;
private List<int> testNumbers2;
private List<int> expectedAddResults;
public MathTests()
{
testNumbers1 = new List<int>();
testNumbers2 = new List<int>();
expectedAddResults = new List<int>();
// Fill tests.
}
void ITestInterleave.Interleave()
{
// Destroy old test.
// Set up new test.
}
public void Dispose()
{
// Destroy some objects.
}
[Test]
public void Add()
{
for(int i = 0; i < testNumbers1.Count; i++)
{
Assert.IsEqual(testNumbers1[i] + testNumbers2[i] == expectedAddResults[i], "{0} + {1} == {2}",
testNumbers1[i], testNumbers2[i], expectedAddResults[i]);
}
}
}
Unlike other testing frameworks, Ensemble.Testing does not use exceptions, rather a context is passed to objects such as Assert. This means that methods will continue running even if a test within the test method fails. Appropriate methods return a boolean that can be used to determine if the test succeeded. For example:
[TestFixture]
public class MathTests : IDisposable, ITestInterleave
{
private List<int> testNumbers1;
private List<int> testNumbers2;
private List<int> expectedAddResults;
public MathTests()
{
testNumbers1 = new List<int>();
testNumbers2 = new List<int>();
expectedAddResults = new List<int>();
// Fill tests.
}
void ITestInterleave.Interleave()
{
// Destroy old test.
// Set up new test.
}
public void Dispose()
{
// Destroy some objects.
}
[Test]
public void Add()
{
for(int i = 0; i < testNumbers1.Count; i++)
{
if(!Assert.IsEqual(testNumbers1[i] + testNumbers2[i] == expectedAddResults[i], "{0} + {1} == {2}",
testNumbers1[i], testNumbers2[i], expectedAddResults[i]))
return;
}
}
}
Note that all the methods return true if the test succeeded and false if it did not, this means that Assert.IsFalse(1==2) would return true.