Digital Fairy Tales by Drasko DRASKOVIC     About     Archive     Feed

Testing Iris RESTful API

Iris and Mainflux

Iris is a HTTP framework written in Go. We have choosen Iris as HTTP API protocol development framework for Mainflux IoT platform because of it’s impressive bechmarks and simplicity. As robustness and consequently test coverage is very important for any serious and professional project, this article explains Iris RESTful API testing techniques on the example of Mainflux server.

EDIT 1 - Due to the needs for leanest approach possible, Mainflux project decided to strip Iris (and any other framework) and stick with bare Go standard lib for HTTP development.

EDIT 2 - Interesting discussion on this subject can be found on Reddit.

Mainflux project adopts TDD approach, and Go is a great language with powerful testing capabilities - so it is well suited for writing test scenarios in an organized and well designed manner.

Go Testing Framework

Go Testing framework is nicely explained here. In short, recipe for testing <my_module>.go is following:

  • Create <my_module>_test.go and make it belong to the same package (it is actually package we are testing, not only this particular module)
  • In your test, use import "testing"
  • Define function func TestSomething(t *testing.T)
  • Optionally, if some prerequisite set-up is needed you can use func TestMain(m *testing.M)

As explained here, tests can be run via go test in the current dir. In order to test the whole project, Travis for example uses:

go test -v ./...

So this is the way you should test your project from the project root.

Testing Go HTTP RESTful APIs

Usually, for testing HTTP servers Go already provides testing library called httptest. Some examples of using this library can be found here, here, here or here. Or even here.

However, Iris does not use Go’s net/http - it uses fasthttp (look at the imports here). This means that you can not use httptest to test the server.

Gin Gonic for example uses net/http (as can be seen in imports here, so you can write tests like this.

@kataras, Iris author, reccomends usage of the httpexpect testing framework for testing Iris-based HTTP servers - please refer to this link.

Httpexpect, Fasthttp and Iris

This is a hard part ;). Let’s go slowly in code disecting.

In this httpexpect example we can see that func IrisHandler() is returning fasthttp.RequestHandler, which is api.Router, where api is iris.New(), i.e. Iris instance. Then here in irisTester() function we use this handler (Router of the Iris instance) to create httpexpect instance.

Further, when we look FrameworkAPI interface over here, we can see that this structure contains member function Tester(), defined in the following way: Tester(*testing.T) *httpexpect.Expect, which is basically a getter which fetches testFramework member of the structure Framework. This member is initialized via function NewTester() in which httpexpect.Expect instance is created based on api.Router.

This means that every Iris server already have member testFramework which is correct httpexpect.Expect instance for our fasthttp handler. It is static member (begins with lowercase letter, thus not reachable from other packages) and can be obtained via api.Tester() getter.

Mainflux Iris Test Example

Mainflux http_server_test.go uses iris.Tester(t) to fetch correct httpexpect instance of the current Iris Framework started in HttpServer() gorutine just before.

Code of the test function is following:

```go func TestServer(t *testing.T) { // Config var cfg config.Config cfg.Parse()

go HttpServer(cfg)

// prepare test framework
if ok := <-iris.Available; !ok {
	t.Fatal("Unexpected error: server cannot start, please report this as bug!!")
}

Read more

Test Post

My Test Post

This is a test post just to test Jekyll setup.

#include <stdio.h>

int main(void)
{
    printf("Hello World\n");
    return 0;
}