Przejdź do treści PWA

Golang Warsaw #2

Dziś odbyło się drugie spotkanie Golang Warsaw. Jest to nowa organizacja w naszym mieście (dopiero drugie spotkanie w systemie comiesięcznym). Wiodącym językiem Go.

Będzie to moje pierwsze spotkanie z ludźmi pracującym w tym języku. Nie ukrywam, że chciałbym dowiedzieć się czegoś o tym nowym, tak mocno reklamowanym języku.

Godzina 18:15 - Zaczynamy!

Baner promujący artykuł

Talk #1: Testowanie w Go

Pierwsza prelekcja - Tomasz Grodzki (github.com/tg) opowiedział o testowaniu aplikacji napisanym w Go. Miałem nadzieje, że dowiem się czegoś o testowaniu oraz debugowaniu aplikacji.

Tomek powiedział, że w Go można łatwo pisać aplikację na wielu procesorach, ze względu na to, że ma dzielone wątki. Go ma wiele wbudowanych rzeczy, m. in. biblioteka pomocna w testach (testing).

Testowanie kodu napisanego w Go

Pisanie pierwszego testu: do danego pliku dodajemy na końcu: _test.go.

Pierwsza metoda:

package party

import "testing"

func TestBeer(t * testing.T) {
    if !FridgeContains("beer") {
        t.Fatal("expected some cold beer");
    }
}

Druga metoda (from outside):

package part_test

import (
    "testing"
    "rihanna.com/party"
)

func TestBeer(t *testing.T) {
    if !party.FridgeContains("beer") {
        t.Fatal("expected some cold beer");
    }
}

Uruchomienie testów

go test .
go test rihanna.com/party
go test ./... # odpala wszystkie testy w głąb

testing.T - nasze magiczne 't'. Biblioteka pomocna w testach. Zawiera mnóstwo metod tj: Error, Errorf, Fail, FailNow, Failed, Fatal, Fatalf, Log, Logf, Parallel, Skip, SkipNow, Skipf, Skipped.

Logi pokazują się tylko w przypadku kiedy dany test nie przeszedł. Jeśli uruchomimy testy w parametrem verbose, pokażemy wszystkie logi (nawet w tych testach które przeszły).

Testy z parallel będą się uruchamiały jednocześnie.

Examples - część testu

func ExampleHandsUp() {
    fmt.PrintLn(HandsUp("o o o")
    // Output:
    // \o/ \o/ \o/
}

func Example() // package
func ExampleF() // function
func ExampleT() // type
func ExampleT_M() // method

func Example*_xyz() // more...

Dokumentacja

go doc -ex=true . # budowanie dokumentacji

Narzędzie to potrafi postawić webserwer oraz wygenerować dokumentację HTML.

Trzeci rodzaj testów to benchmarks.

func BenchmarkHeadSpin(b *testing.B) {
    for i := 0; i < b.N; i++ {
        HeadSpin()
    }
}

Uruchamiamy je za pomocą:

go test -bench . # ta kropka to wyrażenie regularne

go test sam sobie dopiera ile iteracji ma zrobić w ciągu zadanego okresu czasowego. Parametr benchtime zmienia ten okres czasu.

testing.B = testing.T + (ReportAllocs, ResetTimer, RunParallel, SetBytes, SetParallelism, StartTimer, StopTimer)

  • ReportAllocs - raportuje alokację pamięci

Więcej kontroli

// since go 1.4
func TestMain(m *testing.M) {
    os.Exit(m.Run())
}

Tyle odnośnie podstaw testowania

Jeśli do go test przekażesz flagę, której go test nie rozpozna przekaże te parametry do MainTest.

W bibliotece standardowej mamy kilka rzeczy, które ułatwiają testowanie:

  • net/httptest
  • testing/iotest - do testowania wejścia / wyjścia
  • testing/quick - do testowania: generuje losowe argumenty naszej funkcji

net / httptest

  • httptest.ResponseRecorder
  • httptest.Server - automatycznie nasłuchuje na localhost z wybranym przez system porcie, oraz zwraca nam URL do siebie

testing / iotest

  • iotest.DataErrReader
  • iotest.TimeoutReader - za drugim razem gdy będzie czytał, zwróci iotest.ErrTimeout
  • HalfRead - czyta dane do połowy - pomocne do testowania, co się stanie, jeśli nasza fn dostanie mniej danych niż się spodziewa
  • OneByteReader - czy nasz fn radzi sobie ze skrajnymi wartościami
  • TruncateWrite - zapisze przekazaną liczbę bajtów, ale poinformuje, że zapisał komplet danych - taka oszukańcza fn 😄

testing / quick

  • Black box testing
  • Generuje losowe ciągi znaków
  • quickCheck and quick.CheckEqual
  • inspirowana QuickCheck z Haskell-a

Reflect - dość skomplikowana biblioteka do losowania wartości - więcej golang.org/pkg/reflect/

quick.Config

type Config struct {
    // Set max number of iterations
    MaxCount int

    // Scale max number of iterations
    MaxCountScale flaot64

    // Source of random number
    Rand *rand.Rand

    // Generator of values
    Values func ([]reflect.Value, *rand.Rand)
}

Polecane narzędzia

  • go vet - sprawdza popularne błędy w kodzie
  • -race flag - stara się wykryć kiedy używamy zmienny z różnych go routings
  • Go bardzo lubi interfejsy, powinniśmy korzystać z nich, ponieważ lepiej się potem testuje

Profile

go test pozwala zapisywać wynik do pliku.

  • go test -covertprofile cover.out
  • go test -cpuprofile cpu.out
  • go test -memprofile mem.out

Nie działa to na OSX: github.com/golang/go/issues/6047

Pokrycie kodu

go test -cover

# prezentacja na stronie internetowej
go test -coverprofile=c.pro
go test cover -html=c.pro

Referencje

  • golang.org/pkg/testing
  • blog.golang.org
  • go help test
  • go help testflag

Talk #2

Była tylko jedna prelekcja, niestety, ze względu na chorobę drugiego prelegenta.

Do zobaczenia na następnym Golang!