5

在我的几个项目中,我使用 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 中使用回调函数不是 while-loop 检查),以确保测试方法在测试完成后立即执行。

4

2 回答 2

5

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

  1. 通过NuGetSelenium WebDriver 包安装到项目中。

在此处输入图像描述

2.将首选驱动程序下载到您的项目中,添加到您的项目中并将“复制到输出目录”设置为“如果较新则复制”。对于这个示例,我使用 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 解决方案(源代码)。

点击这里下载

更新 1

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

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

在此处输入图像描述

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

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

QUnit.config.autostart = false;

2.下载适用于 Windows 的 PhantomJS 可执行文件,添加到您的项目中并将“复制到输出目录”设置为“如果较新则复制”。

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 测试项目

这个项目演示了如何在 MSTest 中运行 PhantomJS。

PhantomJS 表单项目

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

在此处输入图像描述

于 2013-01-09T12:42:36.743 回答