diff --git a/src/Tools/AI Test Toolkit/AITestSummary.xlsx b/src/Tools/AI Test Toolkit/AITestSummary.xlsx new file mode 100644 index 0000000000..e938bfeb3b Binary files /dev/null and b/src/Tools/AI Test Toolkit/AITestSummary.xlsx differ diff --git a/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al b/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al index dd68b22f82..59d2417505 100644 --- a/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al @@ -123,6 +123,15 @@ codeunit 149044 "AIT Test Context" AITTestContextImpl.SetTestMetric(TestMetric); end; + /// <summary> + /// Sets the accuracy of the test. + /// </summary> + /// <param name="Accuracy">The accuracy as a decimal between 0 and 1.</param> + procedure SetAccuracy(Accuracy: Decimal) + begin + AITTestContextImpl.SetAccuracy(Accuracy); + end; + var AITTestContextImpl: Codeunit "AIT Test Context Impl."; } \ No newline at end of file diff --git a/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al b/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al index 1499ffb8df..ce0f1dc83c 100644 --- a/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al @@ -18,9 +18,12 @@ codeunit 149043 "AIT Test Context Impl." var AITTestSuiteMgt: Codeunit "AIT Test Suite Mgt."; GlobalTestOutputJson: Codeunit "Test Output Json"; + GlobalAccuracy: Decimal; CurrentTurn: Integer; NumberOfTurns: Integer; IsMultiTurn: Boolean; + AccuracySetManually: Boolean; + AccuracyErr: Label 'Accuracy must be between 0 and 1.'; AnswerTok: Label 'answer', Locked = true; ContextTok: Label 'context', Locked = true; GroundTruthTok: Label 'ground_truth', Locked = true; @@ -146,6 +149,34 @@ codeunit 149043 "AIT Test Context Impl." SetSuiteTestOutput(CurrentTestOutputJson.ToText()); end; + /// <summary> + /// Sets the accuracy of the test. + /// </summary> + /// <param name="Accuracy">The accuracy as a decimal between 0 and 1.</param> + procedure SetAccuracy(Accuracy: Decimal) + begin + if (Accuracy < 0) or (Accuracy > 1) then + Error(AccuracyErr); + + AccuracySetManually := true; + GlobalAccuracy := Accuracy; + end; + + /// <summary> + /// Gets the accuracy of the test. Can only be retrieved if the accuracy of the test was already set manually. + /// </summary> + /// <param name="Accuracy">The accuracy as a decimal between 0 and 1.</param> + /// <returns>True if it was possible to get the accuracy, false otherwise.</returns> + procedure GetAccuracy(var Accuracy: Decimal): Boolean + begin + if AccuracySetManually then begin + Accuracy := GlobalAccuracy; + exit(true); + end; + + exit(false); + end; + /// <summary> /// Sets to next turn for multiturn testing. /// </summary> @@ -155,7 +186,7 @@ codeunit 149043 "AIT Test Context Impl." if not IsMultiTurn then exit(false); - if CurrentTurn + 1 > NumberOfTurns then + if CurrentTurn > NumberOfTurns then exit(false); CurrentTurn := CurrentTurn + 1; @@ -164,7 +195,7 @@ codeunit 149043 "AIT Test Context Impl." end; /// <summary> - /// Gets the current turn for multiturn testing. Turns start from turn 0. + /// Gets the current turn for multiturn testing. Turns start from turn 1. /// </summary> /// <returns>The current turn number.</returns> procedure GetCurrentTurn(): Integer @@ -172,6 +203,15 @@ codeunit 149043 "AIT Test Context Impl." exit(CurrentTurn); end; + /// <summary> + /// Gets the total number of turns for multiturn testing. + /// </summary> + /// <returns>The total number of turns for the line.</returns> + procedure GetNumberOfTurns(): Integer + begin + exit(NumberOfTurns); + end; + /// <summary> /// This method starts the scope of the Run Procedure scenario. /// </summary> @@ -205,12 +245,16 @@ codeunit 149043 "AIT Test Context Impl." TestInput: Codeunit "Test Input"; TurnsInputJson: Codeunit "Test Input Json"; begin - CurrentTurn := 0; + AccuracySetManually := false; + GlobalAccuracy := 0; + CurrentTurn := 1; GlobalTestOutputJson.Initialize(); TurnsInputJson := TestInput.GetTestInput().ElementExists(TurnsTok, IsMultiTurn); if IsMultiTurn then - NumberOfTurns := TurnsInputJson.GetElementCount() - 1; + NumberOfTurns := TurnsInputJson.GetElementCount() + else + NumberOfTurns := 1; end; /// <summary> @@ -223,7 +267,7 @@ codeunit 149043 "AIT Test Context Impl." TestInput: Codeunit "Test Input"; begin if IsMultiTurn then - TestInputJson := TestInput.GetTestInput(TurnsTok).ElementAt(CurrentTurn).Element(ElementName) + TestInputJson := TestInput.GetTestInput(TurnsTok).ElementAt(CurrentTurn - 1).Element(ElementName) else TestInputJson := TestInput.GetTestInput(ElementName); end; diff --git a/src/Tools/AI Test Toolkit/src/AITTestRunIteration.Codeunit.al b/src/Tools/AI Test Toolkit/src/AITTestRunIteration.Codeunit.al index 4565bd168a..6ff6678936 100644 --- a/src/Tools/AI Test Toolkit/src/AITTestRunIteration.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/AITTestRunIteration.Codeunit.al @@ -21,6 +21,9 @@ codeunit 149042 "AIT Test Run Iteration" GlobalTestMethodLine: Record "Test Method Line"; NoOfInsertedLogEntries: Integer; GlobalAITokenUsedByLastTestMethodLine: Integer; + GlobalNumberOfTurnsForLastTestMethodLine: Integer; + GlobalNumberOfTurnsPassedForLastTestMethodLine: Integer; + GlobalTestAccuracy: Decimal; GlobalSessionAITokenUsed: Integer; trigger OnRun() @@ -124,6 +127,21 @@ codeunit 149042 "AIT Test Run Iteration" exit(GlobalAITokenUsedByLastTestMethodLine); end; + procedure GetNumberOfTurnsForLastTestMethodLine(): Integer + begin + exit(GlobalNumberOfTurnsForLastTestMethodLine); + end; + + procedure GetNumberOfTurnsPassedForLastTestMethodLine(): Integer + begin + exit(GlobalNumberOfTurnsPassedForLastTestMethodLine); + end; + + procedure GetAccuracyForLastTestMethodLine(): Decimal + begin + exit(GlobalTestAccuracy); + end; + [InternalEvent(false)] procedure OnBeforeRunIteration(var AITTestSuite: Record "AIT Test Suite"; var AITTestMethodLine: Record "AIT Test Method Line") begin @@ -144,6 +162,14 @@ codeunit 149042 "AIT Test Run Iteration" // Update AI Token Consumption GlobalAITokenUsedByLastTestMethodLine := 0; + + // Update Turns + GlobalNumberOfTurnsPassedForLastTestMethodLine := 0; + GlobalNumberOfTurnsForLastTestMethodLine := 1; + + // Update Test Accuracy + GlobalTestAccuracy := 0; + GlobalSessionAITokenUsed := AOAIToken.GetTotalServerSessionTokensConsumed(); AITContextCU.StartRunProcedureScenario(); @@ -154,6 +180,7 @@ codeunit 149042 "AIT Test Run Iteration" var AITContextCU: Codeunit "AIT Test Context Impl."; AOAIToken: Codeunit "AOAI Token"; + Accuracy: Decimal; begin if ActiveAITTestSuite.Code = '' then exit; @@ -166,6 +193,19 @@ codeunit 149042 "AIT Test Run Iteration" // Update AI Token Consumption GlobalAITokenUsedByLastTestMethodLine := AOAIToken.GetTotalServerSessionTokensConsumed() - GlobalSessionAITokenUsed; + // Update Turns + GlobalNumberOfTurnsForLastTestMethodLine := AITContextCU.GetNumberOfTurns(); + GlobalNumberOfTurnsPassedForLastTestMethodLine := AITContextCU.GetCurrentTurn(); + + if not IsSuccess then + GlobalNumberOfTurnsPassedForLastTestMethodLine -= 1; + + // Update Test Accuracy + if AITContextCU.GetAccuracy(Accuracy) then + GlobalTestAccuracy := Accuracy + else + GlobalTestAccuracy := GlobalNumberOfTurnsPassedForLastTestMethodLine / GlobalNumberOfTurnsForLastTestMethodLine; + AITContextCU.EndRunProcedureScenario(CurrentTestMethodLine, IsSuccess); Commit(); end; diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITLogEntries.Page.al b/src/Tools/AI Test Toolkit/src/Logs/AITLogEntries.Page.al index 123d63634e..d385fafb3e 100644 --- a/src/Tools/AI Test Toolkit/src/Logs/AITLogEntries.Page.al +++ b/src/Tools/AI Test Toolkit/src/Logs/AITLogEntries.Page.al @@ -68,6 +68,23 @@ page 149033 "AIT Log Entries" { StyleExpr = StatusStyleExpr; } + field(Accuracy; Rec."Test Method Line Accuracy") + { + } + field("No. of Turns Passed"; Rec."No. of Turns Passed") + { + Visible = false; + } + field("No. of Turns"; Rec."No. of Turns") + { + Visible = false; + } + field(TurnsText; TurnsText) + { + StyleExpr = TurnsStyleExpr; + Caption = 'No. of Turns Passed'; + ToolTip = 'Specifies the number of turns that passed out of the total number of turns.'; + } field("Orig. Status"; Rec."Original Status") { Visible = false; @@ -253,6 +270,19 @@ page 149033 "AIT Log Entries" Page.Run(Page::"AIT Test Data Compare", Rec); end; } + action("Download Test Summary") + { + Caption = 'Download Test Summary'; + Image = Export; + ToolTip = 'Downloads a summary of the test results.'; + + trigger OnAction() + var + AITTestSuiteMgt: Codeunit "AIT Test Suite Mgt."; + begin + AITTestSuiteMgt.DownloadTestSummary(Rec); + end; + } } area(Promoted) { @@ -279,6 +309,9 @@ page 149033 "AIT Log Entries" actionref("View Test Data_Promoted"; "View Test Data") { } + actionref("Export Results_Promoted"; "Download Test Summary") + { + } } } } @@ -287,20 +320,26 @@ page 149033 "AIT Log Entries" ClickToShowLbl: Label 'Show data input'; DoYouWantToDeleteQst: Label 'Do you want to delete all entries within the filter?'; InputText: Text; + TurnsText: Text; OutputText: Text; ErrorMessage: Text; ErrorCallStack: Text; StatusStyleExpr: Text; + TurnsStyleExpr: Text; TestRunDuration: Duration; IsFilteredToErrors: Boolean; ShowSensitiveData: Boolean; trigger OnAfterGetRecord() + var + AITTestSuiteMgt: Codeunit "AIT Test Suite Mgt."; begin TestRunDuration := Rec."Duration (ms)"; + TurnsText := AITTestSuiteMgt.GetTurnsAsText(Rec); SetInputOutputDataFields(); SetErrorFields(); SetStatusStyleExpr(); + SetTurnsStyleExpr(); end; local procedure SetStatusStyleExpr() @@ -315,6 +354,18 @@ page 149033 "AIT Log Entries" end; end; + local procedure SetTurnsStyleExpr() + begin + case Rec."No. of Turns Passed" of + Rec."No. of Turns": + TurnsStyleExpr := 'Favorable'; + 0: + TurnsStyleExpr := 'Unfavorable'; + else + TurnsStyleExpr := 'Ambiguous'; + end; + end; + local procedure SetErrorFields() begin ErrorMessage := ''; diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al b/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al index efe7955c0e..679b9cb89a 100644 --- a/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al +++ b/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al @@ -159,6 +159,21 @@ table 149034 "AIT Log Entry" { Caption = 'Output Data'; } + field(40; "No. of Turns"; Integer) + { + Caption = 'Total number of turns'; + ToolTip = 'Specifies the total number of turns.'; + } + field(41; "No. of Turns Passed"; Integer) + { + Caption = 'Number of turns passed'; + ToolTip = 'Specifies the number of turns passed.'; + } + field(45; "Test Method Line Accuracy"; Decimal) + { + Caption = 'Test Method Line Accuracy'; + ToolTip = 'Specifies the accuracy of the test line. The accuracy is calculated as the percentage of turns that passed or can be set manually in the test.'; + } field(50; "Tokens Consumed"; Integer) { Caption = 'Total Tokens Consumed'; diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al index 456639fbb0..071e3c5b15 100644 --- a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al +++ b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al @@ -121,6 +121,12 @@ page 149032 "AIT Run History" AITLogEntryCodeunit.DrillDownFailedAITLogEntries(Rec."Test Suite Code", Rec."Line No. Filter", Rec.Version); end; } + field("Accuracy - By Version"; Rec."Accuracy Per Version") + { + Visible = ViewBy = ViewBy::Version; + Caption = 'Accuracy'; + ToolTip = 'Specifies the average accuracy of the version.'; + } field("Duration - By Version"; Rec."Total Duration (ms)") { Visible = ViewBy = ViewBy::Version; @@ -161,6 +167,12 @@ page 149032 "AIT Run History" AITLogEntryCodeunit.DrillDownFailedAITLogEntries(Rec."Test Suite Code", Rec."Line No. Filter", Rec.Tag); end; } + field("Accuracy - By Tag"; Rec."Accuracy - By Tag") + { + Visible = ViewBy = ViewBy::Tag; + Caption = 'Accuracy'; + ToolTip = 'Specifies the average accuracy of the tag.'; + } field("Duration - By Tag"; Rec."Total Duration (ms) - By Tag") { Visible = ViewBy = ViewBy::Tag; diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al index 8194182f71..dfeb99366f 100644 --- a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al +++ b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al @@ -73,6 +73,14 @@ table 149036 "AIT Run History" FieldClass = FlowField; CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Test Suite Code"), Version = field("Version"), "Test Method Line No." = field("Line No. Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); } + field(14; "Accuracy Per Version"; Decimal) + { + Caption = 'Accuracy'; + ToolTip = 'Specifies the average accuracy of the version.'; + Editable = false; + FieldClass = FlowField; + CalcFormula = average("AIT Log Entry"."Test Method Line Accuracy" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No. Filter"), Version = field("Version"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); + } field(20; "No. of Tests Executed - By Tag"; Integer) { Caption = 'No. of Tests Executed'; @@ -105,6 +113,14 @@ table 149036 "AIT Run History" FieldClass = FlowField; CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No. Filter"), Tag = field(Tag), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); } + field(24; "Accuracy - By Tag"; Decimal) + { + Caption = 'Accuracy'; + ToolTip = 'Specifies the average accuracy of the tag.'; + Editable = false; + FieldClass = FlowField; + CalcFormula = average("AIT Log Entry"."Test Method Line Accuracy" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No. Filter"), Tag = field(Tag), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); + } } keys diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITTestSummary.Report.al b/src/Tools/AI Test Toolkit/src/Logs/AITTestSummary.Report.al new file mode 100644 index 0000000000..5c959e62fc --- /dev/null +++ b/src/Tools/AI Test Toolkit/src/Logs/AITTestSummary.Report.al @@ -0,0 +1,72 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace System.TestTools.AITestToolkit; + +report 149030 "AIT Test Summary" +{ + Caption = 'AI Test Summary'; + ApplicationArea = All; + UsageCategory = Tasks; + DefaultLayout = Excel; + ExcelLayout = 'AITestSummary.xlsx'; + + dataset + { + dataitem(Results; "AIT Log Entry") + { + RequestFilterFields = Version; + RequestFilterHeading = 'AI Test Log Entries'; + + column(CodeunitID; Results."Codeunit ID") + { + } + column(Name; Results."Codeunit Name") + { + } + column(TestName; Results."Procedure Name") + { + } + column(Status; Results.Status) + { + } + column(Accuracy; Results."Test Method Line Accuracy") + { + } + column(TurnsExecuted; Results."No. of Turns") + { + } + column(TurnsPassed; Results."No. of Turns Passed") + { + } + column(Input; Input) + { + } + column(Output; Output) + { + } + column(Error_Message; ErrorMessage) + { + } + column(Error; ErrorCallstack) + { + } + + trigger OnAfterGetRecord() + begin + Input := Results.GetInputBlob(); + Output := Results.GetOutputBlob(); + ErrorMessage := Results.GetMessage(); + ErrorCallstack := Results.GetErrorCallStack(); + end; + } + } + + var + Input: Text; + Output: Text; + ErrorMessage: Text; + ErrorCallstack: Text; +} \ No newline at end of file diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al index 7f582e6ed4..91e3925e07 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al @@ -166,6 +166,30 @@ table 149032 "AIT Test Method Line" FieldClass = FlowField; CalcFormula = count("AIT Log Entry" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Base Version Filter"))); } + field(40; "No. of Turns"; Integer) + { + Caption = 'No. of Turns Executed'; + ToolTip = 'Specifies the total number of turns for the test line.'; + Editable = false; + FieldClass = FlowField; + CalcFormula = sum("AIT Log Entry"."No. of Turns" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Version Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); + } + field(41; "No. of Turns Passed"; Integer) + { + Caption = 'No. of Turns Passed'; + ToolTip = 'Specifies the total number of passed turns for the test line.'; + Editable = false; + FieldClass = FlowField; + CalcFormula = sum("AIT Log Entry"."No. of Turns Passed" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Version Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); + } + field(45; "Test Method Line Accuracy"; Decimal) + { + Caption = 'Accuracy'; + ToolTip = 'Specifies the average accuracy of the test line. The accuracy is calculated as the percentage of turns that passed or can be set manually by the test.'; + Editable = false; + FieldClass = FlowField; + CalcFormula = average("AIT Log Entry"."Test Method Line Accuracy" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Version Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); + } field(101; "AL Test Suite"; Code[10]) { Caption = 'AL Test Suite'; diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al index 7af836cbed..8df370b565 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al @@ -73,6 +73,52 @@ page 149034 "AIT Test Method Lines" AITLogEntry.DrillDownFailedAITLogEntries(Rec."Test Suite Code", Rec."Line No.", AITTestSuite.Version); end; } + field(Accuracy; Rec."Test Method Line Accuracy") + { + } + field(TurnsText; TurnsText) + { + Visible = false; + Editable = false; + Caption = 'No. of Turns Passed'; + ToolTip = 'Specifies the number of turns that passed out of the total number of turns.'; + + trigger OnDrillDown() + var + AITTestSuite: Record "AIT Test Suite"; + AITLogEntry: Codeunit "AIT Log Entry"; + begin + AITTestSuite.SetLoadFields("Base Version"); + AITTestSuite.Get(Rec."Test Suite Code"); + AITLogEntry.DrillDownFailedAITLogEntries(Rec."Test Suite Code", Rec."Line No.", AITTestSuite."Base Version"); + end; + } + field("No. of Turns"; Rec."No. of Turns") + { + Visible = false; + } + field("No. of Turns Passed"; Rec."No. of Turns Passed") + { + Visible = false; + } + field("No. of Turns Failed"; Rec."No. of Turns" - Rec."No. of Turns Passed") + { + Visible = false; + Editable = false; + Caption = 'No. of Turns Failed'; + ToolTip = 'Specifies the number of failed turns of the test line.'; + Style = Unfavorable; + + trigger OnDrillDown() + var + AITTestSuite: Record "AIT Test Suite"; + AITLogEntry: Codeunit "AIT Log Entry"; + begin + AITTestSuite.SetLoadFields("Base Version"); + AITTestSuite.Get(Rec."Test Suite Code"); + AITLogEntry.DrillDownFailedAITLogEntries(Rec."Test Suite Code", Rec."Line No.", AITTestSuite."Base Version"); + end; + } field("No. of Operations"; Rec."No. of Operations") { Visible = false; @@ -196,6 +242,7 @@ page 149034 "AIT Test Method Lines" AITTestSuite: Record "AIT Test Suite"; AITTestSuiteMgt: Codeunit "AIT Test Suite Mgt."; NoLineSelectedErr: Label 'Select a line to compare'; + TurnsText: Text; trigger OnInsertRecord(BelowxRec: Boolean): Boolean begin @@ -205,6 +252,11 @@ page 149034 "AIT Test Method Lines" if AITTestSuite.Get(Rec."Test Suite Code") then; end; + trigger OnAfterGetRecord() + begin + TurnsText := AITTestSuiteMgt.GetTurnsAsText(Rec); + end; + local procedure GetAvg(NumIterations: Integer; TotalNo: Integer): Integer begin if NumIterations = 0 then diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al index 5096fadbbe..accb13e795 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al @@ -127,6 +127,9 @@ page 149031 "AIT Test Suite" AITLogEntry.DrillDownFailedAITLogEntries(Rec.Code, 0, Rec.Version); end; } + field(Accuracy; Rec.Accuracy) + { + } field("No. of Operations"; Rec."No. of Operations") { Visible = false; @@ -257,6 +260,21 @@ page 149031 "AIT Test Suite" end; end; } + action("Download Test Summary") + { + Caption = 'Download Test Summary'; + Image = Export; + ToolTip = 'Downloads a summary of the test results.'; + + trigger OnAction() + var + AITLogEntry: Record "AIT Log Entry"; + AITTestSuiteMgt: Codeunit "AIT Test Suite Mgt."; + begin + AITLogEntry.SetRange(Version, Rec.Version); + AITTestSuiteMgt.DownloadTestSummary(AITLogEntry); + end; + } } area(Navigation) { diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al index cf97553ad6..09e657cb00 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al @@ -161,6 +161,14 @@ table 149030 "AIT Test Suite" FieldClass = FlowField; CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Code"), Version = field("Version"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); } + field(25; Accuracy; Decimal) + { + Caption = 'Accuracy'; + ToolTip = 'Specifies the average accuracy of the test suite. The accuracy is calculated as the percentage of turns that passed or can be set manually by the test.'; + Editable = false; + FieldClass = FlowField; + CalcFormula = average("AIT Log Entry"."Test Method Line Accuracy" where("Test Suite Code" = field("Code"), Version = field("Version"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''))); + } field(50; "Test Runner Id"; Integer) { Caption = 'Test Runner Id'; diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al index d25d95fdb9..ce190c04e1 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al @@ -28,6 +28,10 @@ codeunit 149034 "AIT Test Suite Mgt." CannotRunMultipleSuitesInParallelErr: Label 'There is already a test run in progress. You need to wait for it to finish or cancel it before starting a new test run.'; FeatureNameLbl: Label 'AI Test Toolkit', Locked = true; LineNoFilterLbl: Label 'Codeunit %1 "%2" (Input: %3)', Locked = true; + TurnsLbl: Label '%1/%2', Comment = '%1 - No. of turns that passed, %2 - Total no. of turns'; + EmptyLogEntriesErr: Label 'Cannot download test summary as there is no log entries within the filter.'; + DownloadResultsLbl: Label 'Download Test Summary'; + SummaryFileNameLbl: Label '%1_Test_Summary.xlsx', Locked = true; ConfirmCancelQst: Label 'This action will mark the run as Cancelled. Are you sure you want to continue?'; procedure StartAITSuite(Iterations: Integer; var AITTestSuite: Record "AIT Test Suite") @@ -355,6 +359,9 @@ codeunit 149034 "AIT Test Suite Mgt." AITLogEntry."Procedure Name" := CurrentTestMethodLine.Function; AITLogEntry."Tokens Consumed" := AITTestRunIteration.GetAITokenUsedByLastTestMethodLine(); + AITLogEntry."No. of Turns" := AITTestRunIteration.GetNumberOfTurnsForLastTestMethodLine(); + AITLogEntry."No. of Turns Passed" := AITTestRunIteration.GetNumberOfTurnsPassedForLastTestMethodLine(); + AITLogEntry."Test Method Line Accuracy" := AITTestRunIteration.GetAccuracyForLastTestMethodLine(); AITLogEntry.Insert(true); Commit(); @@ -371,6 +378,17 @@ codeunit 149034 "AIT Test Suite Mgt." TelemetryCustomDimensions.Add('TotalDurationInMs', Format(TotalDurationInMs)); end; + internal procedure GetTurnsAsText(var AITTestMethodLine: Record "AIT Test Method Line"): Text + begin + AITTestMethodLine.CalcFields("No. of Turns Passed", "No. of Turns"); + exit(StrSubstNo(TurnsLbl, AITTestMethodLine."No. of Turns Passed", AITTestMethodLine."No. of Turns")); + end; + + internal procedure GetTurnsAsText(var AITLogEntry: Record "AIT Log Entry"): Text + begin + exit(StrSubstNo(TurnsLbl, AITLogEntry."No. of Turns Passed", AITLogEntry."No. of Turns")); + end; + internal procedure GetAvgDuration(AITTestMethodLine: Record "AIT Test Method Line"): Integer begin if AITTestMethodLine."No. of Tests Executed" = 0 then @@ -440,6 +458,27 @@ codeunit 149034 "AIT Test Suite Mgt." exit(FeatureNameLbl); end; + internal procedure DownloadTestSummary(var AITLogEntries: Record "AIT Log Entry") + var + AITResults: Report "AIT Test Summary"; + ResultsTempBlob: Codeunit "Temp Blob"; + ResultsOutStream: OutStream; + ResultsInStream: InStream; + FilenameTxt: Text; + begin + if not AITLogEntries.FindFirst() then + Error(EmptyLogEntriesErr); + + ResultsTempBlob.CreateOutStream(ResultsOutStream); + + AITResults.SetTableView(AITLogEntries); + AITResults.SaveAs('', ReportFormat::Excel, ResultsOutStream); + + FilenameTxt := StrSubstNo(SummaryFileNameLbl, AITLogEntries."Test Suite Code"); + ResultsTempBlob.CreateInStream(ResultsInStream); + DownloadFromStream(ResultsInStream, DownloadResultsLbl, '', 'xlsx', FilenameTxt); + end; + [EventSubscriber(ObjectType::Table, Database::"AIT Test Suite", OnBeforeDeleteEvent, '', false, false)] local procedure DeleteLinesOnDeleteAITTestSuite(var Rec: Record "AIT Test Suite"; RunTrigger: Boolean) var