Skip to content

Commit

Permalink
Lab 3 bonus: unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kolayne committed Feb 16, 2024
1 parent 4fc530e commit 5a6e285
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 0 deletions.
20 changes: 20 additions & 0 deletions app_go/GO.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,23 @@ external installation.
- Explicit error handling is applied everywhere except for transmission
errors (both in networking and when printing to console), which are
explicitly ignored for there is nothing to do in those cases.

## Tests

For the project there are unit tests that cover key functionalities
of the web application. There are:

- Unit tests: ensure that cat facts are queried without error and
do not repeat too often.

- Integration tests: test that when whatever http request is sent,
the server responses with a non-empty catfact (which is not an
error).

Tests are implemented using best practices:

- A cannonical project structure proposed by the Go authors.

- There are both tests for API and tests that interact with the app
in a way similar to user interface.

6 changes: 6 additions & 0 deletions app_go/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Cat fact web app

![CI badge](https://github.com/kolayne-IU-assignments/S24-core-course-labs/actions/workflows/python-app.yml/badge.svg)

A web application that shows random cat facts on its main page.

## One-shot run
Expand Down Expand Up @@ -46,3 +48,7 @@ docker run --rm -d -p 5000 kolay0ne/app_go
```

Replace `kolay0ne/app_go` with your image/tag name if you built it manually.

## Unit Tests

To run unit tests, navigate to the project directory and run `go test`.
29 changes: 29 additions & 0 deletions app_go/catfact_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import "testing"

// TestCatFact tests that `catFact` loads non-empty facts
// without errors and that those facts are different
func TestCatFact(t *testing.T) {
const TRIES = 5

options := map[string]int{}

for i := 0; i < TRIES; i++ {
s, e := catFact()
if e != nil {
t.Fatal("Error quering a cat fact", e)
} else if s == "" {
t.Fatal("No error occurred but `catFact` returned" +
"an empty string")
}

options[s] += 1
}

// Tests are repeating
t.Logf("Out of %d cat facts, %d are unique", TRIES, len(options))
if len(options) <= (1+TRIES)/2 {
t.FailNow()
}
}
2 changes: 2 additions & 0 deletions app_go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
func handler(w http.ResponseWriter, r *http.Request) {
fact, err := catFact()
if err == nil {
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintf(w, fact)
} else {
w.WriteHeader(http.StatusInternalServerError)
_, _ = fmt.Fprintf(w, "Failed to query a cat fact :(")
}
}
Expand Down
34 changes: 34 additions & 0 deletions app_go/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"io"
"testing"
"net/http"
"net/http/httptest"
"strings"
)

// TestFactLoads tests that the handler returns something that
// is neither empty nor an error
func TestFactLoads(t *testing.T) {
w := httptest.NewRecorder()

handler(w, nil)
resp := w.Result()

if resp.StatusCode != http.StatusOK {
t.Fatal("Server responded with exit code", w.Code)
}

buf, err := io.ReadAll(w.Body)
body := string(buf)
if err != nil {
t.Fatal("Failed to read response body")
}
if len(buf) == 0 {
t.Fatal("Response body is empty")
}
if strings.Contains(body, "Fail") && strings.Contains(body, ":(") {
t.Fatal("An error occurred while retreiving cat fact")
}
}

0 comments on commit 5a6e285

Please sign in to comment.