piątek, 1 listopada 2013

BDD Test Template

Wcześniej pisałem już o Korniszoku i BDD, ale teraz chciałbym przedstawić Ci template z jakim u mnie w pracy się pracuje. Template ten jest w modzie BDD. Testuje jedną klasę przy jednym zachowaniu. Jeżeli mielibyśmy n ważnych zachowań to potrzebujemy stworzyć n takich klas testowych.
Template wygląda następująco:
   [Category("BDD_MySuperClass")]
    public class when_we_run_special_methods : InstanceSpecification<MySuperClass>
    {
        protected override MySuperClass Create_subject_under_test()
        {
            return new MySuperClass();
        }

        [Test]
        public void It_should_do_special_stuff()
        {
            
        }
    } 


Cała magia jest w dwóch klasach abstrakcyjnych:
    public abstract class Specification
    {
        [SetUp]
        public virtual void BaseSetUp()
        {}

        [TearDown]
        public virtual void BaseTearDown()
        {}

        [DebuggerStepThrough]
        protected virtual void Establish_context()
        {}

        [DebuggerStepThrough]
        protected virtual void Because()
        {}

        [DebuggerStepThrough]
        protected virtual void Dispose_context()
        {}

        [DebuggerStepThrough]
        protected virtual void Initialize_subject_under_test()
        {}
    }

I druga generyczna klasa:
    public abstract class InstanceSpecification<TSubjectUnderTest> : Specification
    {
        protected TSubjectUnderTest SubjectUnderTest { get; private set; }

        protected abstract TSubjectUnderTest Create_subject_under_test();

        public override void BaseSetUp()
        {
            Establish_context();
            Initialize_subject_under_test();
            Because();
        }

        public override  void BaseTearDown()
        {
            Dispose_context();
        }

        protected override  void Initialize_subject_under_test()
        {
            SubjectUnderTest = Create_subject_under_test();
        }
    }


'Super' przykład dla StringBuilder jest przedstawiony poniżej:
[Category("BDD_StringBuilder")]
[TestFixture]
public class when_we_insert_char_into_empty_stringBuilder : InstanceSpecification<StringBuilder>
{
    public string SubjectUnderTestString { get { return SubjectUnderTest.ToString(); } }

    protected override StringBuilder Create_subject_under_test()
    {
        return new StringBuilder();
    }

    protected override void Because()
    {
        SubjectUnderTest.Insert(0, "first word");
    }

    [Test]
    public void It_should_start_with_word_first()
    {
        Assert.IsTrue(SubjectUnderTestString.StartsWith("first"));
    }

    [Test]
    public void It_should_not_be_empty_string_because_words_ware_added()
    {
        Assert.NotNull(SubjectUnderTest);
        Assert.IsTrue(SubjectUnderTestString.Any()); //any char
    }
} 


SubjectUnderTestString to pole pomocnicze. Przykład przedstawia wzorzec AAA (Arrange-Act-Assert). Metoda Create_subject_under_test() przygotowuje obiekt, metoda Because() wykonuje pewne zachowania na tym obiekcie i mamy dwie metody testowe.

Więcej szczegółów o testowaniu w stylu BDD możesz zaleź na elegantcode.com. Możesz pobrać code snippet z MyCodeSnippets.

Brak komentarzy:

Prześlij komentarz