Benefits of testing in Golang

Golang is a modern open-source language that has several features that make manual as well as automated testing easier. Though one can write automated tests in just about any language Go offers certain benefits due to which we are able to guarantee error and bug-free code to our clients. Golang gives feature-rich standard library support so as to provide an ideal environment for writing and running tests. It also brings in tools such as the Go Test tool which conducts writing tests at development time. Since Go defines a way to write automated tests that are automatically excluded from the compiled executable this test suite runs at the development time. It also provides code coverage analysis, displaying exactly which lines were exercised by tests, and which were not. Coming to the testing environment that Golang provides, here are some of the features that Golang brings into testing:

Image of Go Programming Language

Logrus

Logrus is a feature-rich structured logger for Golang. We can write logs asynchronously to avoid extra overhead on the system. It has many known service hooks available such as:

Airbrake logo

Airbrake - Error monitoring and detection software.

Influxdb logo

InfluxDB - Time Series
database

Elastisearch logo

ElasticSearch

Redis logo

Redis Cache and more

Benefits:

    Due to asynchronous logging important resources can be saved for other priority tasks.

    Service Hooks such as Airbrake help in quick bug fixing and superior test code quality while Redis features in-memory data set.

    The resultant effect is that with Logrus we are able to efficiently track and write logs that result in neat and well-written code.

Further Logrus comes with many in-built features that might be useful for the developer.

    Logs can be written directly into files.

    When switching between development and production environment, developers can set a log level so that they do not have to continually add or remove logs.

    Further, it is possible to print logs with additional fields like line number from where the logs were called. This is especially helpful while debugging production bugs.


Golang Benchcmp

The benchcmp command displays performance changes between benchmarks. Benchcmp parses the output of two 'go test' benchmark runs, correlates the results per benchmark, and displays the deltas.

Golang Benchcmp is one of the most fantastic tools comprising the Golang Toolkit. By setting benchmarks we can easily compare system calls by understanding which piece/version of code performs better. This can help avoid performance bottlenecks.

Benefits

    With Golang Benchcmp we are able to implement superior quality code which is free of any performance bottlenecks.

    The tool is very efficient while profiling code to get a better understanding of the application’s behavior.

    It also works well in conjunction with benchviz, a tool to visualize results from bench comp and save the result in form of svg.


Golang Pprof

Golang Pprof is Golangs built-in Library. It continually generates data. By utilizing the Pprof tool we are able to perform CPU profiling of the system. It helps us analyze the CPU dump and then generate reports on performance in the CPU by generating a flame graph.

One of the major highlights of Pprof is that it can be efficiently used to detect memory leakage and bottlenecks. With this, it is easy to recognize the block of code that is slowing down the system using visual profile graphs. Pprof provides around 5 profiles and each profile has a different purpose to serve. Following are the predefined profiles:

    goroutine - stack traces of all current goroutines.

    heap - a sampling of all heap allocations.

    threadcreate - stack traces that led to the creation of new OS threads.

    block - stack traces that led to blocking on synchronization primitives.

    mutex - stack traces of holders of contended mutexes.

    Now let’s try the heap profile for a simple go program and see how easily we are able to detect memory leak in our code with the help of Go pprof.

    In the above code, we have created a mux router and given an endpoint heap, you can add new endpoints depending on the profile you want to use. We then call a goroutine “leaks” that will allocate a chunk of memory.

    Now, let’s try to detect this leak using pprof.

    Run command go run main.go to run the code.

    Now run go tool pprof http://localhost:8080/debug/pprof/heap in a separate terminal. This will run pprof in interactive mode. Type ‘top’ and press enter.

    As you can see in the image, the pprof has detected the leaks uses 51.74MB of memory.

    You can also view this in web mode.Enter ‘web’ in pprof interactive mode. This command will open up in the browser to show a graphical representation.

    Image of web mode

    As you can see the visual result also indicated that “leaks” is using up our memory. We have successfully detected the memory leak in our code using pprof.

    Similarly, you can use other profiles according to your requirements.

Benefits

    When used in collaboration with the above mentioned Uber Go-Torch, Golang Pprof helps us develop code that performs at an optimized level.


Pprof Flamegraph

Further, it is possible to view flamegraphs within the pprof tool. The flame graph generates data sets about Time consumption, Memory Consumption, CPU Usage and more.

Sample Flamegraph for experience:
Image of Pprof Flamegraph

It’s the width of the boxes which show the total time on-CPU; greater width may indicate slower functions or it may simply mean that the function is called more often. You can simply click on a box for more details and move ahead in the hierarchy; making it easier to identify hot spots.

Benefits

    Stack traces are difficult to read and can be very time-consuming. Flame Graphs, on the other hand, helps visualize the same stack trace at a glance and identify the challenge quickly and efficiently.

    Flame graphs are easy to zoom in and out for the user. Users can also hover over the element to see how frequently does the element appear in the graph. Resultantly they can optimize code for speed, CPU usage, memory usage, performance and time.


At Gowitek we follow test-driven development methodology. Our developers first consider the requires feature specifications and then write the tests. We then implement features by putting in only the code required to prevent any test fails. By doing testing first we ensure that developers should pay equal attention to functionality as well as bug removal. Also by following such test-driven development, we ensure that testing is given an appropriate amount of time and effort and not done in a hurried and rushed manner. To know more about how we are incorporating Golang in doing so please reach out to us .