func (c TestRunner) Run(suite, test string) revel.Result {
	suiteIndex, ok := registeredTests[suite+"."+test]
	if !ok {
		return c.NotFound("Test %s.%s does not exist", suite, test)
	}
	result := TestResult{Name: test}
	t := testSuites[suiteIndex].Elem
	v := reflect.New(t)
	func() {
		defer func() {
			if err := recover(); err != nil {
				panicErr := revel.NewErrorFromPanic(err)
				if panicErr == nil {
					return
				}
				testSuite := v.Elem().FieldByName("TestSuite").Interface().(testing.TestSuite)
				res := formatResponse(testSuite)
				var buffer bytes.Buffer
				tmpl, _ := revel.MainTemplateLoader.TemplateLang("TestRunner/FailureDetail.html", "")
				_ = tmpl.Render(&buffer, map[string]interface{}{
					"error":    panicErr,
					"response": res,
					"postfix":  suite + "_" + test,
				})
				result.ErrorSummary = errorSummary(panicErr)
				result.ErrorHTML = template.HTML(buffer.String())
			}
		}()
		testSuiteInstance := v.Elem().FieldByName("TestSuite")
		testSuiteInstance.Set(reflect.ValueOf(testing.NewTestSuite()))
		if m := v.MethodByName("After"); m.IsValid() {
			defer m.Call(none)
		}
		if m := v.MethodByName("Before"); m.IsValid() {
			m.Call(none)
		}
		v.MethodByName(test).Call(none)
		result.Passed = true
	}()
	return c.RenderJSON(result)
}
Run runs a single test, given by the argument.
package controllers
import (
	"bytes"
	"encoding/json"
	"fmt"
	"html/template"
	"reflect"
	"sort"
	"strings"
	"github.com/revel/revel"
	"github.com/revel/revel/testing"
)
type TestRunner struct {
	*revel.Controller
}
type TestSuiteDesc struct {
	Name  string
	Tests []TestDesc
	Elem reflect.Type
}
type TestDesc struct {
	Name string
}
type TestSuiteResult struct {
	Name    string
	Passed  bool
	Results []TestResult
}
type TestResult struct {
	Name         string
	Passed       bool
	ErrorHTML    template.HTML
	ErrorSummary string
}
var (
	testSuites []TestSuiteDesc  
	none = []reflect.Value{}  
	registeredTests map[string]int
)
func (c TestRunner) Index() revel.Result {
	c.ViewArgs["suiteFound"] = len(testSuites) > 0
	return c.Render(testSuites)
}
func (c TestRunner) Suite(suite string) revel.Result {
	var foundTestSuites []TestSuiteDesc
	for _, testSuite := range testSuites {
		if strings.EqualFold(testSuite.Name, suite) {
			foundTestSuites = append(foundTestSuites, testSuite)
		}
	}
	c.ViewArgs["testSuites"] = foundTestSuites
	c.ViewArgs["suiteFound"] = len(foundTestSuites) > 0
	c.ViewArgs["suiteName"] = suite
	return c.RenderTemplate("TestRunner/Index.html")
}