简体   繁体   English

在这个测试中多个断言是错误的吗?

[英]Are multiple asserts wrong in this test?

I am trying to test a method called Login that, when the user and password parameters are correct, sets the value of two session variables and three cookies and finally returns true. 我正在尝试测试一个名为Login的方法,当用户和密码参数正确时,设置两个会话变量和三个cookie的值,最后返回true。

I've been reading several posts about unit testing, but somehow that didn't make my case fully clear to me. 我一直在阅读几篇关于单元测试的帖子,但不知怎的,这并没有让我对我的情况完全清楚。 I know that there should be just a single assert per unit test, although you can use more than one as long as you test a single "logical concept". 我知道每单元测试应该只有一个断言,尽管只要测试一个“逻辑概念”就可以使用多个断言。

Login method is correct only if it sets correctly every session variable and cookie and returns the expected value, so I'm not sure if it would be ok to check all these values at once (that would lead me to use six asserts in the unit test, a bit dirty I think) or if I should check the value of each session variable and cookie separately in different tests. 登录方法只有正确设置每个会话变量和cookie并返回预期值才正确,所以我不确定是否可以立即检查所有这些值(这会导致我在单元中使用六个断言)测试,我觉得有点脏)或者我应该在不同的测试中分别检查每个会话变量和cookie的值。

[TestMethod()]
public void SuccessfulLoginTest()
{
    // Arrange.
    String username = "foo";
    String password = "correct password";
    Boolean remember = true;

    // Act.
    Boolean actual = Login(username, password, remember);

    // Assert.
    Assert.IsTrue(actual);
    Assert.AreEqual("foo", HttpContext.Current.Session["Username"]);
    Assert.AreEqual(1, HttpContext.Current.Session["Group"]);
    Assert.AreEqual("foo", HttpContext.Current.Response.Cookies["Username"].Value);
    Assert.AreEqual("en", HttpContext.Current.Response.Cookies["Lang1"].Value);
    Assert.AreEqual("es", HttpContext.Current.Response.Cookies["Lang2"].Value);
}

You've already noticed correctly, that the one assert rule concerns conceptual assertions, not bare calls to the Assert methods. 您已经注意到, 一个断言规则涉及概念断言,而不是对Assert方法的裸调用。 A nice and common trick that reduces confusion when one logical assert is composed of many assertions and also makes the test more readable is wrapping the asserts in an utility method. 当一个逻辑断言由许多断言组成并且使测试更具可读性时,一个很好的常见技巧可以减少混淆,它将断言包含在实用程序方法中。 In your case it could look similar to this: 在你的情况下,它可能看起来像这样:

void AssertSessionIsValid(string username, int group, ...)
{
    Assert.AreEqual(username, HttpContext.Current.Session["Username"]);
    Assert.AreEqual(group, HttpContext.Current.Session["Group"]);
    ...
}

There are many frameworks that help in increasing readability of your tests, like Shouldly . 有许多框架有助于提高测试的可读性,例如Shouldly

Looks fine to me too. 对我来说也很好看。 I'm not sure where you got the notion that there should only be one Assert per unit test. 我不确定你的每个单元测试应该只有一个Assert的概念。 That sounds like an "ivory tower" rule that is just plain silly IMO. 这听起来像一个“象牙塔”规则,只是一个愚蠢的IMO。 If your method sets a bunch of variables given a particular input then you should check all those variables given that input. 如果您的方法在给定特定输入的情况下设置了一堆变量,那么您应该检查给定该输入的所有变量。 Writing six different unit tests (and associated setup code) seems incredibly inefficient. 编写六个不同的单元测试(以及相关的设置代码)似乎非常低效。

But then I tend to lean towards pragmatism over academic "correctness" when it comes to writing software. 但是当谈到编写软件时,我倾向于倾向于实用主义而不是学术上的“正确性”。

I'd suggest to assert everything you care about being 'working' and no more than that. 我建议断言你关心的所有事情都在“工作”,而不仅仅是那个。 Too few asserts and your test will ignore clearly broken functionality; 断言太少而你的测试会忽略明显破坏的功能; too many and your test will be brittle and break unnecessarily when some irrelevant detail changes. 太多了,当一些不相关的细节发生变化时,你的测试会变得脆弱并且不必要地破坏。

Have your conditions matched in a boolean variable and if all are fulfilled, then the boolean variable should return true. 在布尔变量中匹配条件,如果满足所有条件,则布尔变量应返回true。

Asset this boolean variable 资产这个布尔变量

bool AreAllConditionsFulfilled = condition1 && condtionCheckingSessionVariablesOne && conditionCheckingSessionVariablesTwo

Also I would suggest have individual test cases testing each of the Session Variables and assert if they are correct. 此外,我建议让各个测试用例测试每个会话变量,并断言它们是否正确。

[Test]
public void TestUserNameSessionVariable()
{
//Login Code
Assert.AreEqual("foo", HttpContext.Current.Session["Username"]);
}

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

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