次の方法で共有


C# Power Fx テスト 関数を作成する (プレビュー)

注意

プレビュー機能は運用環境での使用を想定しておらず、機能が制限されている可能性があります。 これらの機能を公式リリースの前に使用できるようにすることで、顧客が事前にアクセスし、そこからフィードバックを得ることができます。

Microsoft Power Fx は Power Apps で使用されている強力なローコード言語で、C# を使用して拡張し、カスタム テスト関数を作成できます。 この記事では、作成者と開発者の両方にシームレスなエクスペリエンスを提供する、C# の Power Fx テスト関数の作成方法を説明します。

Power Apps Test Engine の「崖のない」拡張性モデルにより、ユーザーは障壁にぶつかることなく Power Apps Test Engine の機能を拡張できます。 このモデルでは、開発者が C# を使用してカスタム関数を作成し、それを Power Fx に統合して複雑なシナリオを処理することができます。

Test Engine モジュール

Test Engine 内の Power Fx 用の Test Engine モジュールは、拡張性モデルを使用して構築されます。 Test Engine を拡張する方法の例として、製品コードを使用できます。

キャンバス アプリケーションで条件付き同意ダイアログを処理するコードの概要を提供する Power Fx 関数の例を示します。

同意ダイアログは、ユーザーに表示されるプロンプトで、特定のリソースにアクセスしたり、特定のアクションを実行したりするためのアクセス許可を求めます。 このダイアログは、セキュリティを維持し、ユーザーが実行されるアクションを認識し、同意できるようにするために重要です。

SharePoint サイトに接続するアプリの接続同意ダイアログの例です。

同意ダイアログは、不正アクセスや不正操作の防止に役立つため重要です。 これにより、機密性の高い操作が実行される前に、ユーザーに通知し、ユーザーが明示的に同意を与えることを保証します。 これは、アプリケーションがユーザー データにアクセスしたり、アクションを実行したりする必要があるシナリオで重要であり、この条件付き動作は自動テストに影響を与える可能性があります。

同意ダイアログの課題の 1 つは、テストを非決定論的にする可能性があることです。 プロンプトは、ユーザーのアクセス許可や以前の対話など、さまざまな要因に基づいて条件付きで表示される場合があります。 この条件付きの外観は、Test Engine がこれらのダイアログを適切に処理する必要があるため、テスト プロセスを複雑にする可能性があります。

Power Fx による複雑性の抽象化

Power Fx は、同意ダイアログを条件付きで待機し、必要に応じて接続を作成するという複雑の抽象化に役立ちます。 作成者は Power Fx を使用して、同意ダイアログを処理するロジックをより分かりやすく直感的に定義することができます。

カスタム ページの同意ダイアログ処理で Power Fx を使用する例を示します:

Preview.ConsentDialog(Table({Text: "Center of Excellence Setup Wizard"}))

たとえば、ConsentDialog 関数は同意ダイアログが表示されているかどうかを確認します。 その場合、関数はテスト アカウントの同意を確認するダイアログに応答できます。 ダイアログが処理されると、残りのテスト ステップが実行されます。

Table 引数は、提供されたテキストを持つラベルが表示されている場合、同意ダイアログの待機プロセスを終了できます。

C# による Power Fx テスト関数の拡張

次の例は、この例を完了するための開始点として使用できるアウトライン コードの例です。

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.Extensions.Logging;
using Microsoft.Playwright;
using Microsoft.PowerApps.TestEngine.Config;
using Microsoft.PowerApps.TestEngine.TestInfra;
using Microsoft.PowerFx;
using Microsoft.PowerFx.Core.Utils;
using Microsoft.PowerFx.Types;

namespace testengine.module
{
    /// <summary>
    /// This will check the custom pages of a model driven app looking for a consent dialog
    /// </summary>
    public class ConsentDialogFunction : ReflectionFunction
    {
        private readonly ITestInfraFunctions _testInfraFunctions;
        private readonly ITestState _testState;
        private readonly ILogger _logger;
        private static TableType SearchType = TableType.Empty()
              .Add(new NamedFormulaType("Text", FormulaType.String, displayName: "Text"));
    
        /// <summary>
        /// Constructor: Initializes the function with necessary dependencies, 
        /// including ITestInfraFunctions, ITestState, and ILogger.
        /// </summary>
        /// <param name="testInfraFunctions">The test infrastructure functions.</param>
        /// <param name="testState">The test state.</param>
        /// <param name="logger">The logger instance.</param>
        public ConsentDialogFunction(ITestInfraFunctions testInfraFunctions, 
           ITestState testState, 
           ILogger logger) : base(DPath.Root.Append(
               new DName("Preview")), 
               "ConsentDialog", 
               FormulaType.Blank, 
               SearchType)
               {
                  _testInfraFunctions = testInfraFunctions;
                  _testState = testState;
                  _logger = logger;
               }

        /// <summary>
        /// Execute Method: Logs the execution and calls the ExecuteAsync 
        /// method to handle the consent dialog.
        /// </summary>
        /// <param name="searchFor">The table value to search for.</param>
        /// <returns>A blank value.</returns>
        public BlankValue Execute(TableValue searchFor)
        {
            _logger.LogInformation("------------------------------\n\n" +
                "Executing ConsentDialog function.");

            ExecuteAsync(searchFor).Wait();

            return FormulaValue.NewBlank();
        }

        /// <summary>
        /// ExecuteAsync Method: Retrieves the page context and handles the consent dialog with a timeout.
        /// </summary>
        /// <param name="searchFor">The table value to search for.</param>
        /// <returns>A task representing the asynchronous operation.</returns>
        private async Task ExecuteAsync(TableValue searchFor)
        {
            var page = _testInfraFunctions
               .GetContext()
               .Pages
               .Where(p => p.Url.Contains("main.aspx"))
               .First();

            // ... IPage to handle consent dialog with timeout
        }
    }
}

ConsentDialogFunction の例の説明

  • 名前空間とインポート: 必要な名前空間をインポートし、testengine.module の名前空間を定義します。
  • クラス定義: ConsentDialogFunction クラスは ReflectionFunction を継承し、カスタム関数 ConsentDialog を定義します。
  • Constructor: ITestInfraFunctionsITestStateILogger を含む必要な依存関係で関数を初期化します。
  • Execute メソッド: 実行をログに記録し、ExecuteAsync メソッドを呼び出して同意ダイアログを処理します。
  • ExecuteAsync メソッド: ページ コンテキストを取得し、同意ダイアログをタイムアウト処理します。