Peaky discovers tests in an application and maps routes to allow them to be called over HTTP. These tests can live within the application they are testing or hosted in a standalone service.
One of the great benefits of Peaky is in moving tests away from the antiquated paradigm where tests are run on local machines to being run from a shareable and accessible location. This does away with ‘works on my machine’ test issues and allows you to easily share, discover, and execute tests.
Peaky also provides users with a CDN-hosted UI out of the box with hooks to provide your own UI experience if you desire.
Peaky aims to remove the barriers between production and pre-production environment tests. With Peaky you register your target environments and their dependencies and let Peaky inject the correct dependency for each test. E.g. a tests that verifies a homepages availability needs to only be written once and depending on the request to Peaky, it can be ran against any target.
Any public method on concrete type derived from IPeakyTest
.
There are a few exceptions. Peaky will not expose the following as tests:
- Properties
- Constructors
- Methods with parameters having no default values
- Methods with a Special Name
Peaky will also discover Its.Log Sensors in all loaded assemblies and expose them via HTTP endpoints.
Check out the Peaky WebApplication Sample to see an example of actual tests being defined and discovered.
Any class that implements IPeakyTest
(or its derived interfaces IApplyToApplication
, IApplyToEnvironment
, IApplyToTarget
, and IHaveTags
) will have its qualifying methods discovered and exposed as tests.
Write a Peaky test much in the same way that you would write any unit test. A test method that throws an exception will return a 500 Internal Server Error response to the caller, signaling failure, and tests that do not throw an exceptions will return 200 OK, signaling success.
public async Task<string> bing_homepage_returned_in_under_5ms()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
await httpClient.GetAsync("/");
stopwatch.Stop();
stopwatch.ElapsedMilliseconds.Should().BeLessThan(5);
return $"{stopwatch.ElapsedMilliseconds} milliseconds";
}
Tests are exposed by default at http://{domain}/tests
To use Peaky 3 with ASP.NET MVC Core, add the following code to your Startup
class.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddPeakyTests(
targets =>
{
targets.Add("production", "bing", new Uri("https://bing.com"))
.Add("test", "bing", new Uri("https://bing.com"))
.Add("production", "microsoft", new Uri("https://microsoft.com"));
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
app.UsePeaky();
}
config.MapTestRoutes(targets => targets.Add("production","bing", new Uri("https://bing.com")));
A peaky URI ( http://yourPeakyApplicationsBaseUri/tests/{environment}/{application}/{testname}
) has 3 major parts to it:
- Application: What is the name of the service under test?
- Environment: What environment are we testing that application in, e.g local, production, or internal, or deployment A or deployment B?
- Test Name: the name of the method discovered as a test
These elements combine to form unique test URIs.
All tests, their tags, and their parameters are discoverable with a query. The following are examples of queries to discover tests:
HTTP GET /tests
will return all tests in the application
HTTP GET /tests/{environment}
will return all tests within the requested environment
HTTP GET /tests/{environment}/{application}
will return all tests for the application within that environment
A test class can implement IHaveTags which will allow for categorization of tests and allow users to filter based upon them:
HTTP GET /tests/{environment}/{application}/?{tag}=true
will only return tests within the test classes with that tag
HTTP GET /tests/{environment}/{application}/?{tag}=false
will return tests except those within the test classes with that tag
Numerous tags can be filtered on with one request.
By default, Peaky will allow your test classes to take a dependency, via constructor injection, on a couple types: HttpClient
and TestTarget
.
public class BingTests : IApplyToApplication, IHaveTags
{
private readonly HttpClient httpClient;
private readonly TestTarget testTarget;
public BingTests(HttpClient httpClient, TestTarget testTarget)
{
this.httpClient = httpClient;
this.testTarget = testTarget;
}
// ...
}
These are configured using the details provided at app startup:
services.AddPeakyTests(
targets =>
{
targets.Add("production", "bing", new Uri("https://bing.com"));
});
config.MapTestRoutes(targets => targets.Add("production","bing", new Uri("https://bing.com")));
This allows any test classes that apply to both 'production' and 'bing' to take a dependency on an HttpClient
or TestTarget
within their constructors, and Peaky will pass configured instances when a test is run.
If you need additional dependencies, they can be registered for constructor injection as follows:
services.AddPeakyTests(
targets =>
{
targets.Add("production",
"bing",
new Uri("https://bing.com"),
dependencies => dependencies.Register(() => new MyDependency()));
});
config.MapTestRoutes(targets =>
targets.Add("production",
"bing",
new Uri("https://bing.com"),
registry => registry.Register(new TableStorageClient())
.Register(new AuthenticatedHttpClient())));