15

.mdf次のように、単体テストで使用する localdb 接続文字列と共にファイルを構成しました。

<connectionStrings>
        <add name="TestData" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0; AttachDBFilename='|DataDirectory|\TestData.mdf'; Integrated Security=True"/>
</connectionStrings>

テスト用の展開ファイルを正しく構成すると、これはうまく機能します。.mdf のコピーが LocalDB の既定のインスタンスにアタッチされ、SqlClient構成の断片なしでそれに接続されます。それだけで機能します。

でも後片付けはどうするの?私のローカル ボックスでは、定期的に SSMS を使用して古いテスト データベースを手動でデタッチできますが、CI サーバーでは、単体テスト自体をクリーンアップする方が明らかに望ましいでしょう。

localdbデータベースをインスタンスから切り離す同様の自動魔法の方法はありますか?

4

5 に答える 5

4

これは、localDB データベースを削除する方法です。私が気に入らないのは、.mdf も削除されることです。最初にそれを tem ディレクトリにコピーし、そのコピーを使用してデータベースを作成することで、これを克服しました。

var sc = new Microsoft.SqlServer.Management.Common.ServerConnection(your localDB SqlConnection here);
var server = new Microsoft.SqlServer.Management.Smo.Server(sc);
server.KillDatabase(dbName here);

これがフィルに役立つことを願っています

于 2012-09-12T19:32:32.070 に答える
1

使用しているユニット テスト フレームワークでは、クリーンアップ メソッド (つまり、MS Test のAssemblyAttribute、NUnit 3 のOneTimeTearDown、XUnitの共有コンテキスト) をアタッチできますか? その場合、以下のようなものを配線して、テストの最後にデータベースを自動的に切り離すことができます。

public static void CleanUp()
{
    using (var connection = new SqlConnection(ConnectionString))
    {
        connection.Open();

        using (var command = connection.CreateCommand())
        {
            var sql = "DECLARE @dbName NVARCHAR(260) = QUOTENAME(DB_NAME());\n" +
                "EXEC('exec sp_detach_db ' + @dbName + ';');";
            command.CommandText = sql;
            command.ExecuteNonQuery();
         }
    }
}
于 2016-10-26T17:40:00.683 に答える
1

はい。ただし、必要ない場合があります。

私は現在、wbx911/Tim Post の回答にある方法でデータベースにアタッチするプロセスを使用しています。ただし、元のデータベースのコピー (たとえば、プロジェクト/ソリューション ビルドによって作成されたコピー) をアタッチする場合は、それらをデタッチする必要はありません。データベースに接続が接続されていない場合、次のテスト実行でオーバーライドされます。

データベースのコピーが多数アタッチされている場合、またはアタッチされているすべてをクリーンアップしたくない場合は、localDb インスタンスのマスター データベースにアタッチされた次のようなストアド プロシージャを使用できます (例:私は個人的に使用します):

CREATE PROCEDURE [dbo].[DettachTestDatabases]
AS

BEGIN
DECLARE  @imax INT, 
         @i    INT 
DECLARE  @Name VARCHAR(255)

DECLARE  @DbsToDrop TABLE(RowID INT IDENTITY ( 1 , 1 ), 
                          name VARCHAR(255)
                         ) 

INSERT @DbsToDrop
SELECT [name]
  FROM [master].[sys].[databases]
  WHERE 
    --Remove all local dbs with *SomeText*.mdf or SomeOtherTextin name
    (name like '%SomeText%.mdf' or name like '%SomeOtherText%')
    -- Exclude VS test dbs (add more as required...)
    and (name not like '%TESTS.%');

SET @imax = @@ROWCOUNT 
SET @i = 1 

WHILE (@i <= @imax) 
  BEGIN 
        SELECT @Name = name 
        FROM   @DbsToDrop 
        WHERE  RowID = @i

        EXEC master.dbo.sp_detach_db @dbname = @Name;

        PRINT 'Dettatched ' + @Name;

        SET @i = @i + 1;
  END   --while

END --sp
GO

命名規則を使用して、削除するデータベースを決定しています (したがって、like ステートメント)。Visual Studioは、デタッチしたくないテスト結果を管理するために、いくつかのデータベース(または少なくともVSに属していると思います)をアタッチします(したがって、「好きではない」条件)。名前でデタッチする master.dbo.sp_detach_db があるため、実際には名前を参照するだけで済みますが、localdb の名前はワイルドな場合があるため、ルックアップが役立ちます。

必要性を感じていないため (上書きが正常に機能しているため)、テストの最後にこれをまだ自動化していませんが、必要なときにいつでも SSMS で実行できます。ただし、必要がある場合は、クリーンアップ コードから SP への呼び出しを管理するだけで済みます。

データベースのアタッチは、やや高価なプロセスです。データベースを再接続する代わりに、変数データを削除してテーブルを再シードしてデータベースを一貫した状態にするクリーンアップ方法/ SPを選択しました。これは非常に高速です。

改善点があればぜひ教えていただきたいです!

于 2013-11-14T15:23:56.173 に答える
0

xUnit のような単体テストについて話している場合は、テスト自体に追加して、データベースに触れるすべてのものをロールバックできる属性があります。

実際には、エンタープライズ レベルのトランザクションでテストを実行します。これにより、テストごとにデータが安定したままになり、データベースをモックする必要がなくなります。それは事実上受け入れテストになる可能性があります。

例 (xUnit):

[Fact]
[AutoRollback]
public void Should_Insert_Valid_Data()
{
    // Arrange: presume there's an object, sut, that supports insert,
    // and you have some data

    // Act:
    int key = sut.Insert(data);

    // Assert:
    Assert.True(key > 0, "Expected a primary key to be returned");
    var inserted = sut.Get(key);
    Assert.Equal<DataClassName>(data, inserted, CompareAllButKey);
}

(fyi: "sut" は "situation under test" または "subject under test" です)

「テストでデータベースを分離するための戦略」に関するこの記事を参照すると役立つ場合があります。その記事の最後に、他にもいくつかの素敵なリンクがあります。

ところで、サンプルとして xUnit を使用しましたが、他のテスト フレームワークには、ロールバックを制御するための同様の属性があります。

于 2013-09-21T07:36:48.353 に答える
-3

このような :

 // ProjectPath/bin/Debug/dbfile.mdf

 [TestInitialize]
 public void SetUp()
 {           
    AppDomain.CurrentDomain.SetData(
      "DataDirectory", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""));
  }
于 2013-02-04T05:36:51.040 に答える