Showing posts with label Contract Verifier. Show all posts
Showing posts with label Contract Verifier. Show all posts

2010/05/18

Hash Code Acceptance Contract Verifier in MbUnit v3

Designing a good hash code generation algorithm is a black art. There is no formal and objective way to determine what is the best algorithm for a given scenario. In fact, most of the developers do not know how exactly to implement efficiently hash functions. As you know, hash functions for a given type are implemented in .NET by overriding the method Object.GetHashCode(). Most of us (including myself, I must admit) usually shake up and down the values by shifting and xoring them randomly without knowing exactly if the result will be good enough. It’s even worse: if the implementation is poor, your application will continue to work because a bad hash function does "only" affect performance. So you might even not be able to notice it immediately.

In the other hand, testing a hash function is cumbersome. A good hash function should have the following properties:
  • Low probability of collision; meaning that the odds to get two values that produces the same hash code should be as low as possible.
  • Hash codes should be distributed uniformly.
  • It should achieve "avalanche" by generating hash values wildly different if even a single bit is different in the input key.
Writing unit tests for a hash generator is therefore not a trivial task. Fortunately MbUnit comes to rescue. The soon released v3.2 provides a new contract verifier named Hash Code Acceptance Contract.

The contract verifier adds two child tests to the test fixture. They evaluate the probability of collision and the uniform distribution goodness-of-fit. At this time, the avalanche test is not supported (perhaps in a future release?)

Consider the sample type below. It implements an awful hash function of the additive kind. Let's imagine that according to some imaginary specifications, value is a number between 0 and 9, and dayOfWeek is... well, I just let you find out :)
public class Foo
{
private readonly int value;
private readonly DayOfWeek dayOfWeek;

public Foo(int value, DayOfWeek dayOfWeek)
{
this.value = value;
this.dayOfWeek = dayOfWeek;
}

public override int GetHashCode()
{
return value + (int)dayOfWeek;
}
}
Now let's use the contract verifier to evaluate our poor implementation.
[TestFixture]
public class FooTest
{
[VerifyContract]
public readonly IContract HashCodeAcceptanceTests = new HashCodeAcceptanceContract<Foo>()
{
CollisionProbabilityLimit = CollisionProbability.Low,
UniformDistributionQuality = UniformDistributionQuality.Good,
DistinctInstances = DataGenerators.Join(
Enumerable.Range(0, 10),
Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>())
.Select(o => new Foo(o.First, o.Second))
};
}
CollisionProbabilityLimit and UniformDistributionQuality are the expected confidence levels. These are probability values between 0 (good) and 1 (bad), but we use here some handy predefined constants to improve readability (more details here and here). You may want to let the default values of 5% if you are not sure.

DistinctInstances must be fed with an enumeration of distinct Foo instances. It's important to understand that the entire evaluation of the hash function is based on the statistical population you decide to provide. Therefore the confidence in the test results will be as good as (or as bad as, for the pessimists) the quality and the representativeness of that population. Two types of scenarios are possible. Either the range of possibilities is finite and reasonably small, or the number of possible distinct instances is nearly infinite or insanely large. In the first case, it's better to provide to the contract verifier all the possible values. Thus you get an exact and complete stochastic evaluation of your hash function. In the second case, you will need to carefully select a representative subset of all the possible values.

In both cases you can feed the contract verifier by using a static method which returns an enumeration.
// ...
DistinctInstances = GetDistinctInstances()
// ...

private static IEnumerable<Foo> GetDistinctInstances()
{
// ...
}
Or to provide an existing catalog if they can be retrieved from an external data source.
// ...
DistinctInstances = Foo.GetThemAll()
// ...
You may also use the powerful MbUnit data generation framework to easily combine and generate random or sequential values.
// ...
DistinctInstances = DataGenerators.Join(
Enumerable.Range(0, 10),
Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>())
.Select(o => new Foo(o.First, o.Second))
// ...
If we run the tests, the report informs us that the tests have miserably failed. The probability of collision is terribly high and the distribution is far from being uniform.



Let's improve our hash function by using a simple implementation of Dan Bernstein's famous algorithm.
public override int GetHashCode()
{
return 33 * value ^ dayOfWeek.GetHashCode();
}
Unsurprisingly, running the tests again makes the report look better :)



Mission accomplished!

Additional information and examples might be found in the Gallio Wiki.

2009/03/26

Contract Verifiers in MbUnit v3.0.7

Jeff Brown has announced the release of Gallio v3.0.6. This new major version contains numerous new features and fixes which have been implemented during the last 5 months mostly by Jeff and Graham. (See the release note for more details)

We made some notable additions to the contract verifier namespace as well:

  • New syntax based on the declaration of a read-only field rather than an attribute of the test fixture (breaking change)

  • Two new contract verifiers for collection-based classes (ICollection<T> and IList<T>)

  • New experimental contract verifier that checks for some aspects of immutability in a cumstom types
But the work is far for being complete. Here is what you can expect in the future v3.0.7:
  • New contract verifier for implementations of the generic IDictionary interface.

  • New property tester to easily verify the consistency of a property getter/setter.

  • Better immutability contract verifier with additional tests and more possible customizations.

  • Improved stack trace data handling (so that double-clicking a failing test will lead you directly to the declaration of your contract field)

  • Better failure messages (with a new Assert.Explain helper method to decorate inner assertion failures, so we can provide more meaningful messages)

  • More documentation in the Gallio Book.


So, let's go back to work...

2009/02/16

The Collection Contract Verifier

Gallio v3.0.6 is closed to be released. Among the numerous new features and fixes, mostly brought by Jeff and Graham, we have added a new contract verifier for the collection types.

The collection contract verifies that your implementation of the generic interface ICollection<T> behaves correctly. In particular, the contract verifier tests the addition and the deletion of items, but also the consistency of the Count and the ReadOnly properties.

The syntax for declaring a collection contract verifier is very similar to the other contracts:
[VerifyContract]
public readonly IContract CollectionTests = new CollectionContract<TCollection, TItem>
{
// Some Options...
};
You may specify some optional properties to make the contract verifier better fit your specific needs. For instance, setting AcceptEqualItems to true indicates that the collection is expected to accept duplicate items (object equality). You can also provide a custom default instance of the collection by feeding GetDefaultInstance (by default the default constructor is invoked).

To completely test a collection type is a particular painful task. The new collection contract verifier is then probably a nice time saver. However, the verifier expects your collection to have a strictly regular behavior, such as List<T>. It will probably not be suitable for a custom collection which treats addition or deletion of items with a different logic. We could have made the verifier even more flexible with additional options, but at a certain point, it is probably better to write manually the unit tests with ones own little fingers.

2009/01/07

The Immutability Contract Verifier

MbUnit v3 has a new contract verifier called VerifyImmutabilityContract. Basically, it verifies that every field of the tested type is declared with the readonly keyword. It is important to note that the verification is done recursively over all the inner field types, until some known primitive is found, such as String, Boolean, or Int32.

The original idea comes from Jeff Brown which was inspired by a post of Oren Eini.

Here is simple class that implements that sort of immutability, and a test fixture which declares the contract verifier.
public class Foo
{
private readonly int value;
private readonly string name;

// some code here...
}
[TestFixture]
public class FooTest
{
[VerifyContract]
public readonly IContract ImmutabilityTests = new ImmutabilityContract<Foo>();
}
So far, the contract verifier generates only one test method named AreAllFieldsReadOnly.

2008/12/19

New Syntax For Contract Verifiers (Release)

Today, we have commited in the Gallio development trunk, the new syntax for the MbUnit contract verifiers.

That new syntax is a major breaking change. After you update Gallio with the latest version (3.0.5.589 and later), you will need to modify the declaration of your contract verifiers to make your project compilable again. Download the latest development build here.

Please refer to that post for additional details about the new syntax.

2008/09/23

Contract Verifiers - Part IV. - The Comparison Contract Verifier

The comparison contract verifier helps in implementing correctly the generic interface IComparable. It verifies in particular that your type-specific implementation orders instances correctly.
public class Fraction : IComparable<Fration>
{
public Fraction(int numerator, int denominator)
{
// ...
}

// ...
}
As for the other contract verifiers, you must use a dedicated attribute to decorate your test fixture. And as for the equality contract verifier, your test fixture must provide classes of equivalence object instances to be consumed by the contract verifier. The only but important difference here, is that you must feed the method with ordered classes. Each class must contain instances expected to be compared strictly greater than the objects in any previous class. In other words, instances must be put in the ascending order.
[TestFixture]
[VerifyComparisonContract(typeof(Fraction))]
public class FractionTest : IEquivalenceClassProvider<Fration>
{
public EquivalenceClassCollection<Fration> GetEquivalenceClasses()
{
return EquivalenceClassCollection<Fration>.FromDistinctInstances(
new Fraction(1, 6),
new Fraction(1, 5),
new Fraction(1, 4),
new Fraction(1, 3));
};
}
}
The comparison contract verifier checks for the following features:

1. The CompareTo method works as expected. The method must return a negative value if the current object is less than the other object; a positive value if it is greater; or zero if they are equal. Furthermore, if the type is nullable, the contract verifier checks for null reference handling as well. Any non null instance should compares greater than a null reference; and two null references should be equal.
public class Fraction : IComparable<Fration>
{
public int CompareTo(Fraction other)
{
// ...
}
}
Although it is not mandatory, you might decide to override the four comparison operators. The contract verifier is able to check them too. This is an optional feature. You can disable it by setting the named parameter ImplementsOperatorOverload to false.
[TestFixture]
[VerifyComparisonContract(typeof(Fraction), ImplementsOperatorOverload = false)]
public class
FractionTest : IEquivalenceClassProvider<Fration>
{
// ...
}
2. The Greater Than (>) operator overload is correctly implemented and behaves as expected.
public class Fraction : IComparable<Fration>
{
public static bool operator >(Fraction left, Fraction right)
{
// ...
}
}
3. The Greater Than Or Equal (>=) operator overload is correctly implemented and behaves as expected.
public class Fraction : IComparable<Fration>
{
public static bool operator >=(Fraction left, Fraction right)
{
// ...
}
}
4. The Less Than (<) operator overload is correctly implemented and behaves as expected.
public class Fraction : IComparable<Fration>
{
public static bool operator <(Fraction left, Fraction right)
{
// ...
}
}
5. The Less Than Or Equal (<=) operator overload is correctly implemented and behaves as expected.
public class Fraction : IComparable<Fration>
{
public static bool operator <=(Fraction left, Fraction right)
{
// ...
}
}
It is very common to implement equality and comparison in the same time. Should this happen, you can combine several contract verifiers into the same test fixture. This is very handy.
public class Fraction : IComparable<Fration>, IEquality<Fration>
{
}
[TestFixture]
[VerifyComparisonContract(typeof(Fraction))]
[VerifyEqualityContract(typeof(Fraction))]
public class FractionTest : IEquivalenceClassProvider<Fration>
{
// ...
}

2008/09/03

Contract Verifiers - Part III. - The Equality Contract Verifier

The path that leads to a proper implementation of the equality contract has many pitfall traps. Fortunately, the equality contract verifier will help you in avoiding them. For convenience, we will consider as an example, a hypothetical class representing a simple mathematical fraction which implements IEquality<T>.
public class Fraction : IEquality<Fraction>
{
public Fraction(int numerator, int denominator)
{
// ...
}

// ...
}
In order to test the type implementing the generic equality interface, the contract verifier needs some valid type instances. That's why the test fixture must fulfill a two side parts contract.
  • It must have the attribute VerifyEqualityContract.
  • It must implement the interface IEquivalenceClassProvider<T>, which will provide the test runner with various object instances to play with.
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;

[TestFixture]
[VerifyEqualityContract(typeof(Fraction))]
public class FractionTest : IEquivalenceClassProvider<Fraction>
{
public EquivalenceClassCollection<Fraction> GetEquivalenceClasses()
{
return EquivalenceClassCollection<Fraction>.FromDistinctInstances(
new Fraction(1, 2),
new Fraction(2, 3),
new Fraction(4, 5));
}
}
The IEquivalenceClassProvider<T> has a single method that you must use to return a collection of equivalence classes for the evaluated type. An equivalence class is a collection of object instances that are expected to be equal (The notion of equality is of course to be understood in the sense of your own equality contract). In the simplest scenarios, it is generally sufficient to provide several distinct object instances to be compared together. Use the factory method FromDistinctInstances to construct such a collection of equivalence classes. In the previous example, we provide 3 equivalence classes, each containing 1 single object.

However, in more complex scenarios, we want to verify that different object instances "representing" the same value are actually equal. For instance, the fraction 1/2 should be equal to the fraction 2/4 or 3/6. Instead of using the factory method, use the constructor to provide some equivalence classes containing a variable number of objects.
[TestFixture]
[VerifyEqualityContract(typeof(Fraction))]
public class FractionTest : IEquivalenceClassProvider<Fraction>
{
public EquivalenceClassCollection<Fraction> GetEquivalenceClasses()
{
return new EquivalenceClassCollection<Fraction>(
new EquivalenceClass<Fraction>(
new Fraction(1, 2),
new Fraction(2, 4),
new Fraction(3, 6)),
new EquivalenceClass<Fraction>(
new Fraction(2, 3),
new Fraction(4, 6)),
new EquivalenceClass<Fraction>(
new Fraction(4, 5)))
}
}
Now that we have defined our contract verifier, let's see what it will check for.

1. It verifies that the method GetHashCode returns the same value for equal objects. You should override the method and return an identical value for all the objects located in the same equivalence class. However, the contrary is not true: it is not required that the resulting hash value for unequal objects be different (although it would be a good idea, for efficiency reasons)
public class Fraction : IEquality<Fraction>
{
public override int GetHashCode()
{
// ...
}
}
2. It verifies that the method Object.Equals(object) behaves as expected. The method should return true when two instances of the same equivalence class are compared together, or when an instance is compared to itself. For nullable types (reference types, or value types nested in a Nullable class), it verifies you dealt correctly with null references. The method should return False when called against a null reference.
public class Fraction : IEquality<Fraction>
{
public override bool Equals(object obj)
{
// ...
}
}
3. Same verifications as point 2; but for the strongly typed version of the Equals method (which is actually the only method that the IEquatable<T> interface requires you to implement).
public class Fraction : IEquality<Fraction>
{
public bool Equals(Fraction other)
{
// ...
}
}
Whenever implementing IEquatable<T>, it is usually recommended to overload the two equality operators as well. By default, the equality contract verifier will evaluate them too. If your class does not override those operators, consider disabling that feature by setting to false the named parameter ImplementsOperatorOverload.
[TestFixture]
[VerifyEqualityContract(typeof(Fraction), ImplementsOperatorOverload = false)]
public class FractionTest : IEquivalenceClassProvider<Fraction>
{
// ...
}
4. It verifies that the equality operator (==) behaves as expected. The verifications are the same as for points 2 and 3. For nullable types, it is also verified that two null references are considered to be equal.
public class Fraction : IEquality<Fraction>
{
public static bool operator ==(Fraction left, Fraction right)
{
// ...
}
}
5. It verifies that the inequality operator (!=) behaves as expected.
public class Fraction : IEquality<Fraction>
{
public static bool operator !=(Fraction left, Fraction right)
{
// ...
}
}

2008/08/25

Contract Verifiers - Part II. - The Exception Contract Verifier

Designing custom exceptions is not a so easy task. The recommended guidelines are relatively strict; and writing unit tests for them is fastidious. That is why the exception contract verifier is useful. It helps testing your custom exceptions, and catching potential design and behavioral problems.

The contract verifier is available as a companion attribute for your test fixture. It adds the necessary test methods, which verify that your exception is well designed and behaves as expected.
public class MyCustomException : Exception
{
// ...
}
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;

[TestFixture]
[VerifyExceptionContract(typeof(MyCustomException))]
public class MyCustomExceptionTest
{
}
Although the test fixture contains no explicit test methods, the test runner will execute 5 tests provided by the contract verifier attribute. Each of them corresponds to a specific guideline:

1. Provides a public default parameter-less constructor.
2. Provides a public constructor taking one single parameter for the error message .
3. Provides a public constructor taking two parameters for the error message and an inner exception.

public class MyCustomException : Exception
{
public MyCustomException()
{
// ...
}

public MyCustomException(string message)
{
// ...
}

public MyCustomException(string message, Exception innerException)
{
// ...
}
}
If for some reason, you decide that your custom exception should handle with construction differently, you can disable the 3 tests above by setting to false the named parameter ImplementsStandardConstructors.
[TestFixture]
[VerifyExceptionContract(typeof(MyCustomException), ImplementsStandardConstructors = false)]
public class MyCustomExceptionTest
{
}
4. Decorates your custom exception with the attribute System.SerializableAttribute.
[Serializable]
public class MyCustomException : Exception
{
}
5. Implements a protected constructor for data serialization.
public class MyCustomException : Exception, ISerializable
{
protected MyCustomException(SerializationInfo info, StreamingContext context)
{
// ...
}
}
Again, in some scenarios, you might decide to not support the serialization process (if your code base targets the compact framework, for instance). Disable the serialization tests by setting to false the named parameter ImplementsSerialization.
[TestFixture]
[VerifyExceptionContract(typeof(MyCustomException), ImplementsSerialization = false)]
public class MyCustomExceptionTest
{
}
When the serialization tests are enabled, the test runner will verify the preservation of data during a complete round trip serialization operation. This will be done for all the constructors; including the 3 recommended standard constructors described above.

The following sample shows the complete code for a general-purpose custom exception; and the test fixture verifying it.
[Serializable]

public class MyCustomException : Exception, ISerializable
{
public MyCustomException()
{
}

public MyCustomException(string message)
: base(message)
{
}

public MyCustomException(string message, Exception innerException)
: base(message, innerException)
{
}

protected MyCustomException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
[TestFixture]
[VerifyExceptionContract(typeof(MyCustomException))]
public class MyCustomExceptionTest
{
}
And here is the report generated by Gallio for that test fixture:

2008/08/19

Contract Verifiers - Part I. - Introduction

Writing unit tests is costly. Surely less costly than not writing them, but costly too. A commonly accepted trade-off consists in not testing trivial features, or worst, repeating features. You know, all those dozens of little classes that implement repeatedly a roughly similar stuff: custom exceptions, event arguments, equatable, comparable, or disposable interfaces, etc. If you write unit tests, you know how painful and uninteresting it is to test those objects.

Honestly, look at the last project you have worked on. Do you see all those custom exceptions you have written? Have you really tested their serialization and unserialization support? Look at these classes implementing the generic IEquatable interface. Have you verified that the equality behaves correctly in all the possible ways (to a null reference, to itself, commutability of the operation, etc?) If the answer is no, then I sympathize. If yes, well, it was a so boring job, wasn't it?



The next release of Gallio (alpha 4) will come with a cool feature called Contract Verifiers. Actually, it is already available in the alpha 3, but under a preliminary form which will be probably marked as obsolete in the future (or perhaps simply removed).
[Update; Actually, Jeff has just removed it from the repository.]

The principle of the contract verifiers is simple. Basically, a contract verifier is a set of predetermined test methods that you can attach to a given test fixture without actually writing them (we could describe it as a kind of Mixin). The test methods will verify for you that the object fulfills the given implementation contract. It is an all-in-one functionality because the test methods have already been written for you. They also support some configuration; so they can be used in different scenarios.

Let's take an example. Imagine you need to write a class A implementing a well-known interface, or deriving from a well-known base class. Let's call it X. You will have to override the necessary members of X, so that A works correctly; and to write a bunch of unit tests that will verify that the functionalities of X (let's call them x1, x2 and x3) work as expected in your implementation of A. Fortunately, Gallio comes with a contract verifier for X. We will name it XContractVerifier. Unit testing A comes suddenly easy:

[TestFixture]
[TestsOn(typeof(A)]
[XContractVerifier(option1=blabla, option2=blabla)]
public class ATest
{
// My other own tests here...
}

Thanks to the XContractVerifier attribute, and during the execution of the test fixture, the test runner of Gallio will add behind the scene, the necessary test methods that will verify that A implements correctly x1, x2, and x3.

Gallio Alpha 4 includes three built-in contract verifiers (it is a beginning):
It is interesting to notice that the internal working of the contract verifiers is based on the remarkable capability of the Gallio exploration engine to dynamically attach child test methods to a given fixture; although those test methods do not physically exist.