コード例 #1
0
        // async test runner, called once for each test container/file
        private async Task RunTestFileAsync(IRunContext runContext, VsHttpServer listener, string issConfig, string testFilename, IEnumerable <TestCase> selectedTests, IFrameworkHandle frameworkHandle)
        {
            Log($"Entered RunTestFileAsync(), testFilename={testFilename}");

            // TODO: perhaps add wwwroot path in .runsettings file?
            string wwwRoot          = GetParentProjectFolder(testFilename).Replace('\\', '/');
            string relativeFilePath = testFilename.Substring(wwwRoot.Length).Replace('\\', '/');

            // get start time
            var startTime = DateTime.Now;

            // start browser & run the tests, then get the results back from browser
            var browser = new Browser(runContext, wwwRoot, relativeFilePath);
            await browser.LaunchAsync().ConfigureAwait(false);

            List <TsTestResult> testFileResults = await GetBrowserResultsAsync(listener).ConfigureAwait(false);

            // calculate total time to run tests + get results, and also the average time of each test
            //browserResults.TestStartTime = startTime;
            //browserResults.TestEndTime = DateTime.Now;
            //int numTests = (from test in tests where test.Source == testFilename select test).Count();
            //browserResults.Duration = new TimeSpan((browserResults.TestEndTime - browserResults.TestStartTime).Ticks / numTests);

            // process and return test results back to Visual Studio
            ProcessTestFileResults(testFilename, testFileResults, selectedTests, frameworkHandle);

            // close the headless browser
            Log($"RunTestsAsync(): Attempting to close browser...");
            await browser.CloseAsync().ConfigureAwait(false);

            Log($"RunTestsAsync(): ...browser closed");
        }
コード例 #2
0
        private async Task <List <TsTestResult> > GetBrowserResultsAsync(VsHttpServer listener)
        {
            //Debugger.Break();

            // receive results from chrome via http PUT
            Log("GetBrowserResultsAsync(): awaiting browser response...");
            string json = await listener.GetResponseFromBrowserAsync().ConfigureAwait(false);

            Log("GetBrowserResultsAsync(): ...json response received");
            Log($"json = {json}");

            // deserialise json test results
            Log("GetBrowserResultsAsync(): about to deserialise...");
            List <TsTestResult> browserResults = new List <TsTestResult>();

            try
            {
                browserResults = Json.Deserialize <List <TsTestResult> >(json);
                Log("GetBrowserResultsAsync(): ...json deserialised");
            }
            catch (Exception ex)
            {
                Log($"GetBrowserResultsAsync(): ...json deserialisation {ex.GetType().Name} thrown: {ex.Message}");
            }

            return(browserResults);
        }
コード例 #3
0
        // called by VS when user wants to run selection of tests
        public void RunTests(IEnumerable <TestCase> selectedTests, IRunContext runContext, IFrameworkHandle frameworkHandle)
        {
            try
            {
                Log("RunTests(IEnumerable<TestCase> ...) called");

                // because multiple tests may be within the same source file, or scattered across several, we need to
                // optimise things so that we only fire up the browser once for each separate test container file found

                // switch to C# 8.0/VS2019 and use using shorthand syntax: var listener = new VsHttpServer(8638); (no trailing braces required)
                _cancelled = false;
                using (var listener = new VsHttpServer(8638))                 // ensure the listener is started first
                {
                    // get list of distinct filenames for requested tests
                    IEnumerable <string> testFilenames = (from TestCase test in selectedTests select test.Source).Distinct();

                    // find IIS config file for parent solution of tests, for now assume tests are all in single solution (this will need to be changed)
                    string iisConfig = GetIISConfigFile(testFilenames.First());

                    // launch IIS Express (if not already running)
                    Browser.LaunchIISExpress(iisConfig);

                    // Launch all tests asynchronously (should really limit concurrency with a SemaphoreSlim to 16 browsers or so in case someone has 50+ test containers).
                    // Unless there are a large number of long-running tests, it will be faster to use a single browser and fire all the test files at it sequentially
                    // (browser startup and process exit takes a long time, ~6 seconds, executing a page of tests is likely to be < 50-100ms)
                    var tasks = testFilenames.Select(filename => RunTestFileAsync(runContext, listener, iisConfig, filename, selectedTests, frameworkHandle));

                    // and then thunk back to synchronous world using blocking wait-for-all
                    // we need to block here to ensure all the browsers that were started have been closed
                    Task.WhenAll(tasks).GetAwaiter().GetResult();

                    Log("RunTests(IEnumerable<TestCase> ...) all tasks completed");
                }
            }
            catch (Exception ex)
            {
                string errMsg = $"RunTests(IEnumerable<TestCase> ...): Exception thrown , exception={ex.ToString()}";
                Log(errMsg);
                Console.Error.WriteLine(errMsg);
            }
        }