Test
The Test abstract class represents a test within the framework.
            
                using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Internal
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    public abstract class Test : ITest, IXmlNodeBuilder, IComparable, IComparable<Test>
    {
        private static int _nextID = 1000;
        [System.Runtime.CompilerServices.Nullable(2)]
        private ITypeInfo _declaringTypeInfo;
        [System.Runtime.CompilerServices.Nullable(2)]
        private IMethodInfo _method;
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            2,
            1
        })]
        private ITestAction[] _actions;
        public string Id { get; set; }
        public string Name { get; set; }
        public string FullName { get; set; }
        [System.Runtime.CompilerServices.Nullable(2)]
        public string ClassName {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get {
                ITypeInfo typeInfo = TypeInfo;
                if (Method != null) {
                    if (_declaringTypeInfo == null)
                        _declaringTypeInfo = new TypeWrapper(Method.MethodInfo.DeclaringType);
                    typeInfo = _declaringTypeInfo;
                }
                if (typeInfo == null)
                    return null;
                if (!typeInfo.IsGenericType)
                    return typeInfo.FullName;
                return typeInfo.GetGenericTypeDefinition().FullName;
            }
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        public virtual string MethodName {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get {
                return null;
            }
        }
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            2
        })]
        public abstract object[] Arguments {
            [return: System.Runtime.CompilerServices.Nullable(new byte[] {
                1,
                2
            })]
            get;
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        [field: System.Runtime.CompilerServices.Nullable(2)]
        public ITypeInfo TypeInfo {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get;
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        public IMethodInfo Method {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get {
                return _method;
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            set {
                _declaringTypeInfo = null;
                _method = value;
            }
        }
        public RunState RunState { get; set; }
        public abstract string XmlElementName { get; }
        public virtual string TestType => GetType().Name;
        public virtual int TestCaseCount => 1;
        public IPropertyBag Properties { get; }
        public bool IsSuite => this is TestSuite;
        public abstract bool HasChildren { get; }
        [System.Runtime.CompilerServices.Nullable(2)]
        [field: System.Runtime.CompilerServices.Nullable(2)]
        public ITest Parent {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get;
            [System.Runtime.CompilerServices.NullableContext(2)]
            set;
        }
        public abstract IList<ITest> Tests { get; }
        [System.Runtime.CompilerServices.Nullable(2)]
        [field: System.Runtime.CompilerServices.Nullable(2)]
        public virtual object Fixture {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get;
            [System.Runtime.CompilerServices.NullableContext(2)]
            set;
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        [field: System.Runtime.CompilerServices.Nullable(2)]
        public static string IdPrefix {
            [System.Runtime.CompilerServices.NullableContext(2)]
            get;
            [System.Runtime.CompilerServices.NullableContext(2)]
            set;
        }
        public int Seed { get; set; }
        public IMethodInfo[] SetUpMethods { get; set; }
        public IMethodInfo[] TearDownMethods { get; set; }
        internal bool RequiresThread { get; set; }
        internal ITestAction[] Actions {
            get {
                if (_actions == null) {
                    if (Method == null && TypeInfo != null)
                        _actions = TestMetadataCache.Get(TypeInfo.Type).TestActionAttributes;
                    else if (Method != null) {
                        _actions = MethodInfoCache.Get(Method).TestActionAttributes;
                    } else {
                        _actions = GetCustomAttributes<ITestAction>(false);
                    }
                }
                return _actions;
            }
        }
        protected Test(string name)
            : this(null, name, null, null)
        {
        }
        protected Test([System.Runtime.CompilerServices.Nullable(2)] string pathName, string name)
            : this(pathName, name, null, null)
        {
        }
        protected Test(ITypeInfo typeInfo)
            : this(typeInfo.Namespace, typeInfo.GetDisplayName(), typeInfo, null)
        {
        }
        protected Test(IMethodInfo method)
            : this(method.TypeInfo.FullName, method.Name, method.TypeInfo, method)
        {
        }
        [System.Runtime.CompilerServices.NullableContext(2)]
        private Test(string pathName, [System.Runtime.CompilerServices.Nullable(1)] string name, ITypeInfo typeInfo, IMethodInfo method)
        {
            Guard.ArgumentNotNullOrEmpty(name, "name");
            Id = GetNextId();
            Name = name;
            FullName = ((!string.IsNullOrEmpty(pathName)) ? (pathName + "." + name) : name);
            TypeInfo = typeInfo;
            Method = method;
            Properties = new PropertyBag();
            RunState = RunState.Runnable;
            SetUpMethods = Array.Empty<IMethodInfo>();
            TearDownMethods = Array.Empty<IMethodInfo>();
        }
        private static string GetNextId()
        {
            return IdPrefix + _nextID++.ToString();
        }
        public abstract TestResult MakeTestResult();
        public void ApplyAttributesToTest(ICustomAttributeProvider provider)
        {
            ApplyAttributesToTest(provider.RetrieveAndTranslate());
        }
        public void ApplyAttributesToTest(Type type)
        {
            foreach (Type item in GetNestedTypes(type).Reverse()) {
                ApplyAttributesToTest((ICustomAttributeProvider)item);
            }
        }
        private void ApplyAttributesToTest(IEnumerable<IApplyToTest> attributes)
        {
            foreach (IApplyToTest attribute in attributes) {
                attribute.ApplyToTest(this);
            }
        }
        public void MakeInvalid(string reason)
        {
            Guard.ArgumentNotNullOrEmpty(reason, "reason");
            RunState = RunState.NotRunnable;
            Properties.Add("_SKIPREASON", reason);
        }
        public void MakeInvalid(Exception exception, string reason)
        {
            Guard.ArgumentNotNull(exception, "exception");
            Guard.ArgumentNotNullOrEmpty(reason, "reason");
            MakeInvalid(reason + Environment.NewLine + ExceptionHelper.BuildMessage(exception, false));
            Properties.Add("_PROVIDERSTACKTRACE", ExceptionHelper.BuildStackTrace(exception));
        }
        public virtual TAttr[] GetCustomAttributes<TAttr>(bool inherit) where TAttr : class
        {
            if (Method != null)
                return Method.GetCustomAttributes<TAttr>(inherit);
            if (TypeInfo != null)
                return TypeInfo.GetCustomAttributes<TAttr>(inherit);
            return Array.Empty<TAttr>();
        }
        protected void PopulateTestNode(TNode thisNode, bool recursive)
        {
            thisNode.AddAttribute("id", Id);
            thisNode.AddAttribute("name", Name);
            thisNode.AddAttribute("fullname", FullName);
            if (MethodName != null)
                thisNode.AddAttribute("methodname", MethodName);
            if (ClassName != null)
                thisNode.AddAttribute("classname", ClassName);
            thisNode.AddAttribute("runstate", RunState.ToString());
            if (Properties.Keys.Count > 0)
                Properties.AddToXml(thisNode, recursive);
        }
        protected IEnumerable<Type> GetNestedTypes(Type inner)
        {
            Type current = inner;
            while ((object)current != null) {
                yield return current;
                current = current.DeclaringType;
            }
        }
        public TNode ToXml(bool recursive)
        {
            return AddToXml(new TNode("dummy"), recursive);
        }
        public abstract TNode AddToXml(TNode parentNode, bool recursive);
        [System.Runtime.CompilerServices.NullableContext(2)]
        public int CompareTo(object obj)
        {
            return CompareTo(obj as Test);
        }
        [System.Runtime.CompilerServices.NullableContext(2)]
        public int CompareTo(Test other)
        {
            if (other != null)
                return FullName.CompareTo(other.FullName);
            return -1;
        }
    }
}