0

fiddlercore を使用してセッション情報をキャプチャし、特定の応答のデータを比較しています。私が理解していないことに気付いていることの 1 つは、2 番目の環境から最初の List コレクションにセッション情報を取得していることです。

public class ManageCompares
{
    public static string _test2BaseURL = "https://test2/";
    public static string _dev1BaseURL = "http://dev1/";


    private void RunCompares(string email, string handler, Reporting report)
    {
        ManageProcess.ShutDownProcess("iexplore");

        RunExports exportTest2 = new RunExports();
        RunExports exportDev1 = new RunExports();

        string password = "d";

        List<Session> oAllSessions_Test2 = exportTest2.RunExportGeneration
          (email, password, _test2BaseURL, handler);

        ManageProcess.ShutDownProcess("iexplore");

        List<Session> oAllSessions_Dev1 = exportDev1.RunExportGeneration
            (email, password, _dev1BaseURL, handler);

        exportTest2.ExtractResponse(oAllSessions_Test2, handler, report);

        //report.SetEnvironment2Body(ManageExports.ExtractResponse
        //  (oAllSessions_Dev1, handler, report, report.Environment2));

        if (report.Test2ResponseCode != 500 && report.Dev1ResponseCode != 500)
        {
            bool matches = CompareExports.CompareExportResults
              (report.Environment1Body, report.Environment2Body);

            if (matches)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Exports matched");
                Console.ResetColor();
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Export does not match");
                Console.ResetColor();

                report.GenerateReportFiles();
            }
        }
        else
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine
              ("A exception was returned.  Please review the log file.");
            Console.ResetColor();


        }
    }


}

public class RunExports
{
    public List<Session> RunExportGeneration
     (string email, string password, string baseUrl, 
          string handlersUrlwithParams)
    {
        IWebDriver driver = new InternetExplorerDriver();

        FiddlerApplication.Startup(8877, FiddlerCoreStartupFlags.Default);

        List<Session> oAllSessions = new List<Session>();

        LoginPage login = new LoginPage(driver);

        FiddlerApplication.AfterSessionComplete += delegate(Session oS)
        {
            Monitor.Enter(oAllSessions);
            oAllSessions.Add(oS);
            Monitor.Exit(oAllSessions);
        };

        try
        {
            driver.Navigate().GoToUrl(baseUrl);
            login.LoginToView(email, password);
            driver.Navigate().GoToUrl(baseUrl + handlersUrlwithParams);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            FiddlerApplication.Shutdown();                
            driver.Quit();
        }

        return oAllSessions;
    }
}

List oAllSessions_Test2 と List oAllSessions_Dev1 は、私の 2 つのコレクションです。キャプチャをデバッグすると、通常、oAllSessions_Test2 コレクションに 15 行が表示されます。次に、oAllSessions_Dev1 をキャプチャした後、カウントが 14 または 15 に跳ね上がっていることがわかります。コレクションに含まれるものを見ると、Dev1 キャプチャの一部がそこにあります。oAllSessions_Dev1 には、私が期待しているセッションだけがあります。予期していない場所にポインターがあるに違いないと推測していますが、この時点でそれをクリアする方法に困惑しています。私が気付いているもう 1 つのことは、アプリケーションがさまざまなケースを循環している間、セッション カウンターが増加し続けることです。

また、Selenium WebDriver と IE を使用してブラウザー セッションを開始していますが、この特定の問題に特に関連しているとは思いません。

それで、私はここで何が欠けていますか?

4

2 に答える 2

1

これを行う :

SessionStateHandler tAction = oS =>
        {
            Monitor.Enter(oAllSessions);
            oAllSessions.Add(oS);
            Monitor.Exit(oAllSessions);
        };

FiddlerApplication.AfterSessionComplete += tAction;

......

// 最後に return ステートメントの前に:

 FiddlerApplication.AfterSessionComplete -= tAction;

これが何が起こっているかです。

これ: FiddlerApplication.Startup(8877, FiddlerCoreStartupFlags.Default);

(これは具体的に)FiddlerApplication

外部アプリケーション(フィドラー)で参照を保持し、それらを管理しています。+= して delegate を追加するFiddlerApplication.AfterSessionComplete += tAction;と、フィドラー アプリケーションは AfterSession イベントが発生したときに呼び出すメソッドのリストにこれを追加していました。

これはシングルトンであるため (コード内で 1 つの Fiddler アプリケーション インスタンスのみを扱っている)、+= を実行するたびに同じリストに追加されます。FiddlerApplication のこのリストは、メソッドを呼び出すたびに再作成されるわけではありません。最初に呼び出したものと同じなので、デリゲートがそのスコープ宣言スペースから外れても (ローカル オブジェクトが通常メソッドで行うように)、FiddlerApplication EventList はそれへの参照を保持し、そのデリゲートを毎回起動します (そして他のすべて)。

そう.....

メソッドList<Session> oAllSessions = new List<Session>();では、デリゲートで作成してアクセスします。このローカル変数は呼び出し元のメソッドに戻されList<Session> oAllSessions_Test2 = exportTest2.RunExportGeneration....、デリゲート FiddlerApplication 呼び出しはまったく同じリストになります。したがって、そのメソッドを呼び出して AfterSessionComplete が起動するたびに、呼び出し元の関数に返された後でもリストが更新されます。

それを停止するには、次を追加する必要があります。FiddlerApplication.AfterSessionComplete -= tAction;これは、システムに「ねえ、もうこのメソッドに更新をプッシュしないでください。通知の受信が完了しました。」と伝えます。

于 2013-06-11T20:24:00.543 に答える
0

.NET 言語では、ほとんどの場合、クラス オブジェクトは参照によって渡されます。オブジェクト参照を変数に割り当てた場合、その変数は引き続き元のオブジェクトを参照します。オリジナルへの変更は、すべての参照を通じて表示されます。これは、構造体へのポインタまたは参照をメモリに格納するときに C/C++ で発生していた方法に似ています。実装の詳細は異なりますが、結果は同じです。

後で変更される可能性のあるリスト インスタンスを保存するとどうなるかの例を次に示します。

class ListTest
{
    List<string> l = new List<string>();
    public List<string> GetList() { return l; }
    public void Add(string v) { l.Add(v); }
}

class Program
{
    static void Main(string[] args)
    {
        ListTest t = new ListTest();
        t.Add("a"); t.Add("b"); t.Add("c"); t.Add("d");
        List<string> x1 = t.GetList();
        List<string> x2 = t.GetList().ToList();
        t.Add("e"); t.Add("f"); t.Add("g"); t.Add("h");
        List<string> y1 = t.GetList();
        List<string> y2 = t.GetList().ToList();

        Console.WriteLine("{0}, {1}", x1.Count, y1.Count);
        Console.WriteLine("{0}", string.Join(", ", x1));
        Console.WriteLine("{0}", string.Join(", ", y1));

        Console.WriteLine();

        Console.WriteLine("{0}, {1}", x2.Count, y2.Count);
        Console.WriteLine("{0}", string.Join(", ", x2));
        Console.WriteLine("{0}", string.Join(", ", y2));
    }
}

これを実行すると、とが同じオブジェクトへの参照であるためx1、同一の結果が 1 セット得られます。y12 番目の結果セットは、 の呼び出しによって結果を保持ToListする新しいList<string>インスタンスが作成されるため、異なります。

これは、Fiddler コードによって返されるリストで発生している可能性があります。

-- コードレビュー後に更新

イベントに割り当てているデリゲートAfterSessionCompleteにより、コードoAllSessionsはイベント ハンドラー デリゲートにバインドされた静的オブジェクトとして処理されます。クロージャーなどを生成するコードをいじり始めると、このようなさまざまな副作用が発生します。

インライン メソッドではなくクラス メソッドを使用するようにコードを変更することをお勧めします。oAllSessions変数と割り当てるコードをAfterSessionCompleteクラスの本体にシフトします。これにより、インライン デリゲートが問題の原因であるかどうかが少なくとも確立されます。

于 2013-06-11T04:47:31.400 に答える