Service Testing in SO-Aware
Service testing is another interesting feature that you will find in SO-Aware. Having a tool for testing a service in the repository is very important for the following reasons,
- You can make sure the service up and running (The service deployment and configuration was done correctly).
- The service is responding to the different requests generated by the tests.
- You can have a better idea of the service availability over the time
As SO-Aware is mostly oriented to WCF services, and also supports artifacts like bindings and behaviors, makes this tool very appealing for testing secure services or services with specific bindings elements (like net.tcp services for instance) that are really hard to test with other existing tools in the market.
The testing tool in SO-Aware supports two models, On-Demand testing and Scheduled testing. In the On-Demand testing model, you basically want to test the service at any moment with an specific message to make sure the service is working or for reproducing an issue, but you don’t want to save that test for being executed later. The Scheduling testing model is the opposite, you want to save the test so it can be executed for the test scheduler service and have results about the service health over the time.
A test and the associated results are also exposed as OData resources in the repository, so you can manage the different tests or query results using simple http requests.
As all the service artifacts (endpoints, contract, operations, schemas) are also stored in the repository, the definition of a new test is quite straightforward, you only need to specify which service version you want to test, the operation and provide a request sample message (which can also be automatically inferred from the schema associated to the operation request message in soap services).
The code below creates a new service using the client API.
1: var customersService = repository.ServiceVersions
2: .Expand("Soap/Endpoints/Contract/Operations")
3: .Where(s => s.Service.Name == "Customers" &&
4: s.MajorVersion == 1 && s.MinorVersion == 0)
5: .FirstOrDefault();
6:
7: var endpoint = customersService.Soap.Endpoints.First();
8: var operation = endpoint.Contract.Operations.First(o => o.Name == "GetCustomer");
9:
10: var testManager = new TestManager(RepositoryUri);
11:
12: var sampleMessage = testManager.CreateExampleStringMessageForOperation(customersService.Id,
13: endpoint.Name, operation.Name);
14:
15: test = new Test
16: {
17: Name = "GetCustomer",
18: UsesWindowsAuthentication = true,
19: Username = "TEST",
20: Password = "password",
21: SchedulingTime = 1,
22: SchedulingUnit = "MINUTE",
23: RequestMessage = sampleMessage
24: };
25:
26: repository.AddToTests(test);
27: repository.SetLink(test, "Operation", operation);
28: repository.SetLink(test, "Endpoint", endpoint);
As you can see, the code for creating a new test for a SOAP service is quite straightforward (Testing of REST services is also supported). Only the endpoint and operation that are going to be tested needs to specified. In that example, I am using an endpoint configured with Windows Authentication, so I am passing the credentials in the test definition as WCF does not support Username/Password credentials as a behavior. Otherwise, the test definition could also receive a behavior with the client credentials (A behavior with the certificate definition for instance).
The TestManager is an utility class that can be used for multiple purposes in the definition of a new test, or also for executing an existing test. The TestManager.CreateExampleStringMessageForOperation returns an string representing an xml message inferred from the operation message schemas.
Once the test definition is stored in the repository, it’s going to start being executed by the Test scheduler according to the scheduling options for that test (SchedulingTime and SchedulingUnit properties in the test definition). You can execute the test at any time with an two specific Http Endpoint that SO-Aware publishes for executing tests.
“Testing.svc/Tests/{testId}” for executing an individual test with a simple http get (The response represents the test results)
“Testing.svc/TestGroups/{groupName}” for executing an set of tests with a simple http get. You can associate a group to the test when this is one is created.
1: WebClient client = new WebClient();
2: client.Credentials = CredentialCache.DefaultCredentials;
3: var response = client.DownloadString("http://localhost/SOAware/Testing.svc/Tests/" + test.Id.ToString());
4:
5: Console.WriteLine(response);
Only one line of code is required for executing a test (an http get), so this becomes handy for integrating the tests as part of a build process too.
The test results are also available as a resource in the repository, so you can query for specific test using the traditional OData query options. The example above illustrates how the most recent test execution result can be got for an specific test.
1: var testResult = repository.TestInstances.Where(t => t.Test.Id == test.Id).Last();
You can always browse the tests and the results in SO-Aware portal for getting a more user friendly representation, and see some statistics about the test executions.
The sample code is available at this location.