Skip to content

Instantly share code, notes, and snippets.

@Dkowald
Created May 24, 2012 22:13
Show Gist options
  • Save Dkowald/2784505 to your computer and use it in GitHub Desktop.
Save Dkowald/2784505 to your computer and use it in GitHub Desktop.
qunit + mstest; using simple in-proc webserver.
using System;
using System.IO;
using System.Net;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyApplication.Core.Tests
{
/// <summary>
/// Intergrate a qunit test with mstest.
/// </summary>
/// <remarks>
/// Expects javascript files to all be in <see cref="TestContext.DeploymentDirectory"/>\js
/// </remarks>
[TestClass]
[DeploymentItem("./js/", "js")]
public class JsTest
{
#region Const
public const int DefaultPort = 5054;
public const int DefaultTimeout_msec = 500;
#endregion
#region Ctor
/// <summary>
/// Create using custom <see cref="Port"/>, <see cref="Timeout"/>.
/// </summary>
public JsTest(int port, int timeout)
{ Port = port; TimeOut = timeout; }
/// <summary>
/// Create using <see cref="DefaultPort"/>, <see cref="DefaultTimeout_msec"/>.
/// </summary>
public JsTest()
: this(DefaultPort, DefaultTimeout_msec) { }
#endregion
#region Test Setup / teardown
public TestContext TestContext { get; set; }
/// <summary>
/// Start a <see cref="HttpListener"/> on the port.
/// </summary>
protected HttpListener Server;
[TestInitialize]
public void Initialize()
{
Server = new HttpListener();
Server.Prefixes.Add(String.Format("http://*:{0}/", Port));
Server.Start();
}
/// <summary>
/// Kill off the <see cref="HttpListener"/>.
/// </summary>
[TestCleanup]
public void Cleanup()
{
Server.Stop();
}
#endregion
#region Operations
/// <summary>
/// Blocking run the test; starts the test page, waits for results.
/// returns test error count.
/// </summary>
protected int JsTestErrors(string testName)
{
var waitForResponse = Server.BeginGetContext(null, null);
var testPage = TestContext.DeploymentDirectory + "\\js\\" + testName + ".htm";
//run the page.
var browser = System.Diagnostics.Process.Start(testPage);
browser.Dispose();
//block for result.
if (!waitForResponse.AsyncWaitHandle.WaitOne(TimeOut))
{
throw new TimeoutException("js tests took too long.");
}
var qunitHttpResult = Server.EndGetContext(waitForResponse);
var qunitResult = "";
using (var rd = new StreamReader(qunitHttpResult.Request.InputStream))
{
qunitResult = rd.ReadToEnd();
}
//get the data from the response.
var failures = qunitResult.Split('=')[1];
return Int32.Parse(failures);
}
/// <summary>
/// Update a generated jscript output to be tested.
/// </summary>
protected virtual void UpdateJSFile(string testName, string fileContent)
{
var filePath = TestContext.DeploymentDirectory + "\\js\\" + testName + ".js";
using (var wr = File.CreateText(filePath))
{
wr.Write(fileContent);
}
}
#endregion
#region Properties
public int Port { get; private set; }
public int TimeOut { get; private set; }
#endregion
}
}
/// <reference path="jquery.js" />
/// <reference path="qunit.js" />
//Config qunit to intergrate with a simple mstest, in-proc web-server.
//localhost port, must match port on the .net test.
function GetPort() { return 5054; }
//extend qunit, post result back to server, close window if alls good.
QUnit.done = function (data) {
var port = GetPort();
if (port == null) return;
$.post("http://localhost:"+GetPort()
, { failed: data.failed }
, function () {
//only keep open, if fail.
if (data.failed == 0) {
window.close();
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment