public static bool ReadTest(MethodInfo test, IFixtureData data, string workingDirectory)
        {
            List <string> modelPaths = new List <string>();

            var testAttribs = CustomAttributeData.GetCustomAttributes(test);

            if (testAttribs.Any(x => x.Constructor.DeclaringType.Name == nameof(IgnoreAttribute)))
            {
                return(false);
            }

            var testModelAttrib = testAttribs.FirstOrDefault(x => x.Constructor.DeclaringType.Name == nameof(TestModelAttribute));

            if (testModelAttrib != null)
            {
                string absolutePath;

                // We can't get the instantiated attribute from the assembly because we performed a ReflectionOnly load
                TestModelAttribute testModelAttribute = new TestModelAttribute((string)testModelAttrib.ConstructorArguments.First().Value);

                if (Path.IsPathRooted(testModelAttribute.Path))
                {
                    absolutePath = testModelAttribute.Path;
                }
                else
                {
                    if (workingDirectory == null)
                    {
                        // If the working directory is not specified.
                        // Add the relative path to the assembly's path.
                        absolutePath = Path.GetFullPath(
                            Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), testModelAttribute.Path));
                    }
                    else
                    {
                        absolutePath = Path.GetFullPath(Path.Combine(workingDirectory, testModelAttribute.Path));
                    }
                }

                if (testModelAttribute.IsWildcard)
                {
                    string[] modelFiles = null;
                    try
                    {
                        modelFiles = Directory.GetFiles(Path.GetDirectoryName(absolutePath), Path.GetFileName(absolutePath), SearchOption.AllDirectories);
                    }
                    catch
                    {
                        // Means folder doesn't exist
                    }

                    if (modelFiles == null || modelFiles.Length == 0)
                    {
                        modelFiles = new string[] { absolutePath };
                    }

                    modelPaths.AddRange(modelFiles);
                }
                else
                {
                    modelPaths.Add(absolutePath);
                }
            }
            else
            {
                //set the default modelPath to the empty.rfa file that will live in the build directory
                modelPaths.Add(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "empty.rfa"));
            }

            var runDynamoAttrib = testAttribs.FirstOrDefault(x => x.Constructor.DeclaringType.Name == nameof(RunDynamoAttribute));
            var runDynamo       = false;

            if (runDynamoAttrib != null)
            {
                runDynamo = (bool)runDynamoAttrib.ConstructorArguments.FirstOrDefault().Value;
            }

            foreach (string modelPath in modelPaths)
            {
                var testData = new TestData(data, test.Name, modelPath, runDynamo);
                data.Tests.Add(testData);

                const string EmptyCategory = "[NO CATEGORY]";

                var category        = string.Empty;
                var categoryAttribs =
                    testAttribs.Where(x => x.Constructor.DeclaringType.Name == nameof(CategoryAttribute));

                if (categoryAttribs.Any())
                {
                    foreach (var categoryAttrib in categoryAttribs)
                    {
                        category = categoryAttrib.ConstructorArguments.FirstOrDefault().Value.ToString();
                        if (String.IsNullOrEmpty(category))
                        {
                            category = EmptyCategory;
                        }

                        AddWithCategory(data, category, testData);
                    }
                }
                else
                {
                    AddWithCategory(data, EmptyCategory, testData);
                }

                Console.WriteLine($"Loaded test: {testData} ({modelPath})");
            }

            return(true);
        }
        public override IList<IAssemblyData> ReadAssembly(string assemblyPath, string workingDirectory,
            GroupingType groupType, bool isTesting)
        {
            var dummyTestPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                "RunnerTests.dll");
            var assData = new AssemblyData(dummyTestPath, "RunnerTests", groupType);

            var cat1 = new CategoryData(assData, "Smoke");
            var cat2 = new CategoryData(assData, "Integration");
            var cat3 = new CategoryData(assData, "Failure");
            assData.Categories = new ObservableCollection<ITestGroup>() { cat1, cat2, cat3 };

            var fix1 = new FixtureData(assData, "FixtureA");
            var fix2 = new FixtureData(assData, "FixtureB");
            assData.Fixtures = new ObservableCollection<ITestGroup>() { fix1, fix2 };

            var testModelPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                "empty.rfa");

            var test1 = new TestData(fix1, "TestA", testModelPath, false);
            var test2 = new TestData(fix1, "TestB", testModelPath, false);
            var test3 = new TestData(fix1, "TestC", testModelPath, false);
            var test4 = new TestData(fix2, "TestD", testModelPath, false);
            var test5 = new TestData(fix2, "TestE", @"C:\foo.rfa", false);

            cat1.Tests = new ObservableCollection<ITestData>() { test1, test2 };
            cat2.Tests = new ObservableCollection<ITestData>() { test3 };
            cat3.Tests = new ObservableCollection<ITestData>() { test4, test5 };

            fix1.Tests = new ObservableCollection<ITestData>() { test1, test2, test3 };
            fix2.Tests = new ObservableCollection<ITestData>() { test4, test5 };

            fix1.Assembly = assData;
            fix2.Assembly = assData;
            cat1.Assembly = assData;
            cat2.Assembly = assData;
            cat3.Assembly = assData;

            return new List<IAssemblyData>{assData};
        }
        public static bool ReadTest(MethodInfo test, IFixtureData data, string workingDirectory)
        {
            //set the default modelPath to the empty.rfa file that will live in the build directory
            string modelPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "empty.rfa");

            var testAttribs = CustomAttributeData.GetCustomAttributes(test);

            var testModelAttrib =
                testAttribs.FirstOrDefault(x => x.Constructor.DeclaringType.Name == "TestModelAttribute");

            if (testModelAttrib != null)
            {
                //overwrite the model path with the one
                //specified in the test model attribute
                var relModelPath = testModelAttrib.ConstructorArguments.FirstOrDefault().Value.ToString();
                modelPath = Path.GetFullPath(Path.Combine(workingDirectory, relModelPath));
            }

            var runDynamoAttrib =
                testAttribs.FirstOrDefault(x => x.Constructor.DeclaringType.Name == "RunDynamoAttribute");

            var runDynamo = false;
            if (runDynamoAttrib != null)
            {
                runDynamo = Boolean.Parse(runDynamoAttrib.ConstructorArguments.FirstOrDefault().Value.ToString());
            }

            var testData = new TestData(data, test.Name, modelPath, runDynamo);
            data.Tests.Add(testData);

            var category = string.Empty;
            var categoryAttribs =
                testAttribs.Where(x => x.Constructor.DeclaringType.Name == "CategoryAttribute");
            foreach (var categoryAttrib in categoryAttribs)
            {
                category = categoryAttrib.ConstructorArguments.FirstOrDefault().Value.ToString();
                if (!String.IsNullOrEmpty(category))
                {
                    var cat = data.Assembly.Categories.FirstOrDefault(x => x.Name == category);
                    if (cat != null)
                    {
                        cat.Tests.Add(testData);
                    }
                    else
                    {
                        var catData = new CategoryData(data.Assembly, category);
                        catData.Tests.Add(testData);
                        data.Assembly.Categories.Add(catData);
                    }
                }
            }

            return true;
        }