FreeTestPanel=テスト画面自動作成ツール

作りたてのプログラムを直ぐに動かすには?

皆さんは何かプログラムを書いて取りあえず動かしてみたいときどのようにしていますか?
仮にそれが複数の引数をもち、内部で何らかの処理をして結果を戻り値として返す関数プログラムだとします。この場合大抵の人は次のいずれかの方法を採用すると思います。

  • コンソールアプリケーションを作成してその関数プログラムをコールさせ、コンソールから入力した引数を引き渡するようにする。
  • 単体テストフレームワークを利用して対象プログラムに様々な引数の組み合わせパターンを渡すテストプログラムを書く。
Testing before launch

前者の方法だとそのコンソールアプリケーションが複数のテストプログラムを取り扱うようになった場合、ロジックが複雑になります。後者の方法だと基本的にテスト対象プログラムには単体テストプログラムに記述した引数のテストパターンしか渡せません。任意の引数を与えて実行するとしたらテスト実行中のプログラムを適当なブレークポイントで止めて、IDEのイミディエイトウィンドウからコールするといった面倒な作業が必要になります。


少しプログラムに慣れた人ならWindowsかWebのアプリケーションを作成し、複数のテスト対象プログラムを実行できて、なおかつ画面から引数を自由に入力できるテストアプリケーションを作成するでしょう。こうすればかなりテストプログラムの自由度は上がります。

male and female programmer

しかしこれでは少し不便ではないでしょうか?テスト対象となるプログラムが増えるごとに、実行するテストプログラムを選択して、それぞれのメソッドの引数に合わせた入力エリアの設定と入力値の引数値への型変換、及び実行結果の表示といった処理を追加しなければなりません。これをいちいちコーディングしていたら大変な工数になってしまいます。

FreeTestPanelがこの問題を解決します

FreeTestPanelはこの問題を解消するために作成したテストプログラム実行用画面の自動作成ツールです。

FreeTestPanelの実行画面
FreeTestPanelにより自動生成されたテストプログラムの実行画面

テストプログラムのクラスやメソッドの定義に所定の属性を書き加えることで、自動的にWebアプリケーションによるテスト画面を作成してくれます。作成された画面からテストクラスやテストメソッドを選択すると、引数の入力エリアは自動的に変更され自由に値を設定できるようになります。引数に設定する値の組み合わせも予め登録されたパターンから選択させることも可能です。

以下に実行画面を自動生成するテストプログラムのコーディング例を示します。ハイライトされている[FreeTestClass]、[FreeTestMethod]、[FreeTestPattern]という属性で修飾されたクラスやメソッドが自動生成されたテスト画面上に表示されているテスト対象クラス、テスト対象メソッド、そしてテストパターンになります。

using EmotionSoft.ewd2.SimpleUT;

namespace SocialLoginWebAPITest.App_Code
{
    [FreeTestClass("tc02.SQLサーバーへのSQL実行コマンドのテスト")]
    public class tc02_SQL_ExecTest : WebFreeTestFixture
    {
        protected String TargetContractOrgCD { get; set; }
        protected String TargetContractOrgName { get; set; }

        [FreeTestMethod("t91.テスト会員情報+付属情報の表示(提携先会員IDで検索)",
@"引数personaIDPartには検索する16桁会員番号の契約組織コードを除く検索文字を入力してください。
ここに値が設定されると検索条件は
WHERE PersonalID LIKE '[契約組織コード]%[入力された検索値]%'
にセットされます。
personalIDPartとdaysDiffの何れか一方が入力される必要があります。")]
        public void t91_ShowDmySiteMembershipByIdPrefix(String contractOrgCD, String partnerMemberIdPrefix)
        {
            String connStr = MyTestContext.GetConnectString();
            SqlDataSourceParameterList srcParamList = new SqlDataSourceParameterList();

            String whereClause = SetWhereClauseByPartnerMemberIDPrefix("PersonalID",
                contractOrgCD, partnerMemberIdPrefix, ref srcParamList);

            SqlDbController myDAC = new SqlDbController(connStr);

            //結果確認
            String strSQL =
@"SELECT 
    '0x' + LIFE_ContractOrgCD AS 組織コード,
    SUBSTRING(PersonalID, 2, 14) as 会員ID,
	ConfirmationGUID AS 確認用ワンタイムID,
	PartnerMemberID AS 提携先会員ID,
    EMailAddress AS  メルアド, 
    ProvisionalEMailAddress AS 保留メルアド, 
    EMailAddressConfirmLimit メルアド確認期限
FROM Mst_DmySite_Membership";
            strSQL += Environment.NewLine + whereClause;
            this.ShowResultData(connStr, strSQL, srcParamList, "Mst_DmySite_Membership");
            strSQL =
@"SELECT 
    Update_Time, Update_User, Update_PGM, Muko_Flg
    ,LIFE_ContractOrgCD, PersonalID
    , ItemName, ItemValue
FROM Mst_DmySite_MemberExtraInfo";
            strSQL += Environment.NewLine + whereClause;
            this.ShowResultData(connStr, strSQL, srcParamList, "Mst_DmySite_MemberExtraInfo");
        }  

        [FreeTestPattern("t91_ShowDmySiteMembershipByIdPrefix;" +
            "t92_ShowTestUserAllInfoByIdPrefix;t93_ShowDmySiteMembershipByIdPrefixDetails;t98_DeleteMemberRecordPersonalID16",
            true, true)]
        public virtual List<String[]> ShowDmySiteMemberMastersTestPattern
        {
            get
            {
                var result = new List<String[]>();
                result.Add(new String[] { TargetContractOrgCD, "Prefix001",
                    TargetContractOrgName + "の提携先会員番号の先頭=Prefix001であるレコードを選択",
                    TargetContractOrgName + "/ Prefix001"});
                result.Add(new String[] { TargetContractOrgCD, "PREFIX-002",
                    TargetContractOrgName + "の提携先会員番号の先頭=PREFIX-002であるレコードを選択",
                    TargetContractOrgName + "/ PREFIX-002"});
                result.Add(new String[] { TargetContractOrgCD, "PREFIX-003",
                    TargetContractOrgName + "の提携先会員番号の先頭=PREFIX-003であるレコードを選択",
                    TargetContractOrgName + "/ PREFIX-003"});
                return result;
            }
        }      

開発のツボを心得た便利な機能

FreeTestPanelの機能はこれだけに留まりません。業務系アプリケーションやWebアプリケーションで必ず必要になるDBや外部ファイルの照会機能を持っています。テスト対象となるプログラムが実行された結果、DBの内容がどのように書き換えられたか?あるいは出力されるXMLやJsonファイルの内容がどのように変化したかを簡単に検証することが出来るようになります。

FreeTestPanelによるデータの検索と結果出力
データベースを検索して結果をリスト形式で表示しているところです。

また自動生成される画面はWebアプリケーショであるため、テスト対象プログラムがHttpContextを使用する場合にはMockではなくWebアプリケーションが使用する本物のHttpContextを使用することができます。Mockを作成する手間が省けるだけでなく、SessionやCacheの状態をテストに先駆けて変更したり、テスト実行後の状態変化を照会することが出来ます。これはデバッグの生産性を格段に高めます。

運用部門での利用

元々は単体テスト用のツールとして作成したものですが、その用途は単体テストに留まりません。引数の入力エリアを自動的に生成すること、引数の組み合わせをパターン化して選択可能にすることで、システム運用部門における作業補助用ツールとしても大いに活躍できる可能性があります。

FreeTestPanelによるデータの検索と結果出力(詳細表示)
データベースを検索して結果を詳細表形式で表示しているところです。

例えばDevOpsの現場での運用業務では、DB保守等の定型化された作業をテストメソッドとして登録しておき、FreeTestPanelを使用したWebアプリケーションから選択して実行させることが出来ます。認証情報のユーザー権限と選択可能なテストクラスやテストメソッドの紐づけを行えば、更に運用のためのアプリケーションに近いものが完成します。

リリーススケジュール

2021年初夏を予定

※)現在は.NET FrameworkのWebForm用に作成していますが、近々.NET 5.0版を作成しMVCやRazorPageアプリケーション上でも動作する製品を公開する予定です。