单元测试-依赖于测试
本文关键字:测试 依赖于 单元测试 | 更新日期: 2023-09-27 18:16:33
我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建了一条记录,并检查返回值是否大于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();
}
}
在我看来,这种方法是不正确的。你可能会创建一些邪恶的代码,这些代码会反过来咬你一口。这样的代码:我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建了一条记录,并检查返回值是否大于0。
- 破坏了单元测试原则
- 难以维护
- 非常死板、繁琐且容易出错
单元测试必须是独立于的,否则根本就不要写它们。这样做的原因是,随着软件复杂性的增长,测试的复杂性也在增加。如果您有一个测试依赖于其他测试,那么维护这些测试就变成了负担。所以软件的成本增加了,但代码的质量却没有。如果测试之间没有依赖关系,那么软件的复杂性就无关紧要了,因为您可以单独测试每个单独的功能。
另一个优点是您可以并行地运行测试。对于大型系统,重要的是持续集成(和部署)周期要快。通过并行运行测试,可以显著加快发布周期。
建议解决方案
您想要完成的可能是集成测试。编写它们的一种方法是为这样的测试创建一个单独的项目。每个测试仍然是相互独立的,但可能每个测试都需要一些NUnit测试术语中的SetUp
和TearDown
。因此,安装程序将准备集成测试通过所需的一切,而TearDown将在每次测试后执行清理。
这是非常顽皮的,但是您可以取消注释(如果由测试向导创建或添加)
//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()
{
}
与模拟一些常见的测试数据没有什么不同,尽管同样可疑。