docs/articles/nunit/writing-tests/attributes/testcasesource.md
TestCaseSourceAttribute is used on a parameterized test method to identify the source from which the required
arguments will be provided. The attribute additionally identifies the method as a test method. The data is kept separate
from the test itself and may be used by multiple test methods. See Parameterized Tests for a
general introduction to tests with arguments.
Consider a test of the divide operation, taking three arguments: the numerator, the denominator and the expected result. We can specify the test and its data using one of the forms of TestCaseSourceAttribute:
[TestCaseSource(string sourceName)][!NOTE] We use the
nameofoperator to avoid introducing magic strings into code, which offers better resilience when refactoring. Whilenameofis recommended, you could also use the string "DivideCases" to achieve the same outcome.
[!code-csharpBasicTestCaseSource]
The single attribute argument in this form is a string representing the name of the source used to provide test cases. It has the following characteristics:
IEnumerable or a type that implements IEnumerable. For fields an array is generally used. For
properties and methods, you may return an array or implement your own iterator.
IAsyncEnumerable or a type that implements IAsyncEnumerable. (NUnit 4+)Task<T>. (NUnit 3.14+)Sometimes we would like to parameterize the source, e.g. if we use the same source for multiple tests, to this end it is possible to pass parameters to the source, if the source is a method. The parameters are specified as an array of parameters that are passed to the source method.
[!code-csharpParameterizedSource]
[TestCaseSource(Type sourceType, string sourceName)][!code-csharpClassMethodAsTestCaseSource]
The first argument of the attribute in this form is a Type representing the class that will provide the test cases.
The second argument is a string representing the name of the source used to provide test cases. It has the following characteristics:
IEnumerable or a type that implements IEnumerable. For fields an array is generally used. For
properties and methods, you may return an array or implement your own iterator.
IAsyncEnumerable or a type that implements IAsyncEnumerable. (NUnit 4+)Task<T>. (NUnit 3.14+)Similar to Form 1 it is possible to pass parameters to the source, if the source is a method.
[TestCaseSource(Type sourceType)][!code-csharpClassWithoutMethodAsTestCaseSource]
The Type argument in this form represents the class that provides test cases. It must have a default constructor and
implement IEnumerable. The enumerator should return test case data compatible with the signature of the test on which
the attribute appears. See the Test Case Construction section below for details.
Note that it is not possible to pass parameters to the source, even if the source is a method.
As of NUnit 3.12, it is possible to use a typed source with an expected result. This is done by using the
TestCaseSource attribute on a method that returns a TestCaseData object. The TestCaseData object can be
constructed with the expected result as a parameter.
[!code-csharpTypedSourceWithExpectedResult]
See TestCaseData for more information on the TestCaseData class.
As of NUnit 4.1, it is possible to explicitly specify the generic types to be used for a generic method. This
may be useful when any of the test case arguments differ from the desired generic types. When omitted, NUnit will
infer the generic type arguments based on the passed values from the TestCaseSource.
[!code-csharpTypedSourceWithExplicitGenericTypes]
See TestCaseData for more information on the TestCaseData class.
It may seem from the examples above that TestCaseSource can only be used with simple data types or the base Object type. This is not the case. TestCaseSource can be used with typed data and also including expected results, also without using TestCaseData.
In the example below the test method takes a single argument of a an anonymous tuple type with Person and an expected
value of type bool. It can of course be any type, if that makes sense for the test. The TestCaseSource method returns
an IEnumerable<> of the anonymous tuple type.
[!code-csharpTypedValuesWithExpectedAsAnonymousTuple]
It is also possible to use a generic wrapper (or any custom wrapper) for the testcase data and the expected result, as shown in the example below.
[!code-csharpTypedValuesWithExpectedInWrapperClass]
TestCaseSourceAttribute supports one named parameter:
In constructing tests, NUnit uses each item returned by the enumerator as follows:
TestCaseParameters class, its properties are used to provide the test case.
NUnit provides the TestCaseData type for this purpose.[!code-csharpSingleArgumentMatchingValueShorthand]
object[], its members are used to provide the arguments for the method. This is the approach taken in
the three first examples above.int[].IEnumerable and IEnumerator may be used but NUnit will actually deal with the underlying IEnumerator
in the current release.Individual test cases are executed in the order in which NUnit discovers them. This order does not follow the lexical order of the attributes and will often vary between different compilers or different versions of the CLR.
As a result, when TestCaseSourceAttribute appears multiple times on a method or when other data-providing attributes are used in combination with TestCaseSourceAttribute, the order of the test cases is undefined.
However, when a single TestCaseSourceAttribute is used by itself, the order of the tests follows exactly the order in which the test cases are returned from the source.
NUnit locates the test cases at the time the tests are loaded. It creates instances of each class used with the third form of the attribute and builds a list of tests to be executed. Each data source class is only created once at this time and is destroyed after all tests are loaded. By design, no communication is possible between the load and execution phases except through the tests that are created.