在单个测试中检查多个不同的示例输入?

发布于 2024-07-19 22:20:11 字数 470 浏览 1 评论 0原文

假设我想编写一个验证电子邮件地址的函数 用正则表达式。 我写了一个小测试来检查我的功能并编写 实际功能。 让它通过。

但是,我可以想出一堆不同的方法来测试相同的内容 函数 ([电子邮件受保护]; [电子邮件受保护];test.test.com 等)。

我是否将需要检查的所有咒语放在同一个、单一的咒语中? 使用多个断言进行测试,或者我是否为每个断言编写一个新测试 我能想到什么?

谢谢!

Let's say I want to write a function that validates an email address
with a regex. I write a little test to check my function and write the
actual function. Make it pass.

However, I can come up with a bunch of different ways to test the same
function ([email protected]; [email protected]; test.test.com, etc).

Do I put all the incantations that I need to check in the same, single
test with several ASSERTS or do I write a new test for every single
thing I can think of?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

饮湿 2024-07-26 22:20:11

大多数测试框架现在都支持某种基于数据的测试,让您可以在多个数据集上运行相同的测试。

请参阅 NUnit 中的 ValuesAttribute

xUnit.net、MBUnit 等也有类似的方法。

Most testing frameworks now support some sort of data based testing to let you run the same test on multiple data sets.

See the ValuesAttribute in NUnit.

xUnit.net, MBUnit and others have similar methods.

離人涙 2024-07-26 22:20:11

一般来说,我创建许多不同的测试,并为每个测试指定自己的名称。 例如,假设有 3 个不同的正则表达式 {A, B, & C} 用于匹配电子邮件地址。 该函数检查传入电子邮件是否匹配并接受找到的第一个匹配项。

我会进行以下测试。

  • ATypeEmailShouldMatchPatternA
  • BTypeEmailShouldMatchPatternB
  • CTypeEmailShouldMatchPatternC
  • BadEmailShouldNotMatchAnyPattern
  • EmailCompatibleWithPatternAAndPatternBShouldBeMatchedByA
  • EmailCompatibleWithPatternAAndCShouldBeMatchedByA
  • EmailCompatibleWithPatternBAndCShouldBeMatchedByB

一般来说,我会在每个测试中放置一个断言。

然而,有时,如果断言全部检查同一事物的不同部分,我会在测试中放入多个断言。 例如,假设我有一个函数可以查找与模式 A 匹配的所有电子邮件。我的测试在电子邮件列表中提供,但只有一封与模式 A 匹配。该函数返回一个列表,并且我希望该列表中只有一个元素它。 所以我断言两件事:

  1. 列表中有一个元素。
  2. 其中一个元素是与模式 A 匹配的电子邮件。

Generally I create many different tests, and give each it's own name. For example let's say that there are 3 different regexes {A, B, & C} for matching an email address. The function checks the incoming email for a match and accepts the first match found.

I would have the following tests.

  • ATypeEmailShouldMatchPatternA
  • BTypeEmailShouldMatchPatternB
  • CTypeEmailShouldMatchPatternC
  • BadEmailShouldNotMatchAnyPattern
  • EmailCompatibleWithPatternAAndPatternBShouldBeMatchedByA
  • EmailCompatibleWithPatternAAndCShouldBeMatchedByA
  • EmailCompatibleWithPatternBAndCShouldBeMatchedByB

Generally I'd put one assert in each test.

Sometimes, however, I'll put more than one assert in a test if the asserts are all checking different parts of the same thing. For example, let's say I have a function that finds all the emails matching pattern A. My test feeds in a list of emails but only one matches pattern A. The function returns a list, and I expect that list to have only one element in it. So I would assert two things:

  1. That the list has one element in it.
  2. That the one element is the email that matches pattern A.
柳絮泡泡 2024-07-26 22:20:11

正如 @Paul 提到的几个测试框架支持 RowTests。 使用该功能,您可以编写像这样可怕的东西:

[TestCase ("[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x#[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x%[email protected]", true)]
[TestCase ("x&[email protected]", true)]
[TestCase ("x'[email protected]", true)]
[TestCase ("x*[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x/[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x^[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x`[email protected]", true)]
[TestCase ("x{[email protected]", true)]
[TestCase ("x{[email protected]", true)]
[TestCase ("x|[email protected]", true)]
[TestCase ("x}[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("test", false)]
[TestCase ("", false)]
[TestCase (null, false)]
public void IsEmail_Should_Match_Valid_Email_Addresses(string target, bool result)
{
    Assert.AreEqual(result, target.IsEmail());
}

或者您可以对一堆断言执行相同的操作。 在执行某些操作后断言对象的多个属性是很常见的。 我认为上述解决方案更具可读性。

As @Paul mentioned several test frameworks support RowTests. Using that feature you can write something as monstrous as this:

[TestCase ("[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x#[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x%[email protected]", true)]
[TestCase ("x&[email protected]", true)]
[TestCase ("x'[email protected]", true)]
[TestCase ("x*[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x/[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x^[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("x`[email protected]", true)]
[TestCase ("x{[email protected]", true)]
[TestCase ("x{[email protected]", true)]
[TestCase ("x|[email protected]", true)]
[TestCase ("x}[email protected]", true)]
[TestCase ("[email protected]", true)]
[TestCase ("test", false)]
[TestCase ("", false)]
[TestCase (null, false)]
public void IsEmail_Should_Match_Valid_Email_Addresses(string target, bool result)
{
    Assert.AreEqual(result, target.IsEmail());
}

Or you could do the same with a bunch of asserts. It's common to assert multiple properties on an object after performing some action. I think the above solution is more readable though.

韶华倾负 2024-07-26 22:20:11

如果不同的咒语真的归结为同一件事,那就不是问题。

但是,如果其中一个电子邮件地址突然破坏了测试,您将必须进行调试以找出出现问题的情况。 所以这似乎是分手的一个很好的理由。

您最终会进行数百万个单元测试,这是正确的,因为它们毕竟测试了应用程序的一个单元,但实际上,只要失败的断言破坏测试的方式不会扰乱测试,多个断言就可以了。失败的意义。

If the different incantations really boil down to the same thing it isn't a problem.

However, if one of the email addresses suddenly breaks the test, you are going to have to debug to find out which case went wrong. So that seems a good reason to break them up.

You would end up with millions of unit tests, which is right as they are after all tesing a unit of your application, but in practice multiple asserts will do providing that the way in which a failed assert breaks the test doesn't mess up the meaning of the failure.

凯凯我们等你回来 2024-07-26 22:20:11

BDD 和/或 Context/Specification 框架类似于 SubSpec,它恰好有一些显着的特性示例通过将每批相关断言视为一个单独的观察块来管理此问题,并为其提供名称或描述性标签。

这推动了一个好的测试的关键要素是:

  1. 每个阶段都有 AAA/GWT 分离 - 你被迫真正思考哪个是哪个[并且通常会很快意识到当事情需要更多地分解时]
  2. 你最终会得到关于观察的好名字/描述(行测试通常最多只会给你留下[不太可维护的]注释)
  3. 当24个测试中的第10和17个[与行测试一样]你有每个测试的状态可帮助您缩小解决方案

的范围,当您确实正在执行基于简单表格或矩阵的套件时,行测试在某些情况下可能是合适的。

此外,xUnit.net 的 PropertyData 在某些情况下可以非常强大且合适,作为执行其他答案中的一些技巧的一种方式。

BDD and/or Context/Specification frameworks like SubSpec which happens to have some salient examples manage this by treating each batch of related assertions as a separate Observation block that one gives a name or descriptive label to.

The key elements of a good test that this pushes one towards are:

  1. you have AAA / GWT separation of each of the phases - you're forced to really think about which is which [and will often quickly realise when things need to be broken up more]
  2. You end up with good names/descriptions on Observations (Row Tests generally leave you with [less maintainable] comments at best)
  3. When tests 10 and 17 out of 24 [as with Row Tests] you have the status of each of the tests to assist you in narrowing down the solution

Row Tests can be appropriate in some cases when you really are doing a simple table or matrix based suite of things.

Also xUnit.net's PropertyData can be powerful and appropriate in some cases as a way of doing some of the tricks in the other anwers.

救星 2024-07-26 22:20:11

我认为您不应该为每个案例编写单独的测试,因为所有案例都与测试该字符串是否是正确的电子邮件地址的同一事物相关。 如果您使用 MbUnit 或 NUnit 来运行测试,则可以使用 RowTest 和 Row 属性将不同的值传递给测试。 另一种方法是将所有不同的电子邮件格式存储在一个数组中,然后循环该数组并执行断言。

I don't think that you should write separate test for each case since all the cases are related to the same thing which is testing that the string is the correct email address. If you are using MbUnit or NUnit for running your tests then you can use the RowTest and Row attribute to pass in different values to the test. Another way is to store all the different email formats in an array and loop over the array and perform the assert.

狼性发作 2024-07-26 22:20:11

如果您正在测试相同的功能,我会在同一个测试中使用多个断言来检查它们,前提是您的测试足够简单。

有些人主张每个测试必须只有一个断言,因为测试必须非常非常简单。

如果测试不简单,比如说你有循环和if,你就需要对测试本身进行测试,以检查它的逻辑是否正确,这是不好的。

如果您的测试有多个断言,但仍然保持简单(没有循环,没有 if)并且多个断言正在测试同一件事,那么我就不会那么激进提倡“每个测试单一断言”。 这是你的选择。

If you are testing the same functionality, I'd check them in the same test, with multiple assertions, provided that your tests remain simple enough.

Some people advocate that every test must have just a single assertion, because the test must be very, very, very simple.

If the test is not simple, say that you have loops and ifs, you would need a test for the test itself, to check that its logic is correct, and this is not good.

If your test has multiple assertions, but still remain simple (no loops, no ifs) and the multiple assertions are testing the same thing, then I'd not be so aggressive in advocating "single assert per test". The choice is yours.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文