ChromiumWebBrowser Offscreen does not work with MsTest/NUnit

1.9k Views Asked by At

I'm trying to use ChromiumWebBrowser from MsTest unit test framework in OffScreen mode to provide some testing... But Chromium constructor crashes all the time and I can't do anything with it.

I've alreade left comments in similar threads on github:

Issue #1

Isuee #2

Also I've tried to find help on gitter channel. I've created MsTest project and added simple method where Chromium is used:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CefSharp;
using CefSharp.OffScreen;
using System.Threading;

namespace ChromTests
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            ChromiumWebBrowser browser = null;

            // Create the offscreen Chromium browser.
            using (browser = new ChromiumWebBrowser("http://google.com")) 
            {

            }

            Cef.Shutdown();
        }
    }
}

My solution structure:

My solution structure

My testsettings file (deploys all dependencies into working dir for test engine "TestResults...\Out folder"):

<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Release" id="88aeb968-8fa1-409d-95e4-4d1cb52532e2" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
  <Description>These are default test settings for a local test run.</Description>
  <Deployment>
    <DeploymentItem filename="bin\x64\Release\natives_blob.bin" />
    <DeploymentItem filename="bin\x64\Release\libcef.dll" />
    <DeploymentItem filename="bin\x64\Release\cef.pak" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.OffScreen.xml" />
    <DeploymentItem filename="bin\x64\Release\cef_200_percent.pak" />
    <DeploymentItem filename="bin\x64\Release\cef_100_percent.pak" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.dll" />
    <DeploymentItem filename="bin\x64\Release\cef_extensions.pak" />
    <DeploymentItem filename="bin\x64\Release\widevinecdmadapter.dll" />
    <DeploymentItem filename="bin\x64\Release\snapshot_blob.bin" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.BrowserSubprocess.Core.pdb" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.OffScreen.dll" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.xml" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.BrowserSubprocess.exe" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.Core.dll" />
    <DeploymentItem filename="bin\x64\Release\devtools_resources.pak" />
    <DeploymentItem filename="bin\x64\Release\libEGL.dll" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.BrowserSubprocess.Core.dll" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.pdb" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.Core.pdb" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.BrowserSubprocess.pdb" />
    <DeploymentItem filename="bin\x64\Release\icudtl.dat" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.Core.xml" />
    <DeploymentItem filename="bin\x64\Release\d3dcompiler_47.dll" />
    <DeploymentItem filename="bin\x64\Release\chrome_elf.dll" />
    <DeploymentItem filename="bin\x64\Release\libGLESv2.dll" />
    <DeploymentItem filename="bin\x64\Release\CefSharp.OffScreen.pdb" />
    <DeploymentItem filename="bin\x64\Release\locales\kn.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ml.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\lt.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\et.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\da.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\cs.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\sk.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\he.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\id.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\sl.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\fr.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\lv.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\de.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\tr.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\fa.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\zh-TW.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\hr.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ar.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\pt-BR.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\nl.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\vi.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\gu.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\hu.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ta.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\fi.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ms.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\sr.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\en-US.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\el.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\zh-CN.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\en-GB.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\pl.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\es.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\th.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\bg.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\pt-PT.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\it.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\te.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\fil.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\bn.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ro.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\sw.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\hi.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\nb.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ca.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\sv.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\uk.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ko.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\mr.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ja.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\es-419.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\am.pak" outputDirectory="locales\" />
    <DeploymentItem filename="bin\x64\Release\locales\ru.pak" outputDirectory="locales\" />
  </Deployment>
  <Execution hostProcessPlatform="MSIL">
    <TestTypeSpecific>
      <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b">
        <AssemblyResolution>
          <TestDirectory useLoadContext="true" />
        </AssemblyResolution>
      </UnitTestRunConfig>
    </TestTypeSpecific>
    <AgentRule name="Execution Agents">
    </AgentRule>
  </Execution>
  <Properties />
</TestSettings>

I run tests from Visual Studio Test Explorer and get such error: test engine crashes on test run

please help, need any support or ideas...

1

There are 1 best solutions below

0
On BEST ANSWER

Approach with mstest is possible, but it is not full enough. Maybe, it will help someone. Approach below is similar to NUnit described in: https://github.com/cefsharp/CefSharp/issues/700#issuecomment-297209620

Logic for testing maybe encapsulated in Console application and debugged easily. Test application maybe executed from console with the help of mstest.exe

MSTest.exe can run tests in same app domain as cefsharp process, but only in x86 mode.

Example of command:

>> ChromTests\bin\x86\Release>mstest.exe /testcontainer:chromtests.dll /testsettings:..\..\..\release.testsettings /noisolation
  • /testcontainer - test dll name
  • /testsettings - settings file, similar to one I've posted above
  • /noisolation - gives us possibility to run tests and cefsharp in the same app domain

There is tool for test running vstest.console.exe, and it also should run tests in no isolation mode by default, but it does not work. It has flag /inisolation, but it seems it is useless.

Here is example of approach I've described:

// Console app class for running Chromium:

using CefSharp;
using CefSharp.OffScreen;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;

namespace ConsoleWebChromiumSample
{
    public class ChromiumRunner
    {
        private ChromiumWebBrowser browser = null;

        public void RunChromiumDemo()
        {
            var settings = new CefSettings()
            {
                MultiThreadedMessageLoop = true
            };

            //Perform dependency check to make sure all relevant resources are in our output directory.
            Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

            // Create the offscreen Chromium browser.
            browser = new ChromiumWebBrowser("");
            browser.BrowserInitialized += BrowserInitialized;

            while (!browser.IsBrowserInitialized)
            {
                Thread.Sleep(100);
            }

            Cef.Shutdown();
        }

        private void BrowserInitialized(object sender, EventArgs e)
        {
            Assert.IsTrue(browser.IsBrowserInitialized);
            browser.BrowserInitialized -= BrowserInitialized;
        }
    }
}

Unit test project code:

using ConsoleWebChromiumSample;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ChromTests
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestChromiumDemo()
        {
            ChromiumRunner runner = new ChromiumRunner();
            runner.RunChromiumDemo();
        }
    }
}

Next step - add adapter for running this from Visual Studio. Example about how to : write a visual studio unit test adapter/