/// <summary>
        /// Runs this fixture.
        /// </summary>
        /// <param name="output">The test output helper.</param>
        /// <returns></returns>
        public async Task RunAsync(ITestOutputHelper output = null)
        {
            _run = true;

            try
            {
                if (RequestMessage == null)
                {
                    throw new InvalidOperationException($"Must call {nameof(When)} to configure an HTTP request");
                }

                if (!_assertions.Any())
                {
                    throw new InvalidOperationException("No assertions to run");
                }

                if (output != null)
                {
                    _loggerProvider.SetTestOutputHelper(output);
                }

                using var client = Factory.CreateClient();
                var provider = Factory.Server.Services;

                // Bootstrap.
                if (_bootstrapFunctions.Any())
                {
                    using var scope = provider.CreateScope();
                    foreach (var bootstrap in _bootstrapFunctions)
                    {
                        await bootstrap(scope.ServiceProvider);
                    }
                }

                var logger = provider.GetRequiredService <ILogger <MvcFunctionalTestFixture <TStartup> > >();

                var requestBody = await(RequestMessage.Content?.ReadAsStringAsync() ?? Task.FromResult <string>(null));
                logger.LogInformation($"Sending request {RequestMessage}\n{requestBody ?? "<no body>"}");

                var response = await client.SendAsync(RequestMessage);

                var responseBody = await(response.Content?.ReadAsStringAsync() ?? Task.FromResult <string>(null));
                logger.LogInformation($"Received {response}\n{responseBody ?? "<no body>"}");

                var aggregator = new ExceptionAggregator();

                foreach (var assertion in _assertions)
                {
                    switch (assertion)
                    {
                    case ResponseAssertion ra:
                        aggregator.Run(() => ra.Assertion(response));
                        break;

                    case ResponseBodyAssertion ra:
                        if (aggregator.TryRun(() => ra.Deserializer(responseBody), out var result))
                        {
                            foreach (var a in ra.Assertions)
                            {
                                await aggregator.RunAsync(() => a(provider, result));
                            }
                        }
                        break;

                    case ServiceAssertion sa:
                        using (var scope = provider.CreateScope())
                        {
                            await aggregator.RunAsync(() => sa.Assertion(scope.ServiceProvider));
                        }
                        break;

                    case RequestAssertion ra:
                        var context = await ra.ContextFactory(response);

                        var fixture = new MvcFunctionalTestFixture <TStartup>(_loggerProvider, this);
                        ra.Configurator(context, fixture);
                        await aggregator.RunAsync(() => fixture.RunAsync());

                        break;
                    }
                }

                aggregator.ThrowIfHasExceptions();
            }
            finally
            {
                Reset();
            }
        }