Skip to content

Latest commit

 

History

History
151 lines (97 loc) · 3.55 KB

README.md

File metadata and controls

151 lines (97 loc) · 3.55 KB

Cloud Functions

Run locally

Login to Google Cloud

gcloud auth login

Run the desired function

# pwd = functions/exp
functions-framework --target exp

Then you can POST to the correct URL

curl -m 70 -X POST localhost:8080/exp -H "Authorization:bearer $(gcloud auth print-identity-token)" \
-H "Content-Type:application/json" \
-d '{"user_id": "123"}'

Call a local function

curl -H "Authorization: bearer $(./google-cloud-sdk/bin/gcloud auth print-identity-token)" https://us-central1-archy-f06ed.cloudfunctions.net/archy_py

Python testing & lint

Tox is used to automate testing.

Simply run the tox command to execute all the test script in the tox.ini file.

  • pytest -> Unit test framework.
  • black -> Code formatter.
  • pylint -> Static code analysis tool for lint.
  • isort -> isort your imports, so you don't have to.
  • mypy -> Python typing check utility.

You can run the script by hand if you want:

python -m pytest --rootdir .
black -l 120 .
pylint functions tests main.py
isort .
mypy --install-types --non-interactive --show-error-codes functions/ main.py

Requirements

How to write test

We are writting tests for the serverless cloud functions. Those are http endpoint that expect a request as input:

import functions_framework
from typing import Tuple


@functions_framework.http
def hello(request) -> Tuple[str, int]:
    """HTTP Cloud Function."""

    request_json: Optional[Any] = request.get_json(silent=True)
    return "Hello world!", 200

With google cloud function, the request is a Flask Request

An easy solution to test thoses functions is to use a mock of the request object.

Mock

A mock objects is a simulated object that mimic the behavior of real objects (wikipedia)[https://en.wikipedia.org/wiki/Mock_object]

The idea is to create a new Mock object instead of a Flask Request and to override the return_value. Like this, we control that the get_json will return the desired body

This is how we do it:

  1. Import MagicMock
from unittest.mock import MagicMock
  1. Create a MagicMock instance. Remember to properly name your variable.
request_mock = MagicMock()
  1. Override the return_value of the get_json
request_mock.get_json.return_value = {"user_id": "123"}
  1. Pass the mock object as an input of the function we want to test
hello(request_mock)

Full test example

from unittest.mock import MagicMock

from functions.hello.main import hello


def test_hello():
    body = {"user_id": "123"}

    request_mock = MagicMock()
    request_mock.get_json.return_value = body

    result = hello(request_mock)

    assert ("Hello world!", 200) == result

How to run test

The tests can be run in the command line or with VsCode.

The python path is defined in the pytest.ini file, run this command to run the tests:

pytest

In VsCode, open a test file and select the testing menu on the sidenav.

Go linting

We use golangci-lint, install it locally to validate your code before push:

# binary will be $(go env GOPATH)/bin/golangci-lint
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.46.2