逐步功能测试自动化

时间:2022-10-08 16:32:16

I have a basic class in C# from which I create inherited classes for databinding scenarios. You can think of it as a substitute for .NET's DataRow class.

我在C#中有一个基本类,我从中为数据绑定方案创建了继承类。您可以将其视为.NET的DataRow类的替代品。

I want to automate testing of a typical row's lifetime, making sure that things such as object state and changes detection remains coherent throughout.

我想自动测试典型行的生命周期,确保对象状态和变化检测等内容始终保持一致。

My first thought was to simply use unit test class with a method that would do multiple operations and consequent assertions, like this:

我的第一个想法是简单地使用单元测试类和一个可以执行多个操作和后续断言的方法,如下所示:

/*
For the sake of keeping this as simple as possible, let's just assume
that new instances can be created with a public constructor, as "unchanged".
*/

var row = new PocoTest(); // Derived from aforementionned base class

Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
Assert.IsFalse(row.IsPropertyModified("MyProperty"));

row.MyProperty = "this is a new value";

Assert.AreEqual(RecordStates.Modified, row.RecordState);
Assert.IsTrue(row.IsPropertyModified("MyProperty"));

row.AcceptChanges();

Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
Assert.IsFalse(row.IsPropertyModified("MyProperty"));

However, this doesn't feel right in the unit testing paradigm in which it is recommended to have only one thing at a time being tested.

但是,在单元测试范例中,这种情况并不合适,因为建议一次只测试一件事。

So I'm kind of looking for some advice, here. Am I overthinking this? Should I just keep doing it this way? Or is there another, better and more adapted way to accomplish something like this?

所以我在这里寻找一些建议。我是否过度思考这个?我应该继续这样做吗?或者是否有另一种更好,更适应的方式来完成这样的事情?

2 个解决方案

#1


3  

your tests should each be testing one logical thing. This may require several steps or assertions to verify. This is fine.

你的测试应该每个都测试一个逻辑的东西。这可能需要几个步骤或断言来验证。这可以。

However your tests look to me like 3 tests. 1 which verifies that upon creation the property is unchanged, and then one which verifies that when its changed the object reflects that and then one which verifies that after accepting changes the state is unchanged again.

然而,你的测试看起来像3个测试。 1验证在创建时属性是否未更改,然后验证在其更改时对象反映了该属性,然后验证在接受更改后状态再次未更改。

What have you called your test currently. I suspect that you have had trouble giving it a name, or it has a long convoluted name. Splitting it it should give you nice descriptive names.

你有什么称呼你的考试。我怀疑你在给它起名字时遇到了麻烦,或者它有一个很长的错综复杂的名字。拆分它应该给你很好的描述性名称。

I'd go with this:

我会选择这个:

public void WhenRowIsCreatedItShouldBeInAnUnchangedState()
{
  var row = new PocoTest(); // Derived from aforementionned base class

  Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
  Assert.IsFalse(row.IsPropertyModified("MyProperty"));
}


public void WhenPropertyIsChangedItShouldBeInAModifiedState()
{
  var row = new PocoTest(); // Derived from aforementionned base class
  row.MyProperty = "this is a new value";

  Assert.AreEqual(RecordStates.Modified, row.RecordState);
  Assert.IsTrue(row.IsPropertyModified("MyProperty"));
}

public void WhenChangesAreAcceptedItShouldBeInAnUnchangedState()
{
  var row = new PocoTest(); // Derived from aforementionned base class
  row.MyProperty = "this is a new value";
  row.AcceptChanges();

  Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
  Assert.IsFalse(row.IsPropertyModified("MyProperty"));
}

#2


1  

I'll have to be controversial here - I think the "one test, one test method" is a dogma rather than a useful tool. Its a matter of whether your test is whole, complete and predictable. I'd say go with your current approach - after all what is to be gained by splitting it up and adding complexity. Your code currently has lower cyclomatic complexity than adding in an extra function call for each Assert.

我必须在这里引起争议 - 我认为“一种测试,一种测试方法”是一种教条,而不是一种有用的工具。这是您的测试是完整,完整和可预测的问题。我会说你现在采用的方法 - 毕竟通过拆分和增加复杂性可以获得什么。您的代码当前具有较低的圈复杂度,而不是为每个Assert添加额外的函数调用。

#1


3  

your tests should each be testing one logical thing. This may require several steps or assertions to verify. This is fine.

你的测试应该每个都测试一个逻辑的东西。这可能需要几个步骤或断言来验证。这可以。

However your tests look to me like 3 tests. 1 which verifies that upon creation the property is unchanged, and then one which verifies that when its changed the object reflects that and then one which verifies that after accepting changes the state is unchanged again.

然而,你的测试看起来像3个测试。 1验证在创建时属性是否未更改,然后验证在其更改时对象反映了该属性,然后验证在接受更改后状态再次未更改。

What have you called your test currently. I suspect that you have had trouble giving it a name, or it has a long convoluted name. Splitting it it should give you nice descriptive names.

你有什么称呼你的考试。我怀疑你在给它起名字时遇到了麻烦,或者它有一个很长的错综复杂的名字。拆分它应该给你很好的描述性名称。

I'd go with this:

我会选择这个:

public void WhenRowIsCreatedItShouldBeInAnUnchangedState()
{
  var row = new PocoTest(); // Derived from aforementionned base class

  Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
  Assert.IsFalse(row.IsPropertyModified("MyProperty"));
}


public void WhenPropertyIsChangedItShouldBeInAModifiedState()
{
  var row = new PocoTest(); // Derived from aforementionned base class
  row.MyProperty = "this is a new value";

  Assert.AreEqual(RecordStates.Modified, row.RecordState);
  Assert.IsTrue(row.IsPropertyModified("MyProperty"));
}

public void WhenChangesAreAcceptedItShouldBeInAnUnchangedState()
{
  var row = new PocoTest(); // Derived from aforementionned base class
  row.MyProperty = "this is a new value";
  row.AcceptChanges();

  Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
  Assert.IsFalse(row.IsPropertyModified("MyProperty"));
}

#2


1  

I'll have to be controversial here - I think the "one test, one test method" is a dogma rather than a useful tool. Its a matter of whether your test is whole, complete and predictable. I'd say go with your current approach - after all what is to be gained by splitting it up and adding complexity. Your code currently has lower cyclomatic complexity than adding in an extra function call for each Assert.

我必须在这里引起争议 - 我认为“一种测试,一种测试方法”是一种教条,而不是一种有用的工具。这是您的测试是完整,完整和可预测的问题。我会说你现在采用的方法 - 毕竟通过拆分和增加复杂性可以获得什么。您的代码当前具有较低的圈复杂度,而不是为每个Assert添加额外的函数调用。