Class BlazorInteractiveTestRunner
- Namespace
- Dmnk.Blazor.InteractiveTests
- Assembly
- Dmnk.Blazor.InteractiveTests.dll
This class provides a way for you to write nunit/xunit/whatever "tests" that show a particular blazor component in a window. We call these "tests" interactive tests (not sure if there is a commonly accepted term for this).
This is not intended for actual automated testing. Rather, it is a way for you to work on and manually test a component without starting your whole application - which becomes especially useful in a large application.
Note that your components will be run in a Blazor Hybrid style webview. Running a blazor component in webassembly-mode is not supported since that would require an actual project instead of just a single loose component. And we would have to mock http calls, and debugging would be more difficult, and... it's just not worth it. But do keep that in mind as there may be things that will work in you interactive test but not in the final app if it's deployed as WASM.
Regrettably, this is windows-only, because it relies on the WinForms implementation of BlazorWebView. Implementations of a Blazor Hybrid style webview for other platforms seem to *kind of sort of* exist as community packages. If demand arises, that may be worth looking into. The API shape should allow this to become cross-platform without breaking changes.
public static class BlazorInteractiveTestRunner
- Inheritance
-
BlazorInteractiveTestRunner
- Inherited Members
Examples
(Assuming NUnit, details are probably slightly different for other testing frameworks.)
In My.BlazorLibrary\Counter.razor: Well, a counter component
In My.BlazorLibrary.Tests\Setup.cs:
[SetUpFixture]
public class TestSetUp
{
[OneTimeSetUp]
public void Setup() => BlazorInteractiveTestRunner.PathInfo =
InteractiveTestsProjectPathInfo.FromAssemblyInSolutionDir(GetType().Assembly);
}
In My.BlazorLibrary.Tests\MyInteractiveTests.cs:
// MUST be explicit - it will not terminate on its own.
[Test, Explicit]
public async Task Show_Counter_Component()
{
// This will open up a window with just your `Counter` component so you can play
// with it without starting the whole app.
await BlazorInteractiveTestRunner.ShowComponent<Counter>();
}
Properties
PathInfo
Set this once globally (using one of the setter methods) before calling any of the ShowComponent methods.
Used to determine the location of the staticwebassets.*.json files, which are
required for any BlazorWebView to function (and produced automatically on build by default,
you shouldn't have to worry about that).
public static InteractiveTestsProjectPathInfo? PathInfo { get; set; }
Property Value
Examples
BlazorInteractiveTestRunner.PathInfo = InteractiveTestsProjectPathInfo.FromAssemblyInSolutionDir( typeof(MyTypeInTestProject).Assembly);
Methods
ShowComponent<TComponent>(Action<BlazorComponentParametersBuilder<TComponent>>, IServiceCollection?)
Show the blazor component given by TComponent in a (WinForms) Dialog.
You MUST set PathInfo using one of the SetTestProjectDir methods before calling this.
public static Task ShowComponent<TComponent>(Action<BlazorComponentParametersBuilder<TComponent>> configureComponent, IServiceCollection? services = null) where TComponent : ComponentBase
Parameters
configureComponentAction<BlazorComponentParametersBuilder<TComponent>>Build up a list of parameters for the component.
servicesIServiceCollectionWhen a blazor component uses
@injector[Inject], the service will be resolved using this collection.
Returns
Type Parameters
TComponentThe actual component type
Examples
BlazorInteractiveTestRunner.ShowComponent<MyComponent>(
parameters => parameters
.Add(component => component.MyParameter, 4)
.Add(component => component.MyOtherParameter, "hi"));
ShowComponent<T>(Dictionary<string, object?>?, IServiceCollection?)
A more advanced version of the more type-safe expression based overload ShowComponent<TComponent>(Action<BlazorComponentParametersBuilder<TComponent>>, IServiceCollection?), which allows you to define the parameters as a raw dictionary.
You typically shouldn't need to use this.
public static Task ShowComponent<T>(Dictionary<string, object?>? parameters = null, IServiceCollection? services = null) where T : ComponentBase
Parameters
parametersDictionary<string, object>servicesIServiceCollection
Returns
Type Parameters
T
Examples
BlazorInteractiveTestRunner.ShowComponent<MyComponent>(
new Dictionary<string, object?>()
{
{ "MyParameter", 4 },
{ "MyOtherParameter", "hi" },
});
ShowComponent<TComponent, TTestBed>(Action<BlazorComponentParametersBuilder<TComponent>>, Action<BlazorComponentParametersBuilder<TTestBed>>?, IServiceCollection?)
Allows you to additionally provide a testbed component, which is excepted to have a
ChildContent parameter that the SUT component will then be wrapped in.
public static Task ShowComponent<TComponent, TTestBed>(Action<BlazorComponentParametersBuilder<TComponent>> configureComponent, Action<BlazorComponentParametersBuilder<TTestBed>>? configureTestBed = null, IServiceCollection? services = null) where TComponent : ComponentBase where TTestBed : ComponentBase
Parameters
configureComponentAction<BlazorComponentParametersBuilder<TComponent>>configureTestBedAction<BlazorComponentParametersBuilder<TTestBed>>servicesIServiceCollection
Returns
Type Parameters
TComponentTTestBed
ShowComponent<TComponent, TTestBed>(Dictionary<string, object?>?, Dictionary<string, object?>?, IServiceCollection?)
Allows you to additionally provide a testbed component, which is excepted to have a
ChildContent parameter that the SUT component will then be wrapped in.
public static Task ShowComponent<TComponent, TTestBed>(Dictionary<string, object?>? componentParameters = null, Dictionary<string, object?>? testBedParameters = null, IServiceCollection? services = null) where TComponent : ComponentBase
Parameters
componentParametersDictionary<string, object>testBedParametersDictionary<string, object>servicesIServiceCollection
Returns
Type Parameters
TComponentTTestBed