Skip to content

Execution Orders

Ivan Novikov edited this page Apr 7, 2016 · 4 revisions

NSpectator's Execution Order Demonstration. This wiki entry was created to help visualize the execution order of inherited and abstract classes, as well as that of before/afterAll methods and sub-contexts.

using NSpectator;
using System;

namespace SpecExecutionOrder
{
    // this can be either an abstract class, or just a class
    abstract class Parent_class : Spec
    {
        public const int indentSize = 3;
        public static string order = "\n\n";
        public static int indent = 0;

        void Print(string s)
        {
            Console.WriteLine(s);
        }

        protected void WriteLinePadRight(string s)
        {
            WriteLine(s);
            indent += indentSize;
        }

        protected void WriteLinePadLeft(string s)
        {
            indent -= indentSize;
            WriteLine(s);
        }

        protected void Write(string s)
        {
            order += s.PadLeft(s.Length + indent);
        }

		protected void WriteLine(string s)
        {
            Write(s + "\n");
        }
		
        void before_all()
        {
            WriteLinePadRight("parent: before all\n");
        }

        void before_each()
        {
            Write("parent: before each\n");
        }

        void act_each()
        {
            Write("parent: act each\n");
        }

        void it_works_parent_1()
        {
            Write("parent: it works 1\n");
        }

        void it_works_parent_2()
        {
            Write("parent: it works 2\n");
        }

        void after_each()
        {
            Write("parent: after each\n\n");
        }

        void after_all()
        {
            WriteLinePadLeft("parent: after all\n");
            Print(order);
        }
    }

    class Child_class : Parent_class
    {
        void before_all()
        {
            WriteLinePadRight("child: before all\n");
        }

        void before_each()
        {
            WriteLine("child: before each");
        }

        void act_each()
        {
            WriteLine("child: act each");
        }

        void it_works_child_3()
        {
            WriteLine("child: it works 3");
        }

        void it_works_child_4()
        {
            WriteLine("child: it works 4");
        }

        void after_each()
        {
            WriteLine("child: after each");
        }

        void after_all()
        {
            WriteLinePadLeft("child: after all\n");
        }

        void method_level_context()
        {
            beforeAll = () => WriteLinePadRight("method: before all");

            before = () => WriteLine("method: before each");

            act = () => WriteLine("method: act each");

            it["it works method 5"] = () => WriteLine("method: it works 5");

            it["it works method 6"] = () => WriteLine("method: it works 6");

            after = () => WriteLine("method: after each");

            afterAll = () => WriteLinePadLeft("method: after all");

            context["sub context"] = () =>
            {
                beforeAll = () => WriteLinePadRight("sub: before all");

                before = () => WriteLine("sub: before each");

                act = () => WriteLine("sub: act each");

                it["it works sub 7"] = () => WriteLine("sub: it works 7");

                it["it works sub 8"] = () => WriteLine("sub: it works 8");

                after = () => WriteLine("sub: after each");

                afterAll = () => WriteLinePadLeft("sub: after all");
            };
        }
    }
}

And the output for the spec above. Take note, NSpectator follows the RSpec convention of executing beforeAll blocks prior to executing beforeEach blocks when building a test context. This can be seen in the output where the child: before all block is executed prior to the parent: before each block.

parent: before all
   child: before all
      parent: before each
      child: before each
      parent: act each
      child: act each
      parent: it works 1
      child: after each
      parent: after each

      parent: before each
      child: before each
      parent: act each
      child: act each
      parent: it works 2
      child: after each
      parent: after each

      parent: before each
      child: before each
      parent: act each
      child: act each
      child: it works 3
      child: after each
      parent: after each

      parent: before each
      child: before each
      parent: act each
      child: act each
      child: it works 4
      child: after each
      parent: after each

      method: before all
         parent: before each
         child: before each
         method: before each
         parent: act each
         child: act each
         method: act each
         method: it works 5
         method: after each
         child: after each
         parent: after each

         parent: before each
         child: before each
         method: before each
         parent: act each
         child: act each
         method: act each
         method: it works 6
         method: after each
         child: after each
         parent: after each

         sub: before all
            parent: before each
            child: before each
            method: before each
            sub: before each
            parent: act each
            child: act each
            method: act each
            sub: act each
            sub: it works 7
            sub: after each
            method: after each
            child: after each
            parent: after each

            parent: before each
            child: before each
            method: before each
            sub: before each
            parent: act each
            child: act each
            method: act each
            sub: act each
            sub: it works 8
            sub: after each
            method: after each
            child: after each
            parent: after each

         sub: after all
      method: after all
   child: after all
parent: after all