如何通过 JavaScript 回调在 C# 中运行 QUnit 测试并返回测试结果?

Posted

技术标签:

【中文标题】如何通过 JavaScript 回调在 C# 中运行 QUnit 测试并返回测试结果?【英文标题】:How to run QUnit test and get back test result in C# via JavaScript callback? 【发布时间】:2012-12-16 01:03:03 【问题描述】:

在我的几个项目中,我使用 MVC 模式将(关注点的)代码分成 3 层。模型层和控制层都在 C# 上运行,因此我使用 MSTest 或 NUnit 等测试框架来验证这些层的功能需求。对于视图层,我使用 QUnit 来测试 javascript 文件。

但是,我无法将 QUnit 作为自动化测试执行,因为 MSTest 不直接支持测试网页。我需要像下面的逻辑一样在 MSTest 中运行它。

[TestMethod]
public void JavaScriptTest()

    var result = QUnit.Test('~/QUnit/test1.htm');

    Assert.IsTrue(result.Failed <= 0)

解决方案必须使用 QUnit 中的回调函数 (not while-loop checking) 以确保测试方法在测试完成后立即执行。

【问题讨论】:

【参考方案1】:

对于跨浏览器测试,Selenium WebDriver是解决此问题的最佳选择,因为我们只需更改一行代码即可轻松地在浏览器之间切换。

    通过NuGet将Selenium WebDriver package安装到项目中。

2.Download preferred driver 到你的项目,添加到你的项目 并将“复制到输出目录”设置为“如果较新则复制”。为了这 例如,我使用 Chrome 驱动程序在 Google Chrome 上运行 Selenium 我的机器。

3.在测试方法中,在运行QUnit之前创建驱动并设置最大执行时间。

var browser = new ChromeDriver();
var navigator = browser.Navigate();

// Currently, max execution time is one minute.
browser.Manage().Timeouts()
       .SetScriptTimeout(new TimeSpan(0, 1, 0));

4.请确保您已经将 QUnit 的自动启动设置为 false。

QUnit.config.autostart = false;

5.导航到 QUnit 页面。在这种情况下,我在解决方案文件夹中使用本地网页。

 browser.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 1, 0));
navigator.GoToUrl(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"../../../QUnit example/qunit-demo.htm"));

6.在浏览器对象中使用ExecuteAsyncScript方法为QUnit.done函数注册回调并手动启动QUnit测试。

var response = browser.ExecuteAsyncScript
(
    "var callback = arguments[arguments.length - 1];" +
    "QUnit.done(callback); QUnit.start();"
);

7.当 QUnit 测试完成时,它会返回一个响应。我们需要将其转换为合适的类型并得到测试结果。

var testResult = response as Dictionary<string, object>;

if(testResult == null) throw new Exception("Unhandle error occur while running QUnit."); 

Console.WriteLine("Test complete in " + (long)testResult["runtime"] + " ms.");
Console.WriteLine("---------------------------");
Console.WriteLine("total: " + (long)testResult["total"]);
Console.WriteLine("passed: " + (long)testResult["passed"]);
Console.WriteLine("failed: " + (long)testResult["failed"]);

8.每次使用完成测试时不要忘记关闭浏览器。

browser.Close();

PS。我还为此答案提供了 Visual Studio 2012 解决方案(源代码)。

Click here to download

更新 1

修复了在系统注册回调到完成函数之前 QUnit 开始测试的错误。 包括本地 QUnit 页面。 包括 IEDriver 以下载解决方案。但是,此版本不支持 Windows 8 上的 IE10。但它在 IE8 上运行良好。

【讨论】:

#1 限制,无法从通常用于复杂系统的 JavaScript 捕获 console.log 输出。 #2 限制,最长执行异步脚本为一分钟。【参考方案2】:

PhantomJS 是一个带有 JavaScript API 的 headless WebKit。它对各种 Web 标准具有快速和原生的支持:DOM 处理、CSS 选择器、JSON、Canvas 和 SVG。它是完整的 Web 堆栈,是无头网站测试、屏幕捕获、页面自动化和网络监控的最佳解决方案。

当你想测试一些 JavaScript 库并且不想在测试机器上使用安装的浏览器时,我建议你使用这个框架。

1.请确保您已经将 QUnit 的自动启动设置为 false。

QUnit.config.autostart = false;

2.Download PhantomJS executable file 对于 Windows,添加到您的项目并将“复制到输出目录”设置为“如果较新则复制”。

3.创建运行 PhantomJS.exe 的进程,其中包含 2 个参数,即 JavaScript 文件和测试页面 url。

var scriptPath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../PhantomScript/main.js"));
var pageUrl = "file:///" + Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../QUnitExample/qunit-demo.htm")).Replace('\\', '/');

var process = new Process

    StartInfo =
    
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        WindowStyle = ProcessWindowStyle.Hidden,
        FileName = "phantomjs.exe",
        Arguments = "\"" + scriptPath + "\" \"" + pageUrl + "\""
    
;

4.启动进程并检查该进程的退出代码。

process.Start();
process.WaitForExit();

Assert.AreEqual(process.ExitCode, 0);

在 JavaScript 文件中,我使用 eveluateAsync 访问页面上下文以运行 QUnit 测试,等待它完成并且记录测试量失败。

page.evaluateAsync(function ()

    QUnit.done(function(response)
    
        console.log('!Exit' + response.failed);
    );

    QUnit.start();

    // If QUnit finish after 2500 ms, system will exit application with code -1.
    setTimeout(function()
    
        console.log('!Exit-1');
    , 2500);
);

为了处理日志,我使用以下代码通过退出代码退出进程。

var exitCodeName = '!Exit';
page.onConsoleMessage = function (msg)

    if (msg.indexOf(exitCodeName) == 0)
    
        var exitCode = parseInt(msg.substring(exitCodeName.length).trim(), 10);

        phantom.exit(exitCode || 0);
    
;

PS。我还为我的 SkyDrive 提供了完整的源代码 (VS2012)。您可以在以下链接下载。

PhantomJS Test project

本项目演示如何在 MSTest 中运行 PhantomJS。

PhantomJS Form project

这个项目是用 C# Windows 窗体编写的 PhantomJS 包装器。在测试项目中使用之前,我使用它来测试“main.js”和“core.js”文件。

【讨论】:

以上是关于如何通过 JavaScript 回调在 C# 中运行 QUnit 测试并返回测试结果?的主要内容,如果未能解决你的问题,请参考以下文章

委托在Smobiler自定义控件中运用

如何在猫鼬回调中读取查询?

如何在windows窗口中运用C#读取txt,并在窗口中显示出来

如何通过 C++-CLI 回调和委托将字符串从 C++-CLI 传递到 C#

如何通过 IntPtr 将 c++ 数组编组为 c#

c# 通过窗口名字关闭窗口