Crazor.Test
1.0.12-beta
dotnet add package Crazor.Test --version 1.0.12-beta
NuGet\Install-Package Crazor.Test -Version 1.0.12-beta
<PackageReference Include="Crazor.Test" Version="1.0.12-beta" />
paket add Crazor.Test --version 1.0.12-beta
#r "nuget: Crazor.Test, 1.0.12-beta"
// Install Crazor.Test as a Cake Addin #addin nuget:?package=Crazor.Test&version=1.0.12-beta&prerelease // Install Crazor.Test as a Cake Tool #tool nuget:?package=Crazor.Test&version=1.0.12-beta&prerelease
Writing Unit Tests for cards
Crazor has a companion assembly called Crazor.Test which implements helper classes/methods to make it super easy to test the logic of your cards.
To start you create a MSTest test project
Add Crazor package
Add the Crazor.Test package
nuget add package crazor.test
Modifications to your Web Project
Edit the .csproj to make it a aspnetcore project change
<Project Sdk="Microsoft.NET.Sdk">
to<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
add a Cards folder (should be a peer to Pages folder)
add Cards/_ViewImports.cshtml file containing this:
@using AdaptiveCards @using Crazor @using Crazor.Exceptions @using Crazor.Attributes @using System.Threading; @using System.Threading.Tasks; @using System.ComponentModel.DataAnnotations @removeTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @removeTagHelper *, Microsoft.AspNetCore.Mvc.Razor @addTagHelper *, Crazor @addTagHelper *, {YOUR ASSEMBLY NAME HERE}
Creating a unit test
Now we will create a card and write a unit tests against the card.
Create a test card Foo
Create a test card folder in cards/Foo
Create a Default.cshtml file in it
@inherits CardView <Card Version="1.5"> <TextBlock>Counter=@Counter</TextBlock> <Action.Execute Verb="@nameof(OnSubmit)"/> </Card> @functions { public int Counter {get;set;} public void OnSubmit() => Counter++; }
Now create a unit test for it by creating a .cs file called TestFoo.cs and deriving your class for CardTest
using AdaptiveCards; using Crazor.Test; using Crazor.Test.MSTest; namespace MyTests { [TestClass] public class TestFoo : CardTest { [TestMethod] public async Task TestIncrementCounter() { // create an instance of the card by binding to it's route. await LoadCard("/Cards/Foo") // add assertion against the card .AssertTextBlock("Counter=0") // submit an action .ExecuteAction("OnSubmit") // write assertions agains the card that is returned .AssertTextBlock("Counter=1"); } } }
That's it! The pattern is essentially that you
- use LoadCard(route) to instantiate a card.
- You write assertions against the card
- call ExecuteAction() to send input into the card.
- You write assertions against the card
Method | Description |
---|---|
LoadCard(route) | Load a card |
ExecuteAction(verb, data) | Invoke a verb (mimic a button click on an action). You can pass any arbitrary data payload to simulate input |
Assertion Methods
Method | Description |
---|---|
AssertTextBlock(text) | Assert there is a textblock with a text value |
AssertTextBlock(id, text) | Assert that TextBlock with Id has a text value |
AssertNoTextBlock(text) | Assert that there is no TextBlock with a text value |
AssertHas<T>() | Assert there is an element of type T in the card |
AssertHas<T>(id) | Assert there is an element of type T with id in the card |
AssertHasNo<T>() | Assert there is no element of type T in the card |
AssertHasNo<T>(id) | Assert there is no element of type T with id in the card. |
AssertElement<T>(id, callback) | Find Element of type T and id and pass to the callback for custom assertion. |
AssertElements<T>(callback) | Find all elements of type T and pass to the callback for custom assertion |
AssertCard(callback) | call callback with the card for custom assertions. |
Writing a custom assertion extension
All of the assertion methods are extensions to Task<CardTestContext>, so it is easy to create your own assertion helpers.
Here is the implementation of AssertTextBlock. You can see that you await the task to get the context. The context has
- Card - the adaptive card
- Services - The dependency injection services provider.
And it always returns the context back out so that the assertions can be chained together in a fluent style.
public static async Task<CardTestContext> AssertTextBlock(this Task<CardTestContext> contextTask, string id, string text)
{
var context = await contextTask;
var actual = context.Card.GetElements<AdaptiveTextBlock>().SingleOrDefault(el => el.Id == id)?.Text;
Assert.AreEqual(text, actual, $"TextBlock[{id}] Expected:'{text}' Actual:'{actual}'");
return context;
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- Crazor (>= 1.0.12-beta)
- Crazor.Server (>= 1.0.12-beta)
- Microsoft.NET.Test.Sdk (>= 17.9.0)
- MSTest.TestAdapter (>= 3.3.1)
- MSTest.TestFramework (>= 3.3.1)
- System.Net.Http (>= 4.3.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.12-beta | 62 | 9/6/2024 |
1.0.11-beta | 60 | 6/21/2024 |
1.0.10-beta | 63 | 6/13/2024 |
1.0.9-beta | 67 | 6/9/2024 |
1.0.8-beta | 71 | 6/7/2024 |
1.0.7-beta | 65 | 6/5/2024 |
1.0.6-beta | 57 | 6/3/2024 |
1.0.5-beta | 68 | 5/22/2024 |
1.0.4-beta | 51 | 5/14/2024 |
1.0.3-beta | 62 | 5/11/2024 |
1.0.2-beta | 67 | 5/1/2024 |
1.0.1-beta | 57 | 5/1/2024 |