Test Class Organization

09Feb10

Hi there

Just though I d share this

this is the way I ve been organizing my test code as of late

	public class MyClassTests
	{
		public class Given_a_context
		{
			[Fact]
			public void When_somthing_happens_Then_result()
			{
				throw new NotImplementedException();
			}

			//...............
		}

		public class Given_a_different_context
		{
			[Fact]
			public void When_somthing_happens_Then_result()
			{
				throw new NotImplementedException();
			}

			//...............
		}
	}

I like this because you can still easily find the class name with resharper
you can also separate the contexts you are testing in a more clean way
this works out good for me most of the times, even when you are inheriting
from a base test class.
It also reads well in the Test runner.
Any comments?

Advertisements


9 Responses to “Test Class Organization”

  1. Onya for sharing…

    Based on http://haacked.com/archive/2008/08/24/introducing-subspec.aspx and http://www.code-magazine.com/Article.aspx?quickid=0805061
    and http://www.codethinked.com/post/2009/03/08/Beginning-Mocking-With-Moq-3-Part-1.aspx

    I’m using use a Context/Spec stylee. I find it breaks stuff up in the code and in your head much better than a slab of code with 3x comments or line breaks into AAA.

  2. 3 roundcrisis

    hehe, the two first ones are actually the same article 🙂

    The problem I find with the aproach explained there is that to find the tests I want the test files to be called something like MyUnitTests (where MyUnit is the class under tests) as opposed to: When_an_item_is_added as a class name, it just hard to find a test quickly, but the rest, yeah I agree with that

  3. Sorry didnt see this till now

    I was aware the second article was linked from the first but wanted to be sure that it didnt get skimmed over.
    I use CR but suspect R# can also handle the other arrangement if you do a class or method search rather than a file one. But I take the general point of the findability of something being an important consideration in the naming.
    I consider XYZClassTests orgainisation (assumption of 1:1:1 class:test class:test file) to be an antipattern).

  4. Resubmitting so I get followups!

  5. 6 roundcrisis

    If you say something like “I consider XYZClassTests organisation an Antipattern”, I m sure you expected the Why? or actually in what particular situations

    Regarding discover-ability of the class/ method of course you can do that with R# ( and I think even plain VS does that in the 2010 version) however finding OrderServiceTests is pretty intuitive compared to Given_an_initialised_OrderService your eyes just know what to look for in the first case.
    Anyway, this is a matter of taste, as long as the codebase is consistent, I d say it s ok.

  6. Looking again – I scanned a little too quickly when making the last comment (I assumed there wasnt nesting of classes). With the nesting of classes you’re bringing in most of what I’m talking about. In other words, you’re not implying a 1:1:1 ratio, you have a 1:1:n (class:testgroup:testclass) instead. I’d argue that while a lot of your testing is going to be (and should be) specific to a class (a class being the most common Unit), having a less rigid way of grouping (specification/concern hierarchy[1]/observations) fits the way I like to look at things better (To be pejorative, I’m not testing a class to tick a box, I’m writing specifications for a variety of concerns managed by related clumps of classes – even if in many cases they are just one class)

    [1] You dont preclude this in your arrangement, but making it MyClassTests ties it a) to a class b) to thinking “I wrote my class, now I’m testing my class” instead of doing something higher level

    Immediately after reading AOUT (but before I read the BDD stuff, xUTP and PragUnitTesting) I would probably not have split hairs about this.

    In Context/Spec, you can use namespaces and nested classes to accomplish the grouping you do via the MyClassTests grouping class too (And I do – I have a Specifications folder per project and there’s a hierarchy of cs files with grouped specs in those, including use of folders as appropriate – and the arrangment does not necessarily mirror the foldering [based on namespacing] that the actual SUT has)

    Another thing I like about Context/Specification is that the EstablishContext/Because/Observation structuring is very natural and a nice extension to AAA (and doesnt require comments or putting 2 blank lines between the A regions) (Or #regions around each of the As :P) – it really helps you to think.

    I think it’s fair to say we’re not a million miles apart on this – it’s just a slightly different philosophy. It’s definitely a long way from:

    VS “Generate tests for this class” menu option (because our boss told us we need to tick this box to get the cookie)

    class A
    {
    A
    B
    }

    class ATests
    {
    TestA()
    Arrange
    Act
    Assert
    TestB()
    Arrange
    Act
    Assert
    }

    Or (AOUT IIRC – which doesnt break out the context as explicitly as ‘yours’ or ‘mine’):

    class A
    {
    }

    class ATests
    {
    MethodName_StateUnderTest_Behavior()
    Arrange
    Act
    Assert
    MethodName_StateUnderTest_Behavior()
    Arrange
    Act
    Assert
    MethodName_StateUnderTest_Behavior()
    Arrange
    Act
    Assert
    }

    My “final” (it never is!) arrangement is:

    (top level – the code)

    class X
    class XFactory
    class Y
    class Z
    class ZHelper
    namespace Z.Linq
    class ZExtensions

    (Under Specifications folder/namespace)

    class/namespace XYSpecifications

    class XYZSpecificationBase
    EstablishContext
    v light smattering of helpers

    class When_XStuff
    EstablishContext?
    Arrange
    Because
    Act
    Observation*
    Assert
    class When_YStuff
    EstablishContext?
    Arrange
    Because
    Act
    Observation*
    Assert
    class When_ZStuff
    EstablishContext?
    Arrange
    Because
    Act
    Observation*
    Assert

    class/namespace XY_Z_Specification

    class When_ZStuff
    EstablishContext?
    Arrange
    Because
    Act
    Observation*
    Assert

  7. Oh no, it stripped my indentation! Looks pretty crap but hopefully you’ll be able to pull out my points…


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: