C# 单元测试-相关测试
我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建一条记录,并检查返回值是否大于0 然后,第二个测试检查在第一个测试中创建的记录的数据。但是,它需要在第一次测试中生成的记录的ID 最初,我在第一个测试中调用了第二个测试,这样我就可以通过ID作为参数,它工作得很好,只是这意味着基本上只有一个测试 我创建了一个有序列表,其ID声明在范围之外,但在第一次单元测试之后,该值返回到0,因此显然第二次单元测试失败 有没有办法创建测试,以便它们共享第一次测试中产生的值 代码如下:C# 单元测试-相关测试,c#,.net,visual-studio-2008,unit-testing,C#,.net,Visual Studio 2008,Unit Testing,我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建一条记录,并检查返回值是否大于0 然后,第二个测试检查在第一个测试中创建的记录的数据。但是,它需要在第一次测试中生成的记录的ID 最初,我在第一个测试中调用了第二个测试,这样我就可以通过ID作为参数,它工作得很好,只是这意味着基本上只有一个测试 我创建了一个有序列表,其ID声明在范围之外,但在第一次单元测试之后,该值返回到0,因此显然第二次单元测试失败 有没有办法创建测试,以便它们共享第一次测试中产生的值 代码如下: [Te
[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();
}
}
这很顽皮,但是您可以取消注释(如果是由测试向导或add创建的) 这与模拟一些常见的测试数据没有什么不同,尽管同样可疑 我正在创建一个相互依赖的单元测试列表。例如,我的第一个测试在数据库中创建一条记录,并检查返回值是否大于0 在我看来,这种做法是不正确的。你可能会创造邪恶的代码,这会反过来咬你。此类代码:
- 打破了单元测试的原则
- 很难维持
- 非常死板、繁琐且容易出错
您试图完成的可能是集成测试。编写它们的一种方法是为此类测试创建一个单独的项目。每个测试仍然相互独立,但可能每个测试都需要一些NUnit测试术语中的
设置
和拆卸
。因此,安装程序将准备集成测试通过所需的一切,而拆卸将在每次测试后执行清理 你不应该那样做。每个测试都应该是独立的。你甚至不知道测试运行者执行测试的顺序,他们没有顺序!错。您的第二个单元测试可以在第一个单元测试执行之前执行,因此根本没有创建任何记录。一个自包含的单元测试在设置中创建自己的测试数据,并在拆卸过程中进行清理,但这并不能保证。一些测试运行者甚至故意对测试进行洗牌,以确保测试之间不相互依赖。很抱歉,您使用单元测试的方式是错误的。@user1016253我对此表示赞赏。问题是,客户可能会认为它没有业务价值,并可能在确定优先级时将其丢弃(假设XP的规划游戏)。用Bob Martin的话来说,专业人士总是保持代码的整洁,因为这是保持可持续发展的唯一途径。现在回想起来……哇,我真的不理解单元测试。你能证明“单元测试必须是独立的”这句话是正确的吗?似乎是常识,但我从来没有真正听到过这样做的原因…@101只是增加了几段:基本上,它降低了测试的复杂性。你希望测试尽可能简单,这样你就不会浪费脑力去理解测试了。这是大型系统中的一个大问题。作为奖励,您可以并行运行测试,从而加快测试时间。在实践中,我看到测试运行速度提高了2到8倍。如果是5分钟对40分钟,并且你在每次提交后释放,那么这是有意义的。
//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()
{
}