【发布时间】:2020-01-02 11:31:03
【问题描述】:
我必须用 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 结合起来?
【问题讨论】:
-
选项 1 看起来不错且可维护
-
第一个选项看起来像“共享对象”;由于我试图避免的生命周期差异,只有对 xUnit 和 NUnit 有经验的人可能会感到困惑。 xUnit 每次测试运行都会创建一个类的实例,但 NUnit 的工作方式不同。那些只有 xUnit 经验的人,他们可能会按预期读取该属性,但同时 NUnit 人可能会将其读取为共享状态。如果测试并行运行,也无法使用该对象作为属性
-
您创建每个夹具设置方法并在设置中初始化 sut
-
不确定我理解你的意思,对不起,你能澄清一下吗?
标签: c# unit-testing testing nunit