I am using Go and appengine, and now I would like to do some test cases.
I tried using gos standard test package, Files (both "package hello"):
hello/http.go
hello/http_test.go
Problem: I cannot run go test hello
. The closest I have got is go test hello/http_test.go
which works if I do not make any calls to http.go
, which is quite pointless. :)
Install Go
Set the Go Environmental Variables (Your path may vary):
export GOPATH=~/gopath
export PATH=$PATH:$GOPATH/bin
Download the Google App Engine SDK for Go
Set the Google App Engine Environmental Variables (Your path may vary):
export APPENGINE_SDK=$HOME/appengine
export PATH=$PATH:$APPENGINE_SDK
Symlink the appengine
and appengine_internal
dirctories:
ln -s $APPENGINE_SDK/goroot/src/pkg/appengine $GOPATH/src/pkg/
ln -s $APPENGINE_SDK/goroot/src/pkg/appengine_internal $GOPATH/src/pkg/
Install appenginetesting
go get github.com/mzimmerman/appenginetesting
appengintesting provides a fake appengine.Context
. Behind the scenes It's starts up a Python development server and runs the request through it, so tests can be a little bit slow (seconds instead of milliseconds). To use it in tests you write something like
import "github.com/mzimmerman/appenginetesting"
...
c := appenginetesting.NewContext(nil)
You can then use c
as you would use an actual appengine.Context
. This works will in the test file, but it won't work with contexts that you create by calling appengine.NewContext(r)
The strategy that I'm using in gaego is to import the context from a custom package instead of appengine
. This allows me to use an appengine.Context
when the build is for App Engine and use appenginetesting.Context
when the build is for the test suit.
By setting the following build flags:
// +build appengine
// +build !appengine
The compiler will decide which file it would like to load. Example. This techinique was taken form Gorilla
Then instead of import from appengine
I import from my package E.g.
import (
github.com/gaego/context
)
..
c := context.NewContext(r)
..
That last thing that needs to be mentioned is that you must explicitly close the context, otherwise the python processes will continue to run. You terminate the process by calling:
defer c.Close()
For more examples please view:
context_test.go
recorder_test.go
Edit: Takuya Ueda has created a brunch that works with the latest SDK
Edit2: Joshua Marsh maintains a fork that is compatible with the latest SDK
Edit3: Matt Zimmerman maintains a fork with additional features over the standard aetest package (Login/Logout & Task Queues)
An interesting development: as of 1.8.6 using service stubs for testing has been integrated into the SDK through the "appengine/aetest"
package. This works largely like the above via a "testing" context. More info
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With