mad

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 6, 2018 License: MIT Imports: 4 Imported by: 0

README

MadTitan

Inter galactic test runner and test framework for Go frontend projects.

The name madtitan originate from nickname of Thanos (comics character), he is obsessed with collecting infinity stones, this project is obsessed with collecting all the good parts of javascript testing eco system with the go ones to bring smooth developer experience for frontend works using the Go programming language.

warning I have actively tested this on darwin (os x), if you have issue with a different os open it here and probably someone else who uses your os might help.

Features

  • Fast
  • Combines good parts from the go testing package, karma,jest,jasmine etc
  • Write unit tests.
  • Write integration tests (vecty only), yep now you can test your vecty components.
  • Code coverage
  • Like thanos who aims to destroy half of the universe, we will destroy half of your frontend project's problems by ensuring it meets your expectations.

Supported browsers

Note that theoretically all browser's supporting the chrome debug protocol must work. Unfortunate I'm only interested in chrome so if you want to take a stab at testing with another browser you are welcome.

  • chrome
  • Add a browser

What is this? and why?

I have been interested in frontend web development using the Go programming language. One challenge that I faced was the way to test my code.

Things that I wanted in any test solution

  • Go 100% (yep I believe Go is much cooler that js)
  • must look familiar
  • must be fast
  • must run on the browser for tests that need access to the dom
  • must be friendly with go tool chain

This inspired me to build such tool.

Installing

We need both the library and the mad command

go get github.com/gernest/madtitan/cmd/mad

Getting started

Create a tests directory in the root of your go package. Then write test functions. There is no convention over the filenames, however the function names follow the convention of the testing package. So, test functions must be of the form TestXxxx and must return either mad.Test or mad.Integration.

Show me the code

 func TestRainfall() mad.Test {
	return mad.Describe("Raining",
		mad.It("must be cloudy", func(t mad.T) {
			ctx := Rainfall()
			if !ctx.Cloudy {
				t.Error("expected to be cloudy")
			}
		}),
	)
}

Running the tests

In the root of your package (where the tests directory is) execute

mad test
✔ TestBefore
✔ TestAfter
✔ TestRenderBody
 Passed :3 Failed:0

for verbose output

mad tes --v
starting websocket server at :1956
Waiting for chrome ...done
TestBefore:
  Before:
    ✔ be called before the testcase  1ms
TestAfter:
  After:
    ✔ should be called after the testcase  1ms
TestRenderBody:
  mad.RenderBody:
    ✔ must have text node  0s
 Passed :3 Failed:0

With code coverage

 mad test --cover
✔ TestRenderBody
✔ TestBefore
✔ TestAfter
 Passed :3 Failed:0
             github.com/gernest/mad 54.4%
 github.com/gernest/mad/integration 66.7%
          github.com/gernest/mad/ws 80.0%
                              Total 58.8%

I want to write unit tests

We got you covered Take a look at this page

I want to write integration tests

NOTE This only works with vecty projects

We got you covered Take a look at this page

FAQ

what is unit test ?

For mad , unit tests are tests which cover a small chunk of functionality. They must not include any use of code that requires rendering/interacting with the browser dom

what is integration test ?

For mad . Integration tests are tests which cover a component/components rendered on the dom.

Credits

This would have never been possible without these projects

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Skip

func Skip(message string)

Skip marks test suite as skipped

Types

type AfterFuncs

type AfterFuncs struct {
	Funcs []func()
}

AfterFuncs is like BeforeFuncs but executed after the test has run.

func (*AfterFuncs) Exec

func (b *AfterFuncs) Exec()

Exec like BeforeFuncs.Exec but executed after the test run.

type BeforeFuncs

type BeforeFuncs struct {
	Funcs []func()
}

BeforeFuncs contains functions that are supposed to be executed before a test.

func (*BeforeFuncs) Exec

func (b *BeforeFuncs) Exec()

Exec implements Test interface. When called this will iterate and call every function that is stored in the Funcs field. Iteration is done by the order in which the functions are added.

TODO: Have timeout to allow handling of long running functions. One option is to pass context.Context as the first argument of the functions.

type Component

type Component struct {
	ID        string
	Component func() interface{}
	IsBody    bool
	Cases     Test
}

type Error

type Error struct {
	Message error
	Pending bool
}

Error implements error interface. This is useful for taking care of interupts via panics.

func (*Error) Error

func (e *Error) Error() string

type ExpectResult

type ExpectResult struct {
	Desc     string        `json:"description"`
	Duration time.Duration `json:"duration"`
	Messages []string      `json:"error_messages"`
}

ExpectResult contains reults of executing expectation.

type Expectation

type Expectation struct {
	Parent       *Suite
	Desc         string
	Func         func(T)
	Passed       bool
	FailMessages []string
	Duration     time.Duration
}

Expectation contains the main test function that checks expectations. If the main function after execution happens not to call any method of the passed T object then the test has passed.

func (*Expectation) Exec

func (e *Expectation) Exec()

Exec runs the test function and records the result.

TODO: add timeout.

func (*Expectation) Result

func (e *Expectation) Result() *ExpectResult

Result returns *ExpectResult from executing the expectation.

type Integration

type Integration interface {
	// contains filtered or unexported methods
}

Integration is an interface for integration tests.

func Render

func Render(desc string, c func() interface{}, cases ...Test) Integration

Render returns an integration test for non body Components. Use this to test Components that renders spans,div etc.

NOTE: func()interface{} was supposed to be func()vecty.ComponentOrHTML this is a workaround, because importing vecty in this package will make it impossible to run the commandline tools since vecty only works with the browser.

func RenderBody

func RenderBody(desc string, c func() interface{}, cases ...Test) Integration

RenderBody is like Render but the Component is expected to be elem.Body

func SetupIntegration

func SetupIntegration(name string, i Integration) Integration

SetupIntegration returns an Integration test ready for execution. name is the name of the test function.

type List

type List []Test

List is a list of tests.

func (List) Exec

func (ls List) Exec()

Exec implements Test interface. This will call Exec method of all the list members.

type SpecResult

type SpecResult struct {
	ID                 string          `json:"id"`
	Package            string          `json:"package"`
	Desc               string          `json:"description"`
	FullName           string          `json:"fullname"`
	Duration           time.Duration   `json:"duration"`
	FailedExpectations []*ExpectResult `json:"failed_expectations,omitempty"`
	PassedExpectations []*ExpectResult `json:"passed_expectations,omitempty"`
	Children           []*SpecResult   `json:"children,omitempty"`
}

SpecResult contains result information after executing a test suite.

type Suite

type Suite struct {
	Parent             *Suite
	Package            string
	ID                 string
	Desc               string
	BeforeFuncs        *BeforeFuncs
	AfterFuncs         *AfterFuncs
	MarkedSKip         bool
	MarkedSkipMessage  string
	Duration           time.Duration
	Expectations       []*Expectation
	FailedExpectations []*Expectation
	PassedExpectations []*Expectation
	Children           []*Suite
}

func (*Suite) Exec

func (s *Suite) Exec()

Exec implements Test interface.

func (*Suite) Fullname

func (s *Suite) Fullname() string

Fullname returns a string depicting full tree descriptions from the parent root Suite to the current one.

func (*Suite) Result

func (s *Suite) Result() *SpecResult

Result returns results of executing the suite.

type T

type T interface {
	Error(...interface{})
	Errorf(string, ...interface{})
	Fatal(...interface{})
	Fatalf(string, ...interface{})
	Errors() []string
}

T is an interface for failing expectations.

type Test

type Test interface {
	Exec()
	// contains filtered or unexported methods
}

Test is an interface for a testable object. Note that this is supposed to be used internally so user's can't implement this interface.

func After

func After(fn ...func()) Test

After is a list of functions that will be executed after the actual test suite is run. You can use this to release resources/cleanup after the tests are done.

func Before

func Before(fn ...func()) Test

Before is a list of functions that will be executed before the actual test suite is run.

func Describe

func Describe(desc string, testCases ...Test) Test

Describe describe what you want to test. The first argument desc, can be a simple string for identifier you want to test, that can be a function, as struct method or anything.

You can use this to organise your test into a nested tree like structure.

func Exec

func Exec(ts ...Test) Test

Exec Executes the tests and returls a List of executed tests.

func It

func It(desc string, fn func(T)) Test

It defines expectations. The test logic happens in the function fn.

Directories

Path Synopsis
cmd
mad command
report

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL