실행되기 전에보고하고 카테고리를 관리하지 않고 쉘 스크립트를 통해 개별 테스트를 실행할 수있는 옵션이 있습니다. 우리는 프로세스를 나쁜 상태로 남겨 둘 수있는 관리되지 않는 코드를 가지고 있으며 때때로 nunit-console 실행마다 각 테스트를 개별적으로 실행하기도합니다.nunit-console은 테스트 픽스처의 모든 테스트 이름을 나열 할 수 있습니까?
답변
nunit-console은 여전히이 옵션을 지원하지 않는 것 같습니다. 그러나 리플렉션을 사용하여 테스트 케이스 목록을 얻는 것은 상당히 간단합니다. 매우 기본적인 수준에서 모든 public
메서드의 목록은 public class
이고 적절한 [Test]/[TestFixture]
특성이 필요합니다. 테스트 구성 방법에 따라 [Ignore]
특성으로 표시된 테스트를 제거하거나 기본 클래스의 테스트 메서드를 고려하는 등의 추가 필터링을 수행해야 할 수 있습니다. 기본적인 수준에서
TestFixture
에서 시험 방법을 원하는 경우
// Load the assembly containing your fixtures
Assembly a = Assembly.LoadFrom(assemblyName);
// Foreach public class that is a TestFixture and not Ignored
foreach (var c in a.GetTypes()
.Where(x=>x.IsPublic
&& (x.GetCustomAttributes(typeof(NUnit.Framework.TestFixtureAttribute)).Count() > 0)
&& (x.GetCustomAttributes(typeof(NUnit.Framework.IgnoreAttribute)).Count() ==0)))
{
// For each public method that is a Test and not Ignored
foreach (var m in c.GetMethods()
.Where(x=>x.IsPublic
&& (x.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute)).Count() > 0)
&& (x.GetCustomAttributes(typeof(NUnit.Framework.IgnoreAttribute)).Count() ==0)))
{
// Print out the test name
Console.WriteLine("{0}.{1}", c.ToString(), m.Name);
// Alternately, print out the command line to run test case using nunit-console
//Console.WriteLine("nunit-console /run:{0}.{1} {2}", c.ToString(), m.Name, assemblyName);
}
}
은 확실히 당신이 조금을 간소화 할 수있을 것입니다.
주석에서 설명한 것처럼및 TestCaseSource
과 같은 다른 NUnit 특성에주의해야하는 경우이 작업은 좀 더 복잡해집니다. 이 속성의 일부 기능을 지원하도록 아래 코드를 수정했습니다.
static void PrintTestNames(string assemblyName) {
Assembly assembly = Assembly.LoadFrom(assemblyName);
foreach (var fixture in assembly.GetTypes().Where(x => x.IsPublic
&& (x.GetCustomAttributes(typeof(TestFixtureAttribute)).Count() > 0)
&& (x.GetCustomAttributes(typeof(IgnoreAttribute)).Count() == 0))) {
foreach(var method in fixture.GetMethods().Where(x=>x.IsPublic
&& (x.GetCustomAttributes(typeof(IgnoreAttribute)).Count() == 0)
&& ((x.GetCustomAttributes(typeof(TestAttribute)).Count() > 0)
|| (x.GetCustomAttributes(typeof(TestCaseAttribute)).Count() > 0)
|| (x.GetCustomAttributes(typeof(TestCaseSourceAttribute)).Count() > 0))
)) {
var testAttributes = method.GetCustomAttributes(typeof(TestAttribute)) as IEnumerable<TestAttribute>;
var caseAttributes = method.GetCustomAttributes(typeof(TestCaseAttribute)) as IEnumerable<TestCaseAttribute>;
var caseSourceAttributes = method.GetCustomAttributes(typeof(TestCaseSourceAttribute)) as IEnumerable<TestCaseSourceAttribute>;
if (caseAttributes.Count() > 0) {
foreach(var testCase in caseAttributes) {
if (!string.IsNullOrEmpty(testCase.TestName)) {
PrintTestName(fixture.ToString(), testCase.TestName);
}
else {
string arguments = ExtractArguments(testCase.Arguments);
PrintTestName(fixture.ToString(), method.Name + arguments);
}
}
}
else if (caseSourceAttributes.Count() > 0) {
foreach (var testCase in caseSourceAttributes) {
var sourceName = testCase.SourceName;
if (!string.IsNullOrEmpty(sourceName)) {
var staticMember = fixture.GetField(sourceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
var instanceMember = fixture.GetField(sourceName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var staticMethodMember = fixture.GetMethod(sourceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
var instanceMethodMember = fixture.GetMethod(sourceName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var staticPropMember = fixture.GetProperty(sourceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
var instancePropMember = fixture.GetProperty(sourceName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
IEnumerable memberValues;
if (null != staticMember) {
memberValues = staticMember.GetValue(null) as IEnumerable;
}
else if (null != instanceMember) {
var instance = Activator.CreateInstance(fixture);
memberValues = instanceMember.GetValue(instance) as IEnumerable;
} else if(null != staticMethodMember) {
memberValues = staticMethodMember.Invoke(null,new object [0]) as IEnumerable;
}
else if (null != instanceMethodMember) {
var instance = Activator.CreateInstance(fixture);
memberValues = instanceMethodMember.Invoke(instance, new object[0]) as IEnumerable;
}
else if (null != staticPropMember) {
memberValues = staticPropMember.GetValue(null) as IEnumerable;
}
else if (null != instancePropMember) {
var instance = Activator.CreateInstance(fixture);
memberValues = instancePropMember.GetValue(instance) as IEnumerable;
}
else {
Console.WriteLine("*** Ooops...Looks like I don't know how to get {0} for fixture {1}", sourceName, fixture.ToString());
continue;
}
foreach (var memberValue in memberValues) {
if (null != memberValue as IEnumerable) {
PrintTestName(fixture.ToString(), method.Name + ExtractArguments(memberValue as IEnumerable));
}
else {
PrintTestName(fixture.ToString(), method.Name + "(" + memberValue.ToString() + ")");
}
}
} else {
Console.WriteLine("*** Ooops...Looks like I don't know how to handle test {0} for fixture {1}", method.Name, fixture.ToString());
}
}
}
else {
PrintTestName(fixture.ToString(), method.Name);
}
}
}
}
static string ExtractArguments(IEnumerable arguments) {
string caseArgs = "(";
bool first = true;
foreach (var arg in arguments) {
if (first) first = false;
else caseArgs += ",";
caseArgs += Convert.ToString(arg);
}
return caseArgs + ")";
}
static void PrintTestName(string fixture, string testName) {
Console.WriteLine("{0}.{1}", fixture, testName);
//Console.WriteLine("nunit-console /run:{0}.{1} {2}", fixture, testName, assemblyName);
}
위의 코드를 보면, 당신은 시험에 대한 TestCaseSource
는 재산/방법/필드 이름을 지정하는 문자열이 어디 기능을 처리 한 것을 알 수 있습니다. 또한 코드가 더 많을 때 코드가 있다는 것을 알 수 있습니다.이 코드는 여전히 매우 직관적이므로 TestCaseSource의 다른 버전을 사용하고 있거나 다른 NUnit 특성을 사용하고 있다면 쉽게 확장 할 수 있습니다. 음식을 제공하지 않았다.
nunit-console이 실행될 테스트의 수와 동일한 수의 테스트가 인쇄 될 수 있도록 위의 카운터를 추가하기가 쉽습니다.
이것은 기본을 얻지 만, 다른 입력에서 자동으로 테스트를 생성 할 수있는 고급 속성 중 일부를 사용하면 운이 없어진 것입니다! –
@SebastianGood 위의 TestCase + TestCaseSource 순열에 대한 지원을 추가했습니다. 다른 TestCaseSource 옵션 (또는 내가 찾지 못한 다른 속성)을 처리하도록 코드를 확장하면 다른 것들을 사용하는 경우에는 간단해야하지만, 독자에게 * 연습으로 남겨 두겠다. – forsvarir
테스트 클래스가 이러한 속성을 가진 (추상) 기본 클래스를 상속하는 경우도 고려해야합니다. 그런 다음 동일한 테스트 방법을 여러 번 실행하기 위해 개수를 조정해야합니다. – WebDancer
이제 테스트를 실행하지 않고 모든 테스트 사례를 나열하는 데 사용할 수있는 --explore
명령 줄 옵션이 있습니다. 더 구체적으로
nunit3-console.exe MyProject.dll --explore
더 많은 정보를 들면 : 그들은 실행하지만, 바로 당신이 원하는 것은 것을 얻을 것입니다 생각에 나는 오전으로하여 MyAssembly.dll/labels` 모든 테스트를 표시합니다 https://github.com/nunit/docs/wiki/Console-Command-Line#description
'NUNIT 콘솔 미리 목록을 작성한 다음 사용자에게 프롬프트하거나 (또는'/ runlist ='파일에 추가하십시오)? 카테고리 사용을 원하지 않는 이유는 무엇입니까? – ClickRick
우리는 그들을 미리 원한다. 여기에서 핵심은 한 번에 하나씩 실행하고 싶다는 것입니다. 즉, 테스트 당 한 번씩 nunit-console 자체를 반복해서 실행해야합니다. 우리는 더 이상이 작업을 수행 할 필요가 없도록 구성 요소를 변경했지만 여전히 이에 대한 대답을 보지 않고는 놀랍습니다. –
이것이 여전히 문제가된다면 EventListener 클래스를 사용하여 살펴 보려고합니다 (http://imistaken.blogspot.co.uk/2009/03/nunit-extensions-adding-logic-at-run 참조). .html 예를 들어) 당신이 그런 식으로 목록을 얻을 수 있는지,하지만 그 시점에서 테스트의 실제 실행을 억제 할 수있는 의존하고, 그게 내가 그것을 시도하지 않고 알 수없는 무언가이다. – ClickRick