0

いくつかのエンド ツー エンド テストを構築したい従来の ASP.NET 4.0 WebForms アプリケーションがあります。Specflow を使用してテストを作成し、Selenium WebDriver を使用して Firefox のスクリプトを作成します。

アプリケーションは単純な ADO.NET を使用して DB (MS SQL Server 2008 R2 SP1) にアクセスしています。

テストの分離を実現したいので、1 つのテストが DB に書き込むすべてを、テストの最後に削除したいので、次のアプローチを使用します。

        [BeforeScenario]
        public void ScenarioSetup()
        {

            Scope = new TransactionScope(TransactionScopeOption.RequiresNew,
                                         new TransactionOptions {IsolationLevel =    IsolationLevel.ReadUncommitted});
            Browser.CreateNew();
        }

        [AfterScenario]
        public void ScenarioCleanup()
        {
            if (Scope != null)
            {
                Scope.Dispose();
            }
            Browser.Close();
        }

そのため、トランザクション スコープを開き、最後に破棄します。

Givenブロックで、EF5 DbContext を開き、いくつかのセットアップ データを書き込みます。

  public void GivenIHaveAccountsWithDifferentStatusesInTheSystem()
    {
        using (var ctx = new WorkflowImprovementsContext())
        {
            try
            {
                _contact = new Contact()
                {
                    created = new DateTime(2010, 1, 18),
                    countryId = 1,
                    stateId = 1,
                    contactName = "Account Contact Name One",
                    companyName = "Company Company Account One",
                    address1 = "Address 1 One",
                    address2 = "Address 2 One",
                    city = "City Account One",
                    email = "Email Account One",
                    zipCode = "A123",
                    phone = "0735352244",
                    mobile = "0735352244",
                    pager = "0735352244",
                    fax = "0735352244",
                    webSite = "www.test.com"
                };
                ctx.Contacts.Add(_contact);

                ctx.SaveChanges();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + ex.StackTrace);
            }

        }

使用後にコンテキストが破棄されることに注意してください。

ReSharper テストランナーから specflow テストを実行します。テストのWhenステップのある時点でのテストは、Firefox (別のプロセス) を起動し、AJAX 呼び出しを介して DB に入れられたばかりのデータが読み取られるページに移動するようにブラウザーをスクリプト化します。

これは私が立ち往生している場所です.TransactionScopeを破棄するまで、AJAX呼び出しは返されません(その背後にあるWebサービスのコードはDBアクセスを待機します)。

Firefox プロセス内のアプリが、テスト ランナー プロセス内から書き込まれたデータを読み取れないのはなぜですか? (TSはReadUncommittedで、他のすべてを試しましたが、まだ運がありません)

データを読み取った後に後でアサートし、TS を破棄する必要があるため、DB 内のデータがロールバックされます。

4

1 に答える 1

1

開いているトランザクション内でデータベースにデータを作成し、トランザクションがまだ開いていてコミットされていない間に、別のプロセスの別のトランザクションから同じデータを読み取ろうとしているようです。これは、トランザクション スコープのデフォルトの分離レベルでは機能しません。アプリケーションで ReadUncommitted を使用するか、アプリケーションのクエリで nolock ヒントを使用しない限り、トランザクションがコミットされるまでその情報を読み取ることはできません。

おそらく、アプリケーションがコミットされていないデータを読み取ることを許可したくないでしょう。これが、リレーショナル データベースが ACID プロパティに準拠し、トランザクションを使用する理由です。コミットされていない情報を読み取ることができれば、アプリケーションで悪いことが起こる可能性があります。それはあなたのアプリケーションにとっては問題ないかもしれません - しかし、あなたのアプリケーションがそれをしなければならないのでそれがあなたがしていることではないなら、私はテストのためだけにそれをすることはお勧めしません.

とにかく、トランザクションを使用してテストでデータを削除するという考えは好きではありませんでした.実際には意図されておらず、面倒な方法でトランザクションを使用しているようです. すべてのテストのセットアップとティアダウン、およびアプリケーション コードの実行を 1 つのトランザクションで実行する単一のプロセスの方が優れていますが、それでも私はそこに夢中ではありません。

本当に、あなたは考えすぎて、これを難しくしすぎているかもしれません。テスト中のアクションを実行する前にデータを作成し、後で削除することが必要な場合は、可能な限り単純なことを行い、前に追加して後に削除する必要があります。プロセスの境界を越えて実際にアプリケーションにヒットしている場所で、あなたがしていることはもっと嫌いです。

于 2013-07-27T18:50:23.870 に答える