Skapa enhetstester från Standard-arbetsflödeskörningar i Azure Logic Apps med Visual Studio Code

Gäller för: Azure Logic Apps (Standard)

Enhetstestning är en viktig metod som håller din app eller lösning tillförlitlig och korrekt under hela livscykeln för programvaruutveckling. Enhetstester hjälper dig att effektivt och systematiskt verifiera de viktigaste komponenterna i din lösning.

För standardarbetsflöden för logikappar kan du skapa enhetstester med hjälp av Visual Studio Code och Tillägget Azure Logic Apps (Standard). Med den här funktionen kan du använda tidigare utförda arbetsflödeskörningar för att skapa enhetstester och skräddarsy dem efter scenarier som stöds av din logikappslösning. Den här metoden ger följande fördelar:

  • Återanvänd arbetsflödeskörningar för att generera mockdata för specifika åtgärder i arbetsflödet.

    Med dessa data kan du testa arbetsflöden utan att behöva anropa externa tjänster, system eller API:er. Du sparar tid och arbetsflödet förblir i linje med det faktiska arbetsflödets körningsscenario.

  • Förbättra arbetsflödets kvalitet genom att identifiera och åtgärda potentiella problem innan du distribuerar till andra miljöer.

  • Effektivisera enhetstestintegrering med din utvecklingsprocess, samtidigt som du säkerställer konsekvent och korrekt arbetsflödesbeteende.

Den här guiden visar hur du skapar en enhetstestdefinition från en arbetsflödeskörning. Den här definitionen hånar de externa anropen från varje arbetsflödesåtgärd utan att ändra arbetsflödeslogik. När du skapar ett enhetstest från en arbetsflödeskörning får du ett enhetstestprojekt som innehåller två mappar:

  • En mapp som innehåller starkt skrivna klasser för varje typbar åtgärd i arbetsflödet.

  • En mapp för varje enhetstestdefinition, som innehåller följande filer:

    • En JSON-fil som representerar de genererade simulerade åtgärderna i arbetsflödet.

    • En C#-fil som innehåller en exempelklass och metoder som du använder för att konfigurera egna intyg, bekräfta att arbetsflödet fungerar som förväntat och se till att arbetsflödet fungerar tillförlitligt och förutsägbart i ditt större Azure-ekosystem.

Förutsättningar

Begränsningar och kända problem

  • Den här versionen stöder för närvarande endast C# för att skapa enhetstester.

  • Den här versionen stöder inte icke-hånade åtgärder. Kontrollera att alla åtgärder i arbetsflödets utförandeväg är simulerade.

  • Den här versionen stöder inte följande åtgärdstyper:

    • Integreringskontoåtgärder
    • Åtgärder för datamappning
    • Anpassade kodåtgärder
    • XML-åtgärder
    • Flytande åtgärder
    • EDI-koda och avkoda processer

Granska de grundläggande begreppen

Följande lista innehåller grundläggande men viktiga begrepp om enhetstester för Standard-arbetsflöden:

  • Enhetstest för logikapp

    En kontrollerad arbetsflödeskörning som matar in falska objekt. Dessa objekt representerar antingen arbetsflödesutlösaren eller åtgärder som är beroende av externa tjänster eller system.

  • Åtgärd som kan simuleras

    En arbetsflödesåtgärd som är beroende av en extern tjänst eller ett externt system. Du kan konvertera dessa åtgärder till simulerade åtgärder för att skapa och köra enhetstest.

Skapa ett enhetstest från en arbetsflödeskörning

  1. Öppna standardlogikappprojektet i Visual Studio Code.

  2. I verktygsfältet Visual Studio Code går du till menyn Kör och väljer Starta felsökning. (Tangentbord: Tryck på F5)

  3. Gå tillbaka till Explorer-fönstret . I projektet expanderar du mappen för arbetsflödesdefinition.

  4. Öppna snabbmenyn workflow.json och välj Översikt.

  5. På översiktssidan går du till Körningshistorik och väljer den arbetsflödeskörning som ska användas för att skapa ett enhetstest.

    Skärmbild som visar Visual Studio Code med standard logikapp-projekt, felsökningsläge som körs, öppnad arbetsflödesöversiktssida och vald arbetsflödeskörning.

  6. I verktygsfältet för körningshistorik väljer du Skapa enhetstest från körning.

    Skärmbild som visar Visual Studio Code, sidan körningshistorik för standardarbetsflöde och valt kommando för att skapa enhetstest.

  7. Ange ett namn som ska användas för enhetstestet, enhetstestklassen och C#-filen.

    I utforskarfönstret visas en ny projektmapp med namnet Tester under mappen för logikappens projekt. Mappen Tester innehåller följande mappar och filer:

    Skärmbild som visar Mappen Visual Studio Code, Standard logic app project och Tests med enhetstestmappar och filer.

    Mapp eller fil Beskrivning
    Tests
    || <logic-app-name>
    I Tests mappen visas en <logic-app-name> mapp när du lägger till enhetstester i ett logikapp-projekt.
    Tests
    || <logic-app-name>
    ||| <workflow-name>
    I mappen <logic-app-name> visas en <workflow-name> mapp när du lägger till enhetstester för ett arbetsflöde.
    Tests
    || <logic-app-name>
    ||| <workflow-name>
    |||| MockOutputs
    |||||<operation-name-outputs>.cs
    <workflow-name> I mappen MockOutputs innehåller mappen en C#-fil (.cs) med starkt skrivna klasser för varje anslutningsåtgärd i arbetsflödet. Varje .cs filnamn använder följande format:

    < operation-name >[Trigger\|Action]Output.cs

    Om en anslutningsåtgärd har dynamiska kontrakt visas en klass för varje dynamisk typ. En dynamisk typ refererar till en åtgärdsparameter som har olika indata och utdata baserat på värdet för parametern. Du kan använda de här klasserna för att utöka enhetstesterna och skapa nya modeller från grunden.
    Tests
    || <logic-app-name>
    ||| <workflow-name>
    |||| <unit-test-name>
    ||||| <unit-test-name>-mock.json
    ||||| <unit-test-name>.cs
    <workflow-name> I mappen <unit-test-name> innehåller mappen följande filer:

    – Filen <unit-test-name>-mock.json innehåller en JSON-representation för de genererade mocks, baserat på arbetsflödeskörningen som skapade enhetstestet.

    – Filen <unit-test-name>.cs innehåller en C#-exempelklass och metoder som använder *-mock.json filen för att köra och kontrollera resultat. Du kan redigera den här filen så att den matchar dina specifika testscenarier.

Granska filen *-mock.json

Den här filen innehåller följande huvudavsnitt:

triggerMocks avsnitt

Avsnittet triggerMocks innehåller det simulerade resultatet från arbetsflödesutlösaren. Det här avsnittet krävs för att starta arbetsflödeskörningen enligt följande exempel:

{
    "triggerMocks": {
        "When_messages_are_available_in_a_queue_(peek-lock)": {
            "name": "When_messages_are_available_in_a_queue_(peek-lock)",
            "status": "Succeeded",
            "outputs": {
                "body": {
                    "contentData": {
                        "messageId": "1234",
                        "status": "new",
                        "contentType": "application/json",
                        "userProperties": {},
                        "scheduledEnqueueTimeUtc": "1/1/0001 12:00:00 AM",
                        "timeToLive": "14.00:00:00",
                        "deliveryCount": 1,
                        "enqueuedSequenceNumber": 0,
                        "enqueuedTimeUtc": "2025-04-07T01:10:09.738Z",
                        "lockedUntilUtc": "2025-04-07T01:11:09.769Z",
                        "lockToken": "78232fa8-03cf-4baf-b1db-3375a64e0ced",
                        "sequenceNumber": 5
                    }
                }
            }
        }
    },
    "actionMocks": {...}
}

actionMocks avsnitt

För varje imiterbar åtgärd i en arbetsflödesexekvering innehåller actionMocks-avsnittet en simulerad åtgärd och garanterar en kontrollerad exekvering av arbetsflödet.

{
    "triggerMocks": {...},
    "actionMocks": {
        "Call_External_API": {
            "name": "Call_External_API",
            "status": "Succeeded",
            "outputs": {
                "statusCode": 200,
                "body": {
                    "status": "Awesome!"
                }
            }
        },
        "CompleteMessage": {
            "name": "CompleteMessage",
            "status": "Succeeded",
            "outputs": {
                "statusCode": "OK",
                "body": {}
            }
        }
    }
}

Granska *.cs-filen för enhetstest

Den här enhetstestklassen tillhandahåller ett ramverk för att testa arbetsflöden i standardlogikappar genom att mocka utlösare och åtgärder. Med den här klassen kan du testa arbetsflöden utan att anropa externa tjänster eller API:er.

Testklassstruktur

En typisk enhetstestklass använder följande struktur:

[TestClass]
public class <unit-test-name>
{
    public TestExecutor TestExecutor;

    [TestInitialize]
    public void Setup()
    {
        this.TestExecutor = new TestExecutor("<workflow-name>/testSettings.config");
    }

    // Add test methods here.

    // Add helper methods here.
}

Setup()-metod

Den här metoden instansierar TestExecutor klassen med hjälp av sökvägen till konfigurationsfilen för testinställningar. Metoden körs före varje testkörning och skapar en ny instans av TestExecutor.

[TestInitialize]
public void Setup()
{
    this.TestExecutor = new TestExecutor("<workflow-name>/testSettings.config");
}

Exempel på testmetoder

I följande avsnitt beskrivs exempeltestmetoder som du kan använda i enhetstestklassen.

Statiskt test av falska data

Följande metod visar hur du använder statiska mock-data för att testa arbetsflödet. I den här metoden kan du utföra följande uppgifter:

  • Ange egenskapsvärden för dina simulerade åtgärder.
  • Kör arbetsflödet med konfigurerade testdata.
  • Bekräfta att exekveringen lyckades.
[TestMethod]
public async Task <workflow-name>_<unit-test-name>_ExecuteWorkflow_SUCCESS_Sample1()
{
    // PREPARE mock: Generate mock action and trigger data.
    var mockData = this.GetTestMockDefinition();
    var sampleActionMock = mockData.ActionMocks["Call_External_API"];
    sampleActionMock.Outputs["your-property-name"] = "your-property-value";

    // ACT: Create the UnitTestExecutor instance. Run the workflow with mock data.
    var testRun = await this.TestExecutor
        .Create()
        .RunWorkflowAsync(testMock: mockData).ConfigureAwait(continueOnCapturedContext: false);

    // ASSERT: Confirm successful workflow execution and that the status is 'Succeeded'.
    Assert.IsNotNull(value: testRun);
    Assert.AreEqual(expected: TestWorkflowStatus.Succeeded, actual: testRun.Status);
}

Dynamiskt modelldatatest

Följande metod visar hur man använder dynamisk mockdata med callbackmetoder. Den här metoden ger dig två alternativ som dynamiskt genererar falska data:

Med båda metoderna kan du skapa dynamiska svar baserat på enhetstestkörningskontexten.

[TestMethod]
public async Task <workflow-name>_<unit-test-name>_ExecuteWorkflow_SUCCESS_Sample2()
{
    // PREPARE: Generate mock action and trigger data.
    var mockData = this.GetTestMockDefinition();
    
    // OPTION 1: Define a callback class.
    mockData.ActionMocks["Call_External_API"] = new CallExternalAPIActionMock(
        name: "Call_External_API", 
        onGetActionMock: CallExternalAPIActionMockOutputCallback);

    // OPTION 2: Define an inline lambda function.
    mockData.ActionMocks["Call_External_API"] = new CallExternalAPIActionMock(
        name: "Call_External_API", 
        onGetActionMock: (testExecutionContext) =>
        {
            return new CallExternalAPIActionMock(
                status: TestWorkflowStatus.Succeeded,
                outputs: new CallExternalAPIActionOutput {

                    // If this account contains a JObject Body, 
                    // set the properties you want here:
                    // Body = "something".ToJObject()

                }
            );
        });
        
    // ACT: Create UnitTestExecutor instance. Run the workflow with mock data.
    var testRun = await this.TestExecutor
        .Create()
        .RunWorkflowAsync(testMock: mockData).ConfigureAwait(continueOnCapturedContext: false);

    // ASSERT: Confirm successful workflow execution and that the status is 'Succeeded'.
    Assert.IsNotNull(value: testRun);
    Assert.AreEqual(expected: TestWorkflowStatus.Succeeded, actual: testRun.Status);
}

Felscenariotest

Följande metod visar hur du testar feltillstånd. I den här metoden kan du utföra följande uppgifter:

  • Konfigurera simulerade åtgärder så att de misslyckas med specifika felkoder och meddelanden.
  • Bekräfta att arbetsflödet hanterar dessa felvillkor korrekt.
[TestMethod]
public async Task <workflow-name>_<unit-test-name>_ExecuteWorkflow_FAILED_Sample3()
{
    // PREPARE: Generate mock action and trigger data.
    var mockData = this.GetTestMockDefinition();
    var mockError = new TestErrorInfo(code: ErrorResponseCode.BadRequest, message: "Input is invalid.");
    mockData.ActionMocks["Call_External_API"] = new CallExternalAPIActionMock(
        status: TestWorkflowStatus.Failed, 
        error: mockError);

    // ACT: Create UnitTestExecutor instance. Run the workflow with mock data.
    var testRun = await this.TestExecutor
        .Create()
        .RunWorkflowAsync(testMock: mockData).ConfigureAwait(continueOnCapturedContext: false);

    // ASSERT: Confirm successful workflow execution and that the status is 'Succeeded'.
    Assert.IsNotNull(value: testRun);
    Assert.AreEqual(expected: TestWorkflowStatus.Failed, actual: testRun.Status);
}

Hjälpmetoder

I följande avsnitt beskrivs metoder som används av exempeltestmetoderna. Hjälpmetoder visas under testmetoderna i klassdefinitionen.

GetTestMockDefinition()

Följande metod läser in den falska definitionen från en JSON-fil. Du kan redigera den här metoden om dina falska data lagras på en annan plats eller i ett annat format.

private TestMockDefinition GetTestMockDefinition()
{
    var mockDataPath = Path.Combine(TestExecutor.rootDirectory, "Tests", TestExecutor.logicAppName, 
        TestExecutor.workflow, "<unit-test-name>", "<unit-test-name>-mock.json");
    return JsonConvert.DeserializeObject<TestMockDefinition>(File.ReadAllText(mockDataPath));
}

Återanropsmetod

Följande metod genererar dynamiskt falska data. Metodnamnet varierar beroende på det simulerade åtgärdsnamnet i testmetoderna för statiska eller dynamiska falska data. Du kan redigera den här metoden för att returnera olika mock-svar baserat på dina testscenariokrav eller använda den som en mall för att skapa dina egna dynamiska återuppringningsmetoder.

public CallExternalAPIActionMock CallExternalAPIActionMockOutputCallback(TestExecutionContext context)
{
    // Sample mock data: Dynamically change the mocked data for "actionName".
    return new CallExternalAPIActionMock(
        status: TestWorkflowStatus.Succeeded,
        outputs: new CallExternalAPIActionOutput {

            // If this account contains a JObject Body, 
            // set the properties you want here:
            // Body = "something".ToJObject()

        }
    );
}