您通常如何描述和实施情景的“给定”步骤?
高级别状态说明
Given I have 4 products
When I look for best-selling products
Then I see top 3 products with maximum number of sales
PRO
CON
明确的数据定义
Given I have following products:
| Name | Sales number |
| Beer | 20 |
| Pizza | 5 |
| Socks | 3 |
| Toilet paper | 100 |
When I look for best-selling products
Then I see following products:
| Name | Sales number |
| Toilet paper | 100 |
| Beer | 20 |
| Pizza | 5 |
PRO
CON
填充数据库
using (var connection = new SqlConnection(connectionString))
{
using (var deleteCommand = new SqlCommand("DELETE FROM Products", connection))
{
connection.Open();
deleteCommand.ExecuteNonQuery();
}
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Products", connection);
DataSet data = new DataSet();
adapter.Fill(data);
foreach (var specFlowRow in table.Rows)
{
DataRow dataRow = data.Tables[0].Rows.Add();
dataRow["Name"] = specFlowRow["Name"];
}
adapter.Update(data);
}
PRO
CONS
存储库存根
// or get stubbed repository from DI framework
productsRepository = new InMemoryProductsRepository();
// or use specflow assist helpers
foreach (var specFlowRow in table.Rows)
productsRepository.Save(new Product(specFlowRow["Name"]));
PRO
CONS
这就是我对可能方式的看法:) 您以什么方式定义和实施“给定”步骤? 谢谢!
答案 0 :(得分:1)
我们通过你提到的组合实现给定。通过使用DI和不同的配置(使用this tool变得容易),我们在内存中大部分时间运行单元测试,并在CI服务器上强制它们作为针对真实数据库的集成测试。因此,您可以获得性能和全面测试。
为了设置您的数据,我个人最喜欢您的示例'显式数据定义'。指定测试使用的数据可确保您可以将测试作为文档阅读。针对未知数据存储运行会使测试难以阅读。但是在这种情况下构建测试数据时,产品的名称并不重要,只有金额。
这是使用Builder模式处理的。仅指定为测试导入的数据,并让Builder为所有其他字段生成默认值。
NBuilder是一个非常好的工具。我们现在正在使用它来进行测试,看起来很有希望。
您的测试看起来像:
class Product
{
public string Name { get; set; }
public int Sales { get; set; }
}
[TestMethod]
public void SalesTest()
{
var products = Builder<Product>.CreateListOfSize(4)
.TheFirst(1)
.With(x => x.Sales = 20)
.AndTheNext(1)
.With(x => x.Sales = 5)
.AndTheNext(1)
.With(x => x.Sales = 3)
.AndTheNext(1)
.With(x => x.Sales = 100).Persist();
var result = SystemUnderTest.Execute();
Assert.AreEqual(3, result.Count);
Assert.AreEqual(100, result[0].Sales);
Assert.AreEqual(20, result[0].Sales);
Assert.AreEqual(5, result[0].Sales);
}
答案 1 :(得分:1)
作为“我们如何设置复杂或相关对象的给定?”的广泛答案。问题 - 如产品和销售 - 所有取决于您指定的行为。没有一种正确的方法。顺便说一句,你没有包含功能和场景文本,以便为我们提供一些关于这个问题的行为的背景,但是,不可否认,这并不难猜测。
你的“不易碎”的第一个例子显示了一个很好的方法来驱逐基本行为,告诉我用户可以查看最畅销产品及其销售数字的简短列表。
如果你想证明显示器在某种程度上关注以排名的方式展示事物,那么你会更明确地给出,然后明确表示你按销售量进行“反向排序”。或者,这个明确的例子可以被认为是非常清楚你的意思。
我通常的经验法则是将设置限制为您在当前场景中要测试的“对象图”的那些部分。这有助于引起人们对正在测试的系统中最“狭窄”的部分的注意。否则,如果您继续从头开始为所有场景构建所有内容,有时很难看到测试的目的。有时您关心父对象中的细节,有时您想要测试各部分的总和。