The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

How do you TDD a code generator?

Posted by Davy Brion on August 13th, 2007

So i’m working on a code generator at work, and obviously i want to do it the TDD way. I wasn’t quite sure how i could make sure that it would be easy to test.

This is what i came up with:

    [TestClass]
    public abstract class GeneratorTests<T> where T : new()
    {
        private SourceStringBuilder _expectedSourceStringBuilder;
        private SourceStringBuilder _generationSourceStringBuilder;
        private T _generator;
 
        protected SourceStringBuilder GenerationSourceStringBuilder
        {
            get { return _generationSourceStringBuilder; }
        }
 
        protected SourceStringBuilder ExpectedSourceStringBuilder
        {
            get { return _expectedSourceStringBuilder; }
        }
 
        protected T Generator
        {
            get { return _generator; }
        }
 
        [TestInitialize]
        public void SetUp()
        {
            _generationSourceStringBuilder = new SourceStringBuilder(0);
            _expectedSourceStringBuilder = new SourceStringBuilder(0);
            _generator = new T();
        }
 
        protected void AssertThatGeneratedCodeContainsExpectedCode()
        {
            Assert.IsTrue(GenerationSourceStringBuilder.ToString()
                              .Contains(ExpectedSourceStringBuilder.ToString()));
        }
    }

This base class can be reused for each test class that tests a specific generator:

    [TestClass]
    public class StandardPropertyGeneratorTests : GeneratorTests<StandardPropertyGenerator>
    {
        [TestMethod]
        public void GenerateCodeFor_SimpleColumn_GeneratedCodeContainsCamelCasedPrivateFieldDeclaration()
        {
            ColumnInfo column = CreateColumn("Test", DataType.Int32);
 
            Generator.GenerateCodeFor(column, GenerationSourceStringBuilder);
 
            ExpectedSourceStringBuilder.AppendLine("private Int32 _test;");
 
            AssertThatGeneratedCodeContainsExpectedCode();
        }
 
        private ColumnInfo CreateColumn(string name, DataType dataType)
        {
            return CreateColumn(name, dataType, false);
        }
 
        private ColumnInfo CreateColumn(string name, DataType dataType, bool nullable)
        {
            ColumnInfo column = new ColumnInfo();
            column.LogicalName = name;
            column.DataType = dataType;
            column.Nullable = nullable;
 
            return column;
        }
    }

How clear is this to someone who has no or hardly no knowledge of what these generators and SourceStringBuilders do? I’d like to know so if you have an opinion, please comment below :)

2 Responses to “How do you TDD a code generator?”

  1. Anja Says:

    shouldn’t you try to compile the generated code and test if the compiled code does what it is supposed to do?

    That would be the ultimate test

  2. Davy Brion Says:

    That’s also a possibility but then i’d have to write a lot of code before i’d get a working test. Now i can add one little piece at a time and work my way up.

    Once all the generators are built this way, it would be pretty easy to write some tests that would indeed compile a generated class and then run some tests on the compiled class

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>