2
// Copyright (C) 2002. James W. Newkirk, Michael C. Two, Alexei A. Vorontsov. All Rights Reserved.
8
using System.Reflection;
9
using System.Collections;
12
/// Summary description for TestSuiteBuilder.
14
public class TestSuiteBuilder
16
Hashtable suites = new Hashtable();
19
public static Assembly Load(string assemblyName)
21
Assembly assembly = Assembly.LoadFrom(assemblyName);
25
private TestSuite BuildFromNameSpace(string nameSpace)
27
if("".Equals(nameSpace)) return rootSuite;
28
TestSuite suite = (TestSuite)suites[nameSpace];
29
if(suite!=null) return suite;
30
int index = nameSpace.LastIndexOf(".");
33
suite = new TestSuite(nameSpace);
35
suites[nameSpace]=suite;
38
string parentNameSpace=nameSpace.Substring( 0,index);
39
TestSuite parent = BuildFromNameSpace(parentNameSpace);
40
string suiteName = nameSpace.Substring(index+1);
41
suite = new TestSuite(suiteName);
42
suites[nameSpace]=suite;
47
public static TestSuite Build(string assemblyName)
49
TestSuiteBuilder builder = new TestSuiteBuilder();
51
Assembly assembly = Load(assemblyName);
53
builder.rootSuite = new TestSuite(assemblyName);
54
int testFixtureCount = 0;
55
Type[] testTypes = assembly.GetExportedTypes();
56
foreach(Type testType in testTypes)
58
if(IsTestFixture(testType))
61
string namespaces = testType.Namespace;
62
TestSuite suite = builder.BuildFromNameSpace(namespaces);
66
object fixture = BuildTestFixture(testType);
69
catch(InvalidTestFixtureException exception)
71
InvalidFixture fixture = new InvalidFixture(testType, exception.Message);
77
if(testFixtureCount == 0)
78
throw new NoTestFixturesException(assemblyName + " has no TestFixtures");
80
return builder.rootSuite;
84
public static TestSuite Build(string testName, string assemblyName)
86
TestSuite suite = null;
88
Assembly assembly = Load(assemblyName);
92
Type testType = assembly.GetType(testName);
95
if(IsTestFixture(testType))
97
suite = MakeSuiteFromTestFixtureType(testType);
99
else if(IsTestSuiteProperty(testType))
101
suite = MakeSuiteFromProperty(testType);
108
private static bool IsTestFixture(Type type)
110
if(type.IsAbstract) return false;
112
return type.IsDefined(typeof(Nunit.Framework.TestFixtureAttribute), true);
115
public static object BuildTestFixture(Type fixtureType)
117
ConstructorInfo ctor = fixtureType.GetConstructor(Type.EmptyTypes);
118
if(ctor == null) throw new InvalidTestFixtureException(fixtureType.FullName + " does not have a valid constructor");
120
object testFixture = ctor.Invoke(Type.EmptyTypes);
121
if(testFixture == null) throw new InvalidTestFixtureException(ctor.Name + " cannot be invoked");
123
if(HasMultipleSetUpMethods(testFixture))
125
throw new InvalidTestFixtureException(ctor.Name + " has multiple SetUp methods");
127
if(HasMultipleTearDownMethods(testFixture))
129
throw new InvalidTestFixtureException(ctor.Name + " has multiple TearDown methods");
134
private static int CountMethodWithGivenAttribute(object fixture, Type type)
137
foreach(MethodInfo method in fixture.GetType().GetMethods(BindingFlags.Public|BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.DeclaredOnly))
139
if(method.IsDefined(type,false))
145
private static bool HasMultipleSetUpMethods(object fixture)
147
return CountMethodWithGivenAttribute(fixture,typeof(Nunit.Framework.SetUpAttribute)) > 1;
150
private static bool HasMultipleTearDownMethods(object fixture)
152
return CountMethodWithGivenAttribute(fixture,typeof(Nunit.Framework.TearDownAttribute)) > 1;
155
public static TestSuite MakeSuiteFromTestFixtureType(Type fixtureType)
157
TestSuite suite = new TestSuite(fixtureType.Name);
160
object testFixture = BuildTestFixture(fixtureType);
161
suite.Add(testFixture);
163
catch(InvalidTestFixtureException exception)
165
InvalidFixture fixture = new InvalidFixture(fixtureType,exception.Message);
166
suite.ShouldRun = false;
167
suite.IgnoreReason = exception.Message;
174
private static bool IsTestSuiteProperty(Type testClass)
176
return (GetSuiteProperty(testClass) != null);
180
/// Uses reflection to obtain the suite property for the Type
182
/// <param name="testClass"></param>
183
/// <returns>The Suite property of the Type, or null if the property
184
/// does not exist</returns>
185
private static TestSuite MakeSuiteFromProperty(Type testClass)
187
TestSuite suite = null;
188
PropertyInfo suiteProperty = null;
191
suiteProperty=GetSuiteProperty(testClass);
192
suite = (TestSuite)suiteProperty.GetValue(null, new Object[0]);
194
catch(InvalidSuiteException)
201
private static PropertyInfo GetSuiteProperty(Type testClass)
203
if(testClass != null)
205
PropertyInfo[] properties = testClass.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
206
foreach(PropertyInfo property in properties)
208
object[] attrributes = property.GetCustomAttributes(typeof(Nunit.Framework.SuiteAttribute),false);
209
if(attrributes.Length>0)
212
CheckSuiteProperty(property);
213
}catch(InvalidSuiteException){
223
private static void CheckSuiteProperty(PropertyInfo property)
225
MethodInfo method = property.GetGetMethod(true);
226
if(method.ReturnType!=typeof(Nunit.Core.TestSuite))
227
throw new InvalidSuiteException("Invalid suite property method signature");
228
if(method.GetParameters().Length>0)
229
throw new InvalidSuiteException("Invalid suite property method signature");