c# - NUnit TestFixture 和 TestCase
问题描述
我必须用 NUnit 编写一些集成测试来测试 HTTP 端点。这意味着应该在所有测试方法之间共享 URL。
[TestFixture("http://my.endpoint.com")]
public class TestSuiteOne
{
[TestCase(10, 20, Expected = 30)]
[TestCase(20, 30, Expected = 50)]
public int TestA(int a, int b, HttpResponseMessage sut)
{
// AAA.
}
[TestCase("XXX", "YYY", Expected = "ABC")]
public int TestA(string a, string b, HttpResponseMessage sut)
{
// AAA.
}
}
要获得来自测试套件属性的每个测试运行的 SUT 值,我知道两个选项:
选项 A(从类属性中读取 SUT)
public abstract class TestSuiteBase
{
protected(string endpoint)
{
Sut = endpoint;
}
protected HttpResponseMessage Sut { get; }
}
[TestFixture("http://my.endpoint.com")]
public class TestSuiteOne : TestSuiteBase
{
public TestSuiteOne(string endpoint) : base(endpoint)
{
}
[TestCase(10, 20, Expected = 30)]
[TestCase(20, 30, Expected = 50)]
public int TestA(int a, int b)
{
// act (read content/response code/headers/etc); Making a call I do not consider as act.
var actual = Sut.DoSomething();
// assert
}
[TestCase("XXX", "YYY", Expected = "ABC")]
public int TestA(string a, string b)
{
// act (read content/response code/headers/etc); Making a call I do not consider as act.
var actual = Sut.DoSomething();
// assert
}
}
选项 B(拦截测试方法调用)
public class MyTestCase: TestCaseAttribute
{
public MyTestCase(params object[] args) : base(Resize(args))
{
}
// I do resize before method call because VS Test Adapters discover tests to show a list in the test explorer
private static object[] Resize(params object[] args)
{
Array.Resize(ref args, args.Length + 1);
args[args.Length - 1] = "{response}";
return args;
}
}
public abstract class TestSuiteBase
{
[SetUp]
public void OnBeforeTestRun()
{
var ctx = TestContext.CurrentContext;
var args = ctx.Test.Arguments;
// Making a call I do not consider as act.
args[args.Length - 1] = MakeCallAndGetHttpResponseMessage(args);
}
}
[TestFixture("http://my.endpoint.com")]
public class TestSuiteOne : TestSuiteBase
{
[MyTestCase(10, 20, Expected = 30)]
[MyTestCase(20, 30, Expected = 50)]
public int TestA(int a, int b, HttpResponseMessage sut)
{
// act (read content/response code/headers/etc); Making a call I do not consider as act.
var actual = sut.DoSomething();
// assert
}
[MyTestCase("XXX", "YYY", Expected = "ABC")]
public int TestA(string a, string b, HttpResponseMessage sut)
{
// AAA.
}
}
有没有更方便的方法可以将来自 TestFixture 的值与 TestCase 结合起来?
解决方案
由于您将端点字符串放在 上TestFixtureAttribute
,我将假设
- 您想与夹具中的所有测试用例共享它。
- 您不想与任何其他灯具共享它。
您的示例中唯一缺少的是一个构造函数,它将接受您提供的参数。只需添加类似...
public TestSuiteOne(string url)
{
Sut = endpoint;
}
只要您创建Sut
只读属性或字段,您的任何测试用例都无法更改它,无论它们是按顺序运行还是并行运行。
您提供的两个选项对我来说似乎都过于复杂,至少在您解释问题的范围内。第一个最接近这个答案。
当然,您完全有可能对网站做其他事情,这会导致并行(甚至顺序)测试相互干扰。不要那样做。:-) 说真的,共享驱动程序与共享字符串完全不同,但这是一个不同的问题。
IMO,顺便说一下,你和你的团队应该习惯一个或另一个测试框架。您提到的生命周期问题并不是 NUnit 和 xUnit 之间唯一的细微差别!
推荐阅读
- php - Compare multidimensional array values by key in php
- javascript - Vuejs如何将点击功能设置为语义UI的关闭功能?
- java - Java ee Servlet 正在处理 AbstractMethodError
- ios - iOS App Rejected EXC_BAD_ACCESS (SIGSEGV) - 无法重现错误
- python - TypeError: 'int' 对象不可调用 total_interest = num_payments(years * 12) * loanpayment(principal, percent, years)
- entity-relationship - 双方一对一关系的实体关系
- javascript - 如何使用 Formik Yup 验证多个电话号码
- c++ - 如何通过保存在容器中的成员指针函数调用?
- sparql - 使用 SPARQL 查询时,如何保护运行 Sesame Triplestore 的系统免受注入?
- python - 如何将变量分配给 matplotlib 图形对象并在布局中重用它