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

时间:2013-01-01 08:06:03

标签: c# javascript selenium phantomjs qunit

在我的几个项目中,我使用MVC模式将代码(关注点)分成3层。 Model和Control层都在C#上运行,所以我使用像MSTest或NUnit这样的测试框架来验证这些层的功能需求。对于View层,我使用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)中使用回调函数,以确保测试完成后立即执行测试方法。

2 个答案:

答案 0 :(得分:5)

对于跨浏览器测试,Selenium WebDriver是解决此问题的最佳选择,因为我们可以通过仅更改一行代码轻松切换浏览器。

  1. 通过Selenium WebDriver package安装NuGet到项目。
  2. enter image description here

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

    enter image description here

    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 :(得分:2)

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

enter image description here

我建议您在测试某些JavaScript库时不要在测试计算机上使用已安装的浏览器时使用此框架。

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

QUnit.config.autostart = false;

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

3.创建具有2个参数的PhantomJS.exe进程,这些参数是JavaScript文件和经过测试的页面网址。

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 Form编写的PhantomJS包装器。我在测试项目中使用它之前用它来测试“main.js”和“core.js”文件。

enter image description here