单元测试 - 依赖测试

时间:2011-12-01 11:16:50

标签: c# .net visual-studio-2008 unit-testing

我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建一个记录,并检查返回值是否大于0.

然后第二个测试检查在第一个测试中创建的记录的数据。但是,它需要在第一次测试中生成的记录的ID。

最初我在第一次测试中调用了第二个测试,这样我就可以将ID作为参数传递,这很好用,除非这意味着基本上只有一个测试。

我创建了一个有序列表,其ID在范围之外声明,但在第一次单元测试之后,该值返回0,显然第二次单元测试失败。

有没有办法创建测试,以便它们共享第一次测试中产生的值?

代码如下:

[TestMethod]
public void TestNewLandlord_InsertIntoImportFiles_ReturnFileID()
{
    try
    {
        DataSet ds = EngineBllUtility.InsertIntoImportFiles(connString, @"C:\Documents and Settings\dTrunley\My Documents", "HFISNewLandlordTest.csv",
        "TestNewLandlord()", WindowsIdentity.GetCurrent().Name, "HFIS Landlords", "NA", 30247531, false);

        importFileId = long.Parse(ds.Tables[0].Rows[0]["ImportFileID"].ToString());
        Assert.IsTrue(importFileId > 0);
    }
    catch (Exception ex)
    {
        Assert.Fail(ex.Message);
    }
}

[TestMethod]
public void TestNewLandlord_InsertIntoImportFiles_CorrectData()
{
    try
    {
        using (SqlConnection connectionString = new SqlConnection(connString))
        {
            using (SqlCommand sqlCommand = new SqlCommand(
                String.Format("SELECT * FROM [mydeposits].[import].[ImportFiles] WHERE [ImportFileID] = {0}", importFileId), connectionString))
            {
                connectionString.Open();
                using (SqlDataReader dr = sqlCommand.ExecuteReader())
                {
                    if (dr.HasRows)
                    {
                        bool correctData = true;
                        dr.Read();
                        if (!dr["ImportFileStatusID"].ToString().Equals("1"))
                            correctData = false;
                        if (!dr["HeadOfficeMemberID"].ToString().Equals("247531"))
                            correctData = false;
                        Assert.IsTrue(correctData);
                        TestCleanup();
                    }
                    else
                        throw new Exception("Import does not exist in database");
                }
            }
        }
    }
    catch (Exception ex)
    {
        Assert.Fail(ex.Message);
        TestCleanup();
    }
}

2 个答案:

答案 0 :(得分:5)

  

我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建一个记录,并检查返回值是否大于0.

在我看来,这种做法是不正确的。你可能会制造出会让你反感的邪恶代码。这样的代码:

  • 打破了单元测试原则
  • 很难维护
  • 非常僵硬,笨重且容易出错

单元测试必须独立,否则根本不要写它们。原因在于软件的复杂性增加 - 测试的复杂性也随之增加。如果你有一个测试取决于其他人维护测试成为负担。因此,软件的成本增加,但代码的质量却没有。如果您在测试之间没有依赖关系 - 软件的复杂性并不重要,因为您可以单独测试每个单独的功能。

另一个优点是您可以并行运行测试。对于大型系统,持续集成(和部署)周期很快很重要。通过并行运行测试,您可以显着加快发布周期。

建议的解决方案

您要完成的任务可能是集成测试。编写它们的一种方法是为这些测试创建一个单独的项目。每个测试仍然是彼此独立的,但是在NUnit测试术语中,每个测试可能需要一些SetUpTearDown。因此,SetUp将准备集成测试所需的所有内容,TearDown将在每次测试后执行清理。

答案 1 :(得分:3)

这非常顽皮,但你可以不发表评论(如果由测试向导创建或添加)

//You can use the following additional attributes as you write your tests:

//Use ClassInitialize to run code before running the first test in the class
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
}

//Use ClassCleanup to run code after all tests in a class have run
[ClassCleanup()]
public static void MyClassCleanup()
{
}

//Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
}

//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
}

模仿一些常见的测试数据并没有什么不同,尽管同样可疑。