Carna

Initialization and Cleanup

If you want to define the initialization of the fixture, you can define it in a constructor.

If you want to define the cleanup of the fixture, you can implement the IDisposable interface and define it in the Dispose method.

For example:

[Specification]
class CustomerSpec : IDisposable
{
    public CustomerSpec() {}

    public void Dispose() {}

    [Example]
    void Ex01() {}

    [Example]
    void Ex02() {}
}

The execution order is

  1. CustomerSpec constructor
  2. CustomerSpec.Ex01 method
  3. CustomerSpec.Dispose method
  4. CustomerSpec constructor
  5. CustomerSpec.Ex02 method
  6. CustomerSpec.Dispose method

If the fixture has a parent fixture, a constructor of the parent fixture is performed before all fixture methods of the fixture are performed and the Dispose method of the parent fixture is performed after all fixture methods of the fixture are performed.

For example:

[Specification]
class CustomerSpec : IDisposable
{
    public CustomerSpec() {}

    public void Dispose() {}

    [Context]
    class Context01 : IDisposable
    {
        public Context01() {}

        public void Dispose() {}

        [Example]
        void Ex01() {}

        [Example]
        void Ex02() {}
    }
}

The execution order is

  1. CustomerSpec constructor
  2. CustomerSpec.Context01 constructor
  3. CustomerSpec.Context01.Ex01 method
  4. CustomerSpec.Context01.Dispose method
  5. CustomerSpec.Context01 constructor
  6. CustomerSpec.Context01.Ex02 method
  7. CustomerSpec.Context01.Dispose method
  8. CustomerSpec.Dispose method

If you want to use the value that is initialized in a constructor of the parent fixture for the initialization of the fixture, you can specify the ParameterAttribute attribute to the value of the parent fixture and specify it in a parameter of a constructor of the fixture. The value is set to a parameter whose name is equal to the name of the ParameterAttribute attribute.

For example:

[Specification]
class CustomerSpec
{
    [Parameter]
    readonly string workingDirectoryPath;

    public CustomerSpec() => workingDirectoryPath = Path.GetTempPath();

    [Context]
    class Context01
    {
        string WorkingDirectoryPath { get; }

        public Context01(string workingDirectoryPath) => WorkingDirectoryPath = workingDirectoryPath;

        [Example]
        void Ex01() {}

        [Example]
        void Ex02() {}
    }
}

If you want to define the cleanup of the fixture asynchronously, you can implement the IAsyncDisposable interface and define it in the DisposeAsync method.

For example:

[Specification]
class CustomerSpec : IAsyncDisposable
{
    public CustomerSpec() {}

    public async ValueTask DisposeAsync() {}

    [Example]
    void Ex01() {}

    [Example]
    void Ex02() {}
}