Implementing Tests Using AttributesIntroduction - Programming Language - Prerequisites - Creating The Test Fixture - Adding A Test - SetUp and TearDown - Ignoring A Test Or A Test Fixture - Summary IntroductionStarting with version 1.7.3 csUnit supports two different ways for decorating tests:
This tutorial demonstrates how to use attributes for decorating and implementing your tests. Programming LanguageThe tutorial uses C#. PrerequisitesThis tutorial makes the following assumptions:
Creating The Test FixtureThe first step is to create the test fixture. That is the class which will contain the tests you plan to write. In our projects we typically use the convention <classToBeTested>Tests, where <classToBeTested> is replaced by the name of the class we want to test. For instance, if the class you want to implement is going to be called Foo then we would call the test fixture FooTests. This is also the name I will also use for this tutorial. Of course, for your projects, you can choose any name you like! You create the test fixture by adding a class to your project. Use FooTests as the class name. The class has no base class and it does not implement any interface. The resulting file should have the name FooTests.cs and it should contain the following code: using System; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> public class FooTests() { public FooTests() { // // TODO: Add constructor logic here // } } } With this code alone, csUnit will not be able to identify your test. In order to achieve this the attribute TestFixture has to be tagged to the class: using System; using csUnit; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> [TestFixture] public class FooTests() { public FooTests() { // // TODO: Add constructor logic here // } } } The TestFixture attribute takes no parameters and can be applied to classes only. It serves only identification purposes. Upon loading the assembly csUnit searches the entire assembly for classes with this custom attribute set. Don't forget to add a reference to the csUnit assembly to your projects references, and also add the using directive to the source code (see sample above). Adding a TestThe next step is to add a test method. Let's assume we want to call it MyFirstTest(). Then you would add the following lines to implement the test: using System; using csUnit; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> [TestFixture] public class FooTests() { public FooTests() { // // TODO: Add constructor logic here // } public void MyFirstTest() { // your test implementation goes here } } } Again, csUnit does not know about the test yet. In order to tag it as a test, the attribute Test is used. This attribute can be applied to methods only. So this is what you have to do (Note: I deleted the constructor as it is not needed): using System; using csUnit; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> [TestFixture] public class FooTests() { [Test] public void MyFirstTest() { // your test implementation goes here } } } When the assembly is loaded csUnit iterates over all public classes it can find. For each of the classes csUnit iterates over all public methods. If the method has a signature of "public void foo()" and it carries the custom attribute test, it is identified as a test. You can choose any name for the test you like, if you use the attribute test. SetUp and TearDownIn some cases you want to able to run all tests within a test fixture using the same start conditions. On the other hand you do not want to duplicate the setup code. Furthermore, you want to be sure, that the setup and the teardown code is executed for each single test in the fixture. Furthermore you want to be able to also cleanup the objects you might have created during setup. And you want to be sure that this is done automatically. csUnit provides two attributes for achieving exactly this: SetUp and TearDown. The following code sample shows how such attributes can be used. using System; using csUnit; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> [TestFixture] public class FooTests() { [SetUp] public void SetUp() { _myTestData = new TestData(); } [TearDown] public void CleanUp() { _myTestData.Dispose(); // assumes IDisposable is implemented _myTestData = null; } [Test] public void MyFirstTest() { // your test implementation goes here } private TestData _myTestData = null; } } Again, the signature of both, the SetUp and the TearDown method, must be "public void foo()". And again, csUnit searches each test fixture for the existence of these attributes. If it finds one of them or both, the SetUp-method will be called immediately before each test, and the TearDown-method will be called immediately after each test. Ignoring A Test Or A TestFixtureIn some cases you might want to not execute a test, e.g. because its implementation is not complete yet. You can achieve this by adding the Ignore attribute to the test. The ignore attribute can be applied to both a single test or to an entire test fixture. It takes one parameter which is a string, where you can indicate the reason why the test should be skipped: using System; using csUnit; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> [TestFixture] public class FooTests() { [Test] public void MyFirstTest() { // your test implementation goes here } [Test, Ignore("Implementation not complete yet.")] public void SkipThisOne() { } } } When csUnit finds the Ignore attribute on a test method, it retrieves the reason from the attribute (that is the string that has been added there) and reports it in the UI as can be seen in the following example: In some even more rare cases, you want to exclude an entire test fixture from execution. In this case simply apply the Ignore attribute to the class: using System; using csUnit; namespace example { /// <summary> /// Summary description for FooTests. /// </summary> [TestFixture] [Ignore("Fixture is of no use yet")] public class FooTests() { [Test] public void MyFirstTest() { // your test implementation goes here } } } If the Ignore attribute is put on a test fixture, it will not even be instantiated during running the tests. csUnit accesses only the type information including the custom attributes for the test fixture and the tests contained in it. SummaryAs you have seen, using attributes is a convenient means for implementing tests. If you prefer the style which is based on naming conventions: csUnit still supports it. Furthermore: You can mix the attribute base and the naming convention based approach as you like. Happy Testing! |
Sponsors:
|
||||||
Copyright © 2002-2008 by Agile Utilities NZ Ltd. All rights reserved. Site design by Andreas Weiss. This site is protected by bot traps. |