本内容を利用した場合の一切の責任を私は負いません。
機能
ソースの中の分岐を通過したことがわかるように、ソースにトレース出力するソースを自動的に追加するものです。
PowerShellスクリプトで行っています。
ソースを変更するため、git等のソース管理システム下等、ソースを復元できる環境下での使用を推奨します。
追加されたソースを実行すると、通過情報がファイル(以降、通過ファイル)に出力されます。
(オプションにより、継続して記録するファイル(以降、報告ファイル)を出力させることもできます。)
出力によりフローを追えるため、デバッグにも利用できます。
通過情報は、1実行内で1度しか出力されません。
(ループ内のトレース出力は1度のみ。)
報告ファイルがある場合は、報告ファイル内の通過情報がリセット(「ー」)されてないと1実行に限らず継続して出力されません。
Java、C++は対応言語と仕様が似ているため、既存言語処理を流用・変更して対応させることもできると思います。
また、Javascriptのnode.js環境外は、トレース出力先に困っただけなので、ブラウザの専用ウィンドウのtextareaタグとかWebストレージに出力するようにすれば対応できると思います。
対応言語
- PowerShell
- C#
- Javascript(node.js環境)
ソース追加ルール
-
開始波カッコの後にトレースを追加
-
データ定義は不追加
オブジェクト、プロパティ、初期化子等。 -
例外ルールを作り、該当は不追加
-
分岐しない場所の開始波カッコは不追加
using、switch直後、try等。
ただし、関数は厳密には分岐ではないが効果が高いため追加。 -
[PowerShell]インスタンス関連ソース(以降、オブジェクトコード)はソースの先頭
Param文有無の処理が複雑になるため。
Param文が有る場合、PowerShell仕様でこのままではエラーになる。
(仕様はParam文は先頭でなければならないっぽい。)
Param文の後に移動したりする必要がある。 -
[C#]オブジェクトコードはnamespaceスコープの始め
using、namespace文の処理が複雑になるため。
Visual Studio(以降、VS)のWindowsフォームアプリケーションの場合、VS仕様でこのままではデザイナが使えなくなる。
(仕様はnamespace内の最初のクラス定義がフォームでなければならないっぽい。)
オブジェクトコードを追加した場合、オブジェクトコードをnamespaceスコープ内の終わりに移動したりする必要がある。 -
[Javascript]オブジェクトコードはソースの先頭
コーディングルール
ソース追加ルールを踏まえて下記になります。
私の場合、ツールが対応できるようにコーディングします。
それが厳しい場合にそれぞれのルールを変更して対応しています。
- 開始波カッコ("{")は行頭(空白での字下げはOK)
このため、制御文の最後に開始波カッコがある場合は対応していません。
バージョン
-
OS
OS 名: Microsoft Windows 10 Home
OS バージョン: 10.0.19041 N/A ビルド 19041
システムの種類: x64-based PC -
PowerShell: 7.0.6
大したことはしてないので以降でも使えると思います。
私の場合は下記からZIP版をダウンロードして展開し、パスを通した環境です。
https://docs.microsoft.com/ja-jp/powershell/scripting/how-to-use-docs?view=powershell-7 -
node.js: node-v10.16.0-win-x64(テスト対象がJavascriptの場合)
大したことはしてないので以降でも使えると思います。
私の場合は下記からZIP版をダウンロードして展開し、パスを通した環境です。
https://nodejs.org/ja/
csv: 5.5.0 -
.NET Framework: 4.6.1(テスト対象がC#の場合)
大したことはしてないので以降はもちろん、多少古くても使えると思います。
同様に、.NET Coreでも使えると思います。 -
VS: Community 2015(GUIを使ったり、テスト対象がC#の場合)
大したことはしてないので以降はもちろん、多少古くても使えると思います。
準備
-
下記のリポジトリをダウンロード
https://github.com/github895439/C1Tester -
ダウンロードしたものを展開
リポジトリの内容
-
C1TesterCoreフォルダ
実際の処理を行うスクリプトとスクリプトが使うデータです。 -
C1Testerフォルダ
単一ファイルではなく、VSソリューション等のソース群で、一括して処理したい時のGUIです。
使い方は、大したことはしてないので、表示やソースを見るとわかると思います。
大まかには、フォルダ選択するとツールがサポートする拡張子のファイルを抽出して一覧に表示します。
チェックボックスでトレース追加等を指定します。
設定内容を保存することができます。 -
exampleフォルダ
PowerShell、Javascript、C#の例があります。
PowerShellとJavascriptはlog.txtが作業ログです。
C#は下記の動画です。
https://www.twitch.tv/videos/1081344873
使い方
単一
- C1TesterCoreフォルダ下のc1tester_add_trace.ps1スクリプトを実行
引き数にソースファイルを指定します。
スクリプトは後記のスクリプトオプションを使用できます。
pwsh c1tester_add_trace.ps1 -report ..\..\example\PowerShell\example.ps1
- ソースファイル実行(markdownのバグで「2」です。)
下記の2ファイルが作成・更新されます。
・c1tester_<ソースファイル名>pass.csv(通過ファイル)
通過情報が出力されています。
・c1tester<ソースファイル名>_report.csv(報告ファイル)
-reportオプションを付けている場合はファイルが作成されていて、実行により内容が更新されます。
一括
- C1Tester.slnソリューションをVSでビルド
- ビルドしたものを実行
- PowerShellの場所を指定
- 「フォルダ選択」ボタン押下
一括処理するフォルダを指定します。 - テスト対象をチェックボックスで指定
- 「トレース追加実行」ボタン押下
- 調整
「報告ファイルを作成」を指定していて、テスト対象が要ビルドである場合、ソースファイルの場所と実行フォルダが違うため、予め報告ファイルを実行フォルダに移動して下さい。 - テスト対象を実行
VSソリューションの場合等、ソースファイルと実行フォルダが違う場合は、上記「単一」の通過ファイルは実行フォルダに作成されます。
上記「単一」と同様に、報告ファイルが有る場合、内容が更新されます。
ソースがCSharp(markdownのバグかイゲタをエスケープしても表示できない)
大まかには上記の「ソース追加ルール」のC#の内容。
インスタンスを作成するソースは対象ソースに依存するため、トレース追加後に手動でコーディングします。
大まかには、
- クラスにm_C1Testerメンバを追加
- m_C1Testerメンバのインスタンスを作成するソースを追加
報告ファイルを使う場合、テスト対象の場所に報告ファイルが作成されるため、実行ファイルの位置に移動します。
ソースがPowerShell
大まかには上記の「ソース追加ルール」のPowerShellの内容。
スクリプトのオプション
>pwsh -c Get-help .\c1tester_add_trace.ps1
c1tester_add_trace.ps1 [-force_write_backup] [-silent] [-add_object_code] [-print_supporting_extension] [-no_remain_backup] [-report]
>
-
-force_write_backup
デフォルトはバックファイルを作成し、バックアップファイルが有る場合は処理を中止します。
このオプションは続行してバックアップファイルを上書きします。 -
-silent
エラーメッセージを抑止します。
エラー内容は終了コードで判別可能です。 -
-add_object_code
オブジェクトコードを追加します。
ツールは独自のクラスとそのインスタンスを使用します。
C#のソリューションの場合、同一名前空間内に複数のソースファイルが有り、一律追加すると重複エラーになるため、選択するためのオプションです。 -
-print_supporting_extension
対応言語の拡張子を表示します。
(GUIが使用しています。) -
-no_remain_backup
複数ファイルを処理するとバックアップファイルが煩わしくなるため、このオプションで残さないようにできます。 -
-report
報告ファイルを出力するためのオプションです。
報告ファイルはツール実行時に初期値を作成するため、テスト対象の位置に作成されます。
補足
Javascriptのnode.js環境外は、トレース出力先に困っただけなので、ブラウザの専用ウィンドウのtextareaタグやWebストレージに出力するようにすれば、これも簡単に対応できると思います。
C#の場合、マルチスレッドの場合があり、機能としてではなくファイル出力にだけ排他をかけているため、出力順が崩れることがあります。
Visual Studio Code(以降、VSC)はリアルタイムでファイルを監視しているようなので、VSCで報告ファイルを開いて表示した状態でテスト対象のWindowsフォームアプリケーションを実行すると、操作する度に通過情報が記録されるのが視認できたりします。
コーディングルールで惜しいのは初期化子で、字下げに対応したいとこだけど、簡単に対応できる方法がみつからず。
開始波カッコを基準にしているので三項演算子には対応していません。
デバッグ目的で使用する場合、-reportオプションを付けずにトレース追加し、下記をfalseにすればトレースソースを残したままトレース処理をしないようにできます。
- m_EnabledTrace
- enabledTrace
- h_enabled_trace
私の例外処理のポリシーは、基本的な使い方で起こる例外以外は処理しません。
主な理由は下記です。
- 例外が表示されれば何が起きたか大まかに表示される
- ものによっては大量にある例外1つ1つの処理を行うことは、費用対効果に見合わない
- ユーザのあらゆる使い方を洗い出すことに工数がかかる上に、洗い出しきれるとは限らない
ただ、基本的な使い方以外に例外処理をする場合もあり、例えば下記です。
- サブスレッドだったりで、例外が起きても何も表示されなかったり、何が起きたかわからない
- 準正常だったりで、例外でしか異常を捕捉できない
- 処理を続行しなければならない(使い勝手ではなく、例えばトランザクション)場合、リソース解放等の異常時処理が必要である
主な履歴
2021/12/27(790c3c3) バグ修正、機能追加、機能変更
[バグ修正]
Javascriptを対象にした場合にトレース情報の出力内容が不正となるバグの修正
(関数名、行番号が表示されない等。)
[機能追加]
Javascriptの対象を非node.jsでも利用可
(詳細はexampleの動画を参照のこと。
トレース情報はtextareaタグを追加すると、そこに出力される。
ファイルではないため、報告ファイルのバックアップ機能は無し。)
[機能変更]
トレース情報のフォーマット
(カンマ区切りの1区にファイル名、行番号、関数名、タイムスタンプが入っていたが、個々となるように分離した。)
2021/10/20 Vectorでバイナリを公開
https://www.vector.co.jp/soft/winnt/prog/se523600.html
2021/08/01 csとjsは大小文字区別に修正、「Enum.」が無視扱いになることの修正