-
-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Where to go from the POC? #1
Comments
An alternative to defining tests in Razor files would be to define SUT components as strings in normal test methods, and somehow trigger the razor compiler. Its still not ideal to write html/razor in strings, but I prefer it to using the builder the library have now. |
I would also suggest removing xunit into its own lib, then we can add other libs for MSTest and nUnit. Although, my next paragraph (if possible) could remove all of these options. Still looking at it to figure out what is going on exactly, but I wouldnt move to strings quite yet, I wonder if there are other options like using "real" razor files. Here is what I am thinking (and i have no idea of it is even possible to do half of the things I am thinking of - which is kind of how Jest works): Have a test project that in it there are a bunch of razor file that are the subject of the test. When the test project run (somehow) - it will execute all the test files and store the strings as files in the test project as .snapshot files with a known name. Next time you run the project it then does the compare to the .snapshot file. What are your thoughts on that, assuming it can even be done? The running the test project part could maybe be a dotnet global tool? |
The library itself does not have a dependency on xUnit. It does have one on XMLUnit, but that is needed to compare the HTML snippets. Shouldly, which it does have a dependency on, as well as Moq, could quite easily be removed. They are my preferred libraries, but not required. I haven't played with Jest in a long time, so not entirely up-to-date on the functionality. I personally like to do TDD, and then snapshot testing isn't needed. That said, I do not think it will be hard to make that work. Here is a rough outline of what would be needed (assuming I understand your idea/requirements correctly): Snapshot testingSolution setup
Testing LibrarySince all modern testing libraries support data driven tests (Theories in xUnit), we can utilize that to create a custom test data source, let us call that
With that, a data driven test will be as simple as this: public class RazorComponentSnapshotTests : RazorComponentFixture
{
[Theory]
[RazorSnapshotTestDataSource]
public void SnapshotTest(Type testComponent, string snapshot)
{
var expectedHtml = snapshot;
var result = Component(testComponent).Render();
result.ShouldBe(expectedHtml);
}
}
The method Considerations
ImprovementsIt would be quite awesome if the test razor components (razor files in test project) could both include the test razor markup and the snapshot/expected html in the same file. Then it is much easier to inspect a test and see everything together. Let me experiment a bit with the above and see if I can hack together a PoC. |
I am working on the TestRunner idea in the meantime (I guess you would say the non TDD version of this), I will let you know if I get anywhere with it - so I dont think I need to change the base lib, we can have both versions working. |
I think we are working on the same thing to be honest. My approach would just be to utilize the visual studio test framework to execute a test runner. For my initial PoC that will be the xunit test runner. With that approach we will reuse all the existing tooling around unittest runners. |
Yes, I understand that is what you are doing, I am doing something slightly different, using the same library, I am making a console app (that could turn into a dotnet global tool maybe) that would load all Components from the library being tested and snapshot them. Both ways are useful and shouldnt conflict with each other |
OK. I agree, both are useful. Let me know when you have something. Should we set up a Gitter channel to chat about this? |
I got defining tests in a razor file working locally. Currently, this is what a test can look like ( @using Microsoft.Extensions.DependencyInjection;
@code {
ServiceCollection TestServices
{
get
{
var res = new ServiceCollection();
// Add mocked services etc. here, e.g.: res.AddSingleton(x => Mock.Of<IJSRuntime>());
return res;
}
}
}
<Fact DisplayName="Component renders without params 2" Services=TestServices>
<Setup>
<Component1 />
</Setup>
<ExpectedOutput>
<div class="my-component xxx">
This Blazor component is defined in the <strong>ComponentLib</strong> package.
</div>
</ExpectedOutput>
</Fact>
<Fact>
<Setup>
<Component1 />
</Setup>
<ExpectedOutput>
<div class="my-component">
This Blazor component is defined in the <strong>ComponentLib</strong> package.
</div>
</ExpectedOutput>
</Fact> I have a special template component named If you do not need to pass a custom service collection to component under test, a test razor component can be as simple as this, where one or more Fact components is included: <Fact DisplayName="Component renders without params 2">
<Setup><Component1 /></Setup>
<ExpectedOutput>
<div class="my-component xxx">
This Blazor component is defined in the <strong>ComponentLib</strong> package.
</div>
</ExpectedOutput>
</Fact> To run the tests, another class is needed, that XUnit will run. Right now it is enough to have a minimal class that just inherits from the public class Component1Tests : RazorComponentTestFixture { } How do you like this syntax compared to the original? I like it quite a lot, because it makes it so much nicer to Setup the component under test with params and everything and also specify expected output, since VS will provide intellisense, and we dont have to escape quotes in strings, etc. No snapshotting yet, but it should be possible. My idea here is to allow the original .razor file to be modified and have its |
I have pushed my current progress to the |
OK guys, think I have a pretty good solution for defining unit tests in razor files. It solves a few of the issues mentioned originally, namely:
Currently, all relevant code is in this folder: https://github.com/egil/razor-component-testing-library/tree/egil-snapshot-testing/sample/ComponentLibTests Example:Simple @inherits RazorComponentTest
<Fact>
<Setup>
<Component1 />
</Setup>
<ExpectedOutput>
<div class="my-component">
This Blazor component is defined in the <strong>ComponentLib</strong> package.
</div>
</ExpectedOutput>
</Fact> Another example that shows of a few other possiblities: @inherits RazorComponentTest
@using Xunit
@using Moq
@using Shouldly
@using Microsoft.Extensions.DependencyInjection
@using Microsoft.JSInterop
@code{
// Override AddServices to provide services used when renderinger
protected override void AddServices(IServiceCollection services)
{
services.AddScoped<IJSRuntime>(_ => Mock.Of<IJSRuntime>());
}
// Use @ref to get a reference to the tested element
Component1 sut1;
// Add more than the default input/output html test in @code sections
[Fact]
public void CanReadPropFromSut()
{
sut1.AccessibleProp.ShouldBeTrue();
}
}
<Fact>
<Setup><Component1 @ref="@sut1" /></Setup>
<ExpectedOutput>
<div class="my-component">
This Blazor component is defined in the <strong>ComponentLib</strong> package.
</div>
</ExpectedOutput>
</Fact>
@code {
// Access rendered result of Fact elements in the RenderResults list.
[Fact]
public void AnotherTest()
{
var expectedText = "This Blazor component is defined in the ComponentLib package.";
RenderResults[1].RenderedHtml.InnerText.Trim().ShouldBe(expectedText);
}
}
<Fact>
<Setup><Component1 /></Setup>
<ExpectedOutput>
<div class="my-component">
This Blazor component is defined in the <strong>ComponentLib</strong> package.
</div>
</ExpectedOutput>
</Fact> TODO:
SnapshottingI prefer if we update the original Two challenges with this:
Please provide some feedback to the above! |
I'll close this issue, and create a separate for snapshotting. |
Snapshotting moved to its own issue: #1 |
Getting latest changes for docs from egil/bUnit dev branch.
The current iteration makes it fairly easy to test the initially generated HTML, in a fairly stable manner (spacing ignored, order of css classes doesnt matter, etc.).
However, a few shortcomings exists currently:
Idears:
I like the idea of defining component tests in a .razor file, that inherits from a
ComponentTestFixture
class.ComponentTestFixture
would be responsible for having the correct unit testing framework annotations, render the SUT component and grap the expected HTML.It could also support various steps, where each step matches a step in a components life-cycle (i.e. first render, users interaction, parameter changed, disposed). E.g. something like this:
The text was updated successfully, but these errors were encountered: