简体   繁体   English

我是否正确使用单元测试?

[英]Am I using Unit Testing correctly?

This is the first time that I write a TestMethod.这是我第一次编写TestMethod。 Am I using Unit Testing correctly?我是否正确使用单元测试?

[TestMethod]
public void TestUpdateAccount()
{
    GwIntegrationServiceSoapClient client = new GwIntegrationServiceSoapClient();

    int id = 21; // Target account to update.
    Account accountToUpdate = client.ReadAccount(id);

    string oldName = accountToUpdate.Name;
    string oldEmail = accountToUpdate.Email;
    string newName = Guid.NewGuid().ToString();
    string newEmail = Guid.NewGuid().ToString() + "@nomail.com";

    // Update the name only, even a value is passed in newEmail 
    // But in the propertiesToUpdate parameter (last one) only Name value is passed.
    // Note: the UpdateAccountProperty could be: 
    //          [UpdateAccountProperty.Name | UpdateAccountProperty.Name.Email]
    client.UpdateAccount(id, newName, newEmail, null, false, UpdateAccountProperty.Name);

    // Read the record after updating from database
    Account updatedAccountFirstTime = client.ReadAccount(21);

    // The name should be changed
    Assert.AreEqual(newName, updatedAccountFirstTime.Name);

    // The email should not be changed
    Assert.AreNotEqual(newEmail, updatedAccountFirstTime.Email);

    ////////////////////////////////////////////////////////////
    // Now, after updating the name and everything is working well
    // Returning the old name to the record.
    client.UpdateAccount(id, oldName, oldEmail, null, false, UpdateAccountProperty.Name);

    // Read the record after updating
    Account updatedAccountSecondTime = client.ReadAccount(21);

    Assert.AreEqual(oldName, updatedAccountSecondTime.Name);
}

Thank you very much for the answers.非常感谢您的回答。 I've updated my test method to these two methods:我已经将我的测试方法更新为这两种方法:

[TestMethod]
public void UpdateAccount_OneValueExpectedToBeUpdated_Updated()
{
    GwIntegrationServiceSoapClient client = new GwIntegrationServiceSoapClient();

    int id = 21; // Target account to update.
    Account accountToUpdate = client.ReadAccount(id);

    string oldName = accountToUpdate.Name;
    string oldEmail = accountToUpdate.Email;
    string newName = Guid.NewGuid().ToString();

    // Update the name only because it's passed by propertiesToUpdate parameter (last one).
    client.UpdateAccount(id, newName, null, null, false, UpdateAccountProperty.Name);

    // Read the record after updating from database
    Account updatedAccountFirstTime = client.ReadAccount(id);

    // The name should be changed
    Assert.AreEqual(newName, updatedAccountFirstTime.Name);
}

[TestMethod]
public void UpdateAccount_NoValueExpectedToBeUpdated_NotUpdated()
{
    GwIntegrationServiceSoapClient client = new GwIntegrationServiceSoapClient();

    int id = 21; // Target account to update.
    Account accountToUpdate = client.ReadAccount(id);

    string oldName = accountToUpdate.Name;
    string oldEmail = accountToUpdate.Email;
    string newName = Guid.NewGuid().ToString();
    string newEmail = Guid.NewGuid().ToString() + "@nomail.com";

    // Update the name only, even a value is passed in newEmail 
    // But in the propertiesToUpdate parameter (last one) only Name value is passed.
    client.UpdateAccount(id, newName, newEmail, null, false, UpdateAccountProperty.Name);

    // Read the record after updating from database
    Account updatedAccountFirstTime = client.ReadAccount(id);

    // The email should not be changed
    Assert.AreNotEqual(newEmail, updatedAccountFirstTime.Email);
}

This is difficult to answer, because the kinds of tests you will find under the title of "Unit Testing" will vary.这很难回答,因为您会在“单元测试”标题下找到的测试类型会有所不同。 Mostly, "Unit Test" is used as a synonym for "Automated Code Test", which strictly speaking, is anything which tests code in some automatic fashion by writing code.大多数情况下,“单元测试”被用作“自动化代码测试”的同义词,严格来说,它是通过编写代码以某种自动方式测试代码的任何东西。

If you want to write good unit tests, there are only a few rules to follow:如果你想写出好的单元测试,只需要遵循几条规则:

  • Test scenarios independently.独立测试场景。
  • Test objects independently.独立测试对象。
  • Keep your tests small and focused.保持你的测试小而专注。 If they bloat, create methods to help reduce the boilerplate code and focus on the specifics of the test.如果它们膨胀,创建方法来帮助减少样板代码并专注于测试的细节。

Ultimately, test one thing per test.最终,每次测试测试一件事。 That way when one particular behaviour or scenario breaks, you have an immediate focus as to which specific part of an object has failed.这样,当一个特定行为或场景发生故障时,您可以立即关注 object 的哪个特定部分发生故障。 In your example, you seem to be testing a number of things in a single method, if the first call to UpdateAccount succeeds, but the second one fails, the whole test fails and you aren't clear as to which part of the object has failed.在您的示例中,您似乎在一个方法中测试了许多东西,如果第一次调用UpdateAccount成功,但第二次调用失败,则整个测试失败并且您不清楚 object 的哪一部分有失败的。

You should get a copy of The art of unit testing .您应该得到一份The art of unit testing

Some points to be mentioned:需要提及的几点:

  • Only one Assert per test.每个测试只有一个断言。
  • Naming conventions for test method: public void MethodUnderTest_Scenario_Behavior()测试方法的命名约定: public void MethodUnderTest_Scenario_Behavior()

It seems good.看起来不错。 I generally have less lines in my tests.我的测试中的行数通常较少。

Could some of the boilerplate be moved into a fixture?可以将一些样板移到固定装置中吗?

Some people (including Roy Osherove in his The Art of Unit Testing) recommend one assert per unit test, seeing as if the first assert fails an exception is thrown and none of the remaining code is called and no other asserts are checked.有些人(包括 Roy Osherove 在他的《单元测试的艺术》中)建议每个单元测试使用一个断言,因为如果第一个断言失败,则会抛出异常,并且不会调用任何剩余的代码,也不会检查其他断言。

This could be split into two or more unit tests to achieve this, eg one for checking the name after update, one for checking the email address and potentially one to check that changing and changing back works.这可以分成两个或多个单元测试来实现这一点,例如,一个用于检查更新后的名称,一个用于检查 email 地址,还可能一个用于检查更改和更改回工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM