mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-11 18:54:31 +00:00
revel/revel#1057 code improvements docs, errcheck, cyclo, etc
This commit is contained in:
251
revel/test.go
251
revel/test.go
@@ -1,3 +1,7 @@
|
||||
// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
|
||||
// Revel Framework source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -52,7 +56,7 @@ func testApp(args []string) {
|
||||
errorf("No import path given.\nRun 'revel help test' for usage.\n")
|
||||
}
|
||||
|
||||
mode := "dev"
|
||||
mode := DefaultRunMode
|
||||
if len(args) >= 2 {
|
||||
mode = args[1]
|
||||
}
|
||||
@@ -61,22 +65,7 @@ func testApp(args []string) {
|
||||
revel.Init(mode, args[0], "")
|
||||
|
||||
// Ensure that the testrunner is loaded in this mode.
|
||||
testRunnerFound := false
|
||||
for _, module := range revel.Modules {
|
||||
if module.ImportPath == revel.Config.StringDefault("module.testrunner", "github.com/revel/modules/testrunner") {
|
||||
testRunnerFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !testRunnerFound {
|
||||
errorf(`Error: The testrunner module is not running.
|
||||
|
||||
You can add it to a run mode configuration with the following line:
|
||||
|
||||
module.testrunner = github.com/revel/modules/testrunner
|
||||
|
||||
`)
|
||||
}
|
||||
checkTestRunner()
|
||||
|
||||
// Create a directory to hold the test result files.
|
||||
resultPath := filepath.Join(revel.BasePath, "test-results")
|
||||
@@ -108,109 +97,27 @@ You can add it to a run mode configuration with the following line:
|
||||
defer cmd.Kill()
|
||||
revel.INFO.Printf("Testing %s (%s) in %s mode\n", revel.AppName, revel.ImportPath, mode)
|
||||
|
||||
// Get a list of tests.
|
||||
// Since this is the first request to the server, retry/sleep a couple times
|
||||
// in case it hasn't finished starting up yet.
|
||||
var (
|
||||
testSuites []controllers.TestSuiteDesc
|
||||
resp *http.Response
|
||||
baseUrl = fmt.Sprintf("http://127.0.0.1:%d", revel.HTTPPort)
|
||||
)
|
||||
for i := 0; ; i++ {
|
||||
if resp, err = http.Get(baseUrl + "/@tests.list"); err == nil {
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i < 3 {
|
||||
time.Sleep(3 * time.Second)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errorf("Failed to request test list: %s", err)
|
||||
} else {
|
||||
errorf("Failed to request test list: non-200 response")
|
||||
}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
json.NewDecoder(resp.Body).Decode(&testSuites)
|
||||
// Get a list of tests
|
||||
var baseURL = fmt.Sprintf("http://127.0.0.1:%d", revel.HTTPPort)
|
||||
testSuites, _ := getTestsList(baseURL)
|
||||
|
||||
// If a specific TestSuite[.Method] is specified, only run that suite/test
|
||||
if len(args) == 3 {
|
||||
testSuites = filterTestSuites(testSuites, args[2])
|
||||
}
|
||||
fmt.Printf("\n%d test suite%s to run.\n", len(testSuites), pluralize(len(testSuites), "", "s"))
|
||||
testSuiteCount := len(*testSuites)
|
||||
fmt.Printf("\n%d test suite%s to run.\n", testSuiteCount, pluralize(testSuiteCount, "", "s"))
|
||||
fmt.Println()
|
||||
|
||||
// Load the result template, which we execute for each suite.
|
||||
module, _ := revel.ModuleByName("testrunner")
|
||||
TemplateLoader := revel.NewTemplateLoader([]string{filepath.Join(module.Path, "app", "views")})
|
||||
if err := TemplateLoader.Refresh(); err != nil {
|
||||
errorf("Failed to compile templates: %s", err)
|
||||
}
|
||||
resultTemplate, err := TemplateLoader.Template("TestRunner/SuiteResult.html")
|
||||
if err != nil {
|
||||
errorf("Failed to load suite result template: %s", err)
|
||||
}
|
||||
|
||||
// Run each suite.
|
||||
var (
|
||||
overallSuccess = true
|
||||
failedResults []controllers.TestSuiteResult
|
||||
)
|
||||
for _, suite := range testSuites {
|
||||
// Print the name of the suite we're running.
|
||||
name := suite.Name
|
||||
if len(name) > 22 {
|
||||
name = name[:19] + "..."
|
||||
}
|
||||
fmt.Printf("%-22s", name)
|
||||
|
||||
// Run every test.
|
||||
startTime := time.Now()
|
||||
suiteResult := controllers.TestSuiteResult{Name: suite.Name, Passed: true}
|
||||
for _, test := range suite.Tests {
|
||||
testUrl := baseUrl + "/@tests/" + suite.Name + "/" + test.Name
|
||||
resp, err := http.Get(testUrl)
|
||||
if err != nil {
|
||||
errorf("Failed to fetch test result at url %s: %s", testUrl, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var testResult controllers.TestResult
|
||||
json.NewDecoder(resp.Body).Decode(&testResult)
|
||||
if !testResult.Passed {
|
||||
suiteResult.Passed = false
|
||||
}
|
||||
suiteResult.Results = append(suiteResult.Results, testResult)
|
||||
}
|
||||
overallSuccess = overallSuccess && suiteResult.Passed
|
||||
|
||||
// Print result. (Just PASSED or FAILED, and the time taken)
|
||||
suiteResultStr, suiteAlert := "PASSED", ""
|
||||
if !suiteResult.Passed {
|
||||
suiteResultStr, suiteAlert = "FAILED", "!"
|
||||
failedResults = append(failedResults, suiteResult)
|
||||
}
|
||||
fmt.Printf("%8s%3s%6ds\n", suiteResultStr, suiteAlert, int(time.Since(startTime).Seconds()))
|
||||
// Create the result HTML file.
|
||||
suiteResultFilename := filepath.Join(resultPath,
|
||||
fmt.Sprintf("%s.%s.html", suite.Name, strings.ToLower(suiteResultStr)))
|
||||
suiteResultFile, err := os.Create(suiteResultFilename)
|
||||
if err != nil {
|
||||
errorf("Failed to create result file %s: %s", suiteResultFilename, err)
|
||||
}
|
||||
if err = resultTemplate.Render(suiteResultFile, suiteResult); err != nil {
|
||||
errorf("Failed to render result template: %s", err)
|
||||
}
|
||||
}
|
||||
failedResults, overallSuccess := runTestSuites(baseURL, resultPath, testSuites)
|
||||
|
||||
fmt.Println()
|
||||
if overallSuccess {
|
||||
writeResultFile(resultPath, "result.passed", "passed")
|
||||
fmt.Println("All Tests Passed.")
|
||||
} else {
|
||||
for _, failedResult := range failedResults {
|
||||
for _, failedResult := range *failedResults {
|
||||
fmt.Printf("Failures:\n")
|
||||
for _, result := range failedResult.Results {
|
||||
if !result.Passed {
|
||||
@@ -239,7 +146,7 @@ func pluralize(num int, singular, plural string) string {
|
||||
|
||||
// Filters test suites and individual tests to match
|
||||
// the parsed command line parameter
|
||||
func filterTestSuites(suites []controllers.TestSuiteDesc, suiteArgument string) []controllers.TestSuiteDesc {
|
||||
func filterTestSuites(suites *[]controllers.TestSuiteDesc, suiteArgument string) *[]controllers.TestSuiteDesc {
|
||||
var suiteName, testName string
|
||||
argArray := strings.Split(suiteArgument, ".")
|
||||
suiteName = argArray[0]
|
||||
@@ -249,20 +156,20 @@ func filterTestSuites(suites []controllers.TestSuiteDesc, suiteArgument string)
|
||||
if len(argArray) == 2 {
|
||||
testName = argArray[1]
|
||||
}
|
||||
for _, suite := range suites {
|
||||
for _, suite := range *suites {
|
||||
if suite.Name != suiteName {
|
||||
continue
|
||||
}
|
||||
if testName == "" {
|
||||
return []controllers.TestSuiteDesc{suite}
|
||||
return &[]controllers.TestSuiteDesc{suite}
|
||||
}
|
||||
// Only run a particular test in a suite
|
||||
for _, test := range suite.Tests {
|
||||
if test.Name != testName {
|
||||
continue
|
||||
}
|
||||
return []controllers.TestSuiteDesc{
|
||||
controllers.TestSuiteDesc{
|
||||
return &[]controllers.TestSuiteDesc{
|
||||
{
|
||||
Name: suite.Name,
|
||||
Tests: []controllers.TestDesc{test},
|
||||
},
|
||||
@@ -273,3 +180,125 @@ func filterTestSuites(suites []controllers.TestSuiteDesc, suiteArgument string)
|
||||
errorf("Couldn't find test suite %s", suiteName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkTestRunner() {
|
||||
testRunnerFound := false
|
||||
for _, module := range revel.Modules {
|
||||
if module.ImportPath == revel.Config.StringDefault("module.testrunner", "github.com/revel/modules/testrunner") {
|
||||
testRunnerFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !testRunnerFound {
|
||||
errorf(`Error: The testrunner module is not running.
|
||||
|
||||
You can add it to a run mode configuration with the following line:
|
||||
|
||||
module.testrunner = github.com/revel/modules/testrunner
|
||||
|
||||
`)
|
||||
}
|
||||
}
|
||||
|
||||
// Get a list of tests from server.
|
||||
// Since this is the first request to the server, retry/sleep a couple times
|
||||
// in case it hasn't finished starting up yet.
|
||||
func getTestsList(baseURL string) (*[]controllers.TestSuiteDesc, error) {
|
||||
var (
|
||||
err error
|
||||
resp *http.Response
|
||||
testSuites []controllers.TestSuiteDesc
|
||||
)
|
||||
for i := 0; ; i++ {
|
||||
if resp, err = http.Get(baseURL + "/@tests.list"); err == nil {
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i < 3 {
|
||||
time.Sleep(3 * time.Second)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errorf("Failed to request test list: %s", err)
|
||||
} else {
|
||||
errorf("Failed to request test list: non-200 response")
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&testSuites)
|
||||
|
||||
return &testSuites, err
|
||||
}
|
||||
|
||||
func runTestSuites(baseURL, resultPath string, testSuites *[]controllers.TestSuiteDesc) (*[]controllers.TestSuiteResult, bool) {
|
||||
// Load the result template, which we execute for each suite.
|
||||
module, _ := revel.ModuleByName("testrunner")
|
||||
TemplateLoader := revel.NewTemplateLoader([]string{filepath.Join(module.Path, "app", "views")})
|
||||
if err := TemplateLoader.Refresh(); err != nil {
|
||||
errorf("Failed to compile templates: %s", err)
|
||||
}
|
||||
resultTemplate, err := TemplateLoader.Template("TestRunner/SuiteResult.html")
|
||||
if err != nil {
|
||||
errorf("Failed to load suite result template: %s", err)
|
||||
}
|
||||
|
||||
var (
|
||||
overallSuccess = true
|
||||
failedResults []controllers.TestSuiteResult
|
||||
)
|
||||
for _, suite := range *testSuites {
|
||||
// Print the name of the suite we're running.
|
||||
name := suite.Name
|
||||
if len(name) > 22 {
|
||||
name = name[:19] + "..."
|
||||
}
|
||||
fmt.Printf("%-22s", name)
|
||||
|
||||
// Run every test.
|
||||
startTime := time.Now()
|
||||
suiteResult := controllers.TestSuiteResult{Name: suite.Name, Passed: true}
|
||||
for _, test := range suite.Tests {
|
||||
testURL := baseURL + "/@tests/" + suite.Name + "/" + test.Name
|
||||
resp, err := http.Get(testURL)
|
||||
if err != nil {
|
||||
errorf("Failed to fetch test result at url %s: %s", testURL, err)
|
||||
}
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
|
||||
var testResult controllers.TestResult
|
||||
err = json.NewDecoder(resp.Body).Decode(&testResult)
|
||||
if err == nil && !testResult.Passed {
|
||||
suiteResult.Passed = false
|
||||
}
|
||||
suiteResult.Results = append(suiteResult.Results, testResult)
|
||||
}
|
||||
overallSuccess = overallSuccess && suiteResult.Passed
|
||||
|
||||
// Print result. (Just PASSED or FAILED, and the time taken)
|
||||
suiteResultStr, suiteAlert := "PASSED", ""
|
||||
if !suiteResult.Passed {
|
||||
suiteResultStr, suiteAlert = "FAILED", "!"
|
||||
failedResults = append(failedResults, suiteResult)
|
||||
}
|
||||
fmt.Printf("%8s%3s%6ds\n", suiteResultStr, suiteAlert, int(time.Since(startTime).Seconds()))
|
||||
// Create the result HTML file.
|
||||
suiteResultFilename := filepath.Join(resultPath,
|
||||
fmt.Sprintf("%s.%s.html", suite.Name, strings.ToLower(suiteResultStr)))
|
||||
suiteResultFile, err := os.Create(suiteResultFilename)
|
||||
if err != nil {
|
||||
errorf("Failed to create result file %s: %s", suiteResultFilename, err)
|
||||
}
|
||||
if err = resultTemplate.Render(suiteResultFile, suiteResult); err != nil {
|
||||
errorf("Failed to render result template: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &failedResults, overallSuccess
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user