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.

Also available in: HTML TXT