Integration Tests in Service Fabric – Test definition

In the last post I gave an overview of the conventions that drive the solution structure and define the test applications. All the code I’m going to explore in this, and future blog posts can be found on my ServiceFabric.Testing repository. The code in the repository doesn’t use the OrderShipping analogy used in the post, but I’ll hope you still get the point ;).

The OrderShippingTests project stateful service has to inherit from the stateful service called AbstractTestRunner. The AbstractTestRunner I’m going to explore the responsibilities and functions of the runner stateful service in future blog posts.

    sealed class Tests : AbstractTestRunner<Tests>
    {
        public Tests(StatefulServiceContext context)
            : base(context)
        {
        }

        protected override Tests Self => this;
    }

The static entry point of the service needs to register the service as a TestsType. This part is important because the client side always assumes this test type.

ServiceRuntime.RegisterServiceAsync("TestsType",
                context => new Tests(context)).GetAwaiter().GetResult();

The ServiceManifest.xml needs to declare the stateful service type as well.

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="TestsPkg" Version="1.0.0" ...>
  <ServiceTypes>
    <StatefulServiceType ServiceTypeName="TestsType" ... />
  </ServiceTypes>
...
</ServiceManifest>

The OrderShippingTestsApplication needs to include the previously defined OrderShippingTests project and add the required ApplicationManifest.xml entries.

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
ApplicationTypeName="OrderShippingTestsType" 
ApplicationTypeVersion="1.0.0" 
xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="OrderShippingTests_MinReplicaSetSize" 
DefaultValue="1" />
    <Parameter Name="OrderShippingTests_PartitionCount" 
DefaultValue="1" />
    <Parameter Name="TOrderShippingests_TargetReplicaSetSize" 
DefaultValue="1" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="TestsPkg" 
ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
  </ServiceManifestImport>
  <DefaultServices>
    <Service Name="Tests">
      <StatefulService ServiceTypeName="TestsType" 
TargetReplicaSetSize="[OrderShippingTests_TargetReplicaSetSize]"
MinReplicaSetSize="[OrderShippingTests_MinReplicaSetSize]">
        <SingletonPartition />
      </StatefulService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

Then the sfproj needs to be edited with the following msbuild entry

  <Target Name="ReleaseAfterBuild" AfterTargets="AfterBuild">
    <MSBuild Projects="$(ProjectPath)" Targets="Package" />
  </Target>

The above trickery instructs to build the application package every time the solution is built. Packaging the application descriptor and all the dependent services is a costly operation. It can take up to several seconds. This makes fast iteration on the tests slow but as we will later see that is not the only disadvantage since the actual application deployment to the cluster requires a lot of time as well.

After this is done the only thing left is to add a test called OrderShippingTests that inherits from R to the AllTests project.

    public class OrderShippingTests : R<OrderShippingTests>
    {
    }

Now everything is ready to be able to write tests for the OrderShipping stateful service production code. In the next post, I’ll be looking into how tests can leverage a simple dependency injection approach to get access to the reliable state manager of the test runner service.

About the author

Daniel Marbach

1 comment

Recent Posts