Skip to content

Commit

Permalink
feat: isolate test network + make single test run (#806)
Browse files Browse the repository at this point in the history
Co-authored-by: Jagruti Tiwari <tiwarijagruti1@gmail.com>
  • Loading branch information
alexgarel and Jagrutiti authored Jun 16, 2022
1 parent 17619ec commit 3618cb1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 25 deletions.
29 changes: 24 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ENV_FILE ?= .env
MOUNT_POINT ?= /mnt
HOSTS=127.0.0.1 robotoff.openfoodfacts.localhost
DOCKER_COMPOSE=docker-compose --env-file=${ENV_FILE}

DOCKER_COMPOSE_TEST=COMPOSE_PROJECT_NAME=robotoff_test PO_LOCAL_NET=po_test docker-compose --env-file=${ENV_FILE}

.DEFAULT_GOAL := dev
# avoid target corresponding to file names, to depends on them
Expand Down Expand Up @@ -140,14 +140,20 @@ unit-tests:
@echo "🥫 Running tests …"
# run tests in worker to have more memory
# also, change project name to run in isolation
COMPOSE_PROJECT_NAME=robotoff_test ${DOCKER_COMPOSE} run --rm workers poetry run pytest --cov-report xml --cov=robotoff tests/unit
${DOCKER_COMPOSE_TEST} run --rm workers poetry run pytest --cov-report xml --cov=robotoff tests/unit

integration-tests:
integration-tests:
@echo "🥫 Running integration tests …"
# run tests in worker to have more memory
# also, change project name to run in isolation
COMPOSE_PROJECT_NAME=robotoff_test ${DOCKER_COMPOSE} run --rm workers poetry run pytest -vv --cov-report xml --cov=robotoff --cov-append tests/integration
( COMPOSE_PROJECT_NAME=robotoff_test ${DOCKER_COMPOSE} down -v || true )
${DOCKER_COMPOSE_TEST} run --rm workers poetry run pytest -vv --cov-report xml --cov=robotoff --cov-append tests/integration
( ${DOCKER_COMPOSE_TEST} down -v || true )

# interactive testings
# usage: make pytest args='test/unit/my-test.py --pdb'
pytest: guard-args
@echo "🥫 Running test: ${args}"
${DOCKER_COMPOSE_TEST} run --rm workers poetry run pytest ${args}

#------------#
# Production #
Expand All @@ -161,6 +167,8 @@ create_external_volumes:
create_external_networks:
@echo "🥫 Creating external networks if needed … (dev only)"
( docker network create ${PO_LOCAL_NET} || true )
# for tests
( docker network create po_test || true )

#---------#
# Cleanup #
Expand All @@ -174,3 +182,14 @@ prune_cache:
docker builder prune -f

clean: goodbye hdown prune prune_cache

#-----------#
# Utilities #
#-----------#

guard-%: # guard clause for targets that require an environment variable (usually used as an argument)
@ if [ "${${*}}" = "" ]; then \
echo "Environment variable '$*' is mandatory"; \
echo use "make ${MAKECMDGOALS} $*=you-args"; \
exit 1; \
fi;
56 changes: 36 additions & 20 deletions doc/how-to-guides/test-and-debug.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Robotoff is an API that pulls prediction data, annotation data, product data, nu


If your development instance is not connected to a product-opener instance
(which happens automatically if you have a running product-opener instance),
(which happens automatically if you have a running product-opener instance),
you won't have a MongoDB instance. This means you won't have any product data on your local set up.
Though you may populate your postgres database with some predictions, insights, images references, etc.

Expand All @@ -23,32 +23,40 @@ $ docker-compose run --rm api poetry run python
> PredictionFactory()
````
> **_NOTE:_** If you are on Windows we recommend using [Git bash](https://git-scm.com/downloads) to run commands.
> **NOTE:**
> If you are on Windows we recommend using [Git bash](https://git-scm.com/downloads) to run commands.
# How to run test cases?
We use [pytest](https://docs.pytest.org/en/7.1.x/) to run test cases and [Makefile](../../Makefile) to run our commands. In `Makefile` you will find all the commands used to run Robotoff.
We use [pytest](https://docs.pytest.org/en/7.1.x/) to run test cases and [Makefile](../../Makefile) to run our commands.
The following command will run all the test cases one by one:
```
$ COMPOSE_PROJECT_NAME=robotoff_test docker-compose run --rm workers poetry run pytest
```bash
$ make tests
```

## How to run a single test case?

You need to specify the name of the test case you want to invoke.
Here is the syntax:
The simplest is to use the *pytest* make target for that:

```
$ COMPOSE_PROJECT_NAME=robotoff_test docker-compose run --rm workers poetry run pytest path/to/test_file.py::the_function_name
```bash
make pytest args='path/to/test_file.py::the_function_name'
```

In this example we call `test_get_type()` from `tests/unit/insights/test_importer.py`
For example,
to call `test_get_type()` from `tests/unit/insights/test_importer.py`:

```bash
$ make pytest args="tests/unit/insights/test_importer.py::TestLabelInsightImporter::test_get_type"
```
$ COMPOSE_PROJECT_NAME=robotoff_test docker-compose run --rm workers poetry run pytest tests/unit/insights/test_importer.py::TestLabelInsightImporter::test_get_type
```

Remember to put quotes especially if you have multiple arguments.


> **NOTE**:
> Be sure to rum `make create_external_networks` before if needed (especially if you get `Network po_test declared as external, but could not be found`)


# When to write your own test cases?

Expand All @@ -65,18 +73,26 @@ To identify parts of the code where Robotoff connects to MongoDB or to Open Food
# Debugging guide

We encourage using [PDB](https://docs.python.org/3/library/pdb.html)
to debug. You can add the following lines in your function to find out what your code does and where it breaks.
to debug.

Running test with `--pdb` flags, pytest will stop and open the pdb console as soon as there is an error or an assert fails.
This can be a good way to try to understand why a test is failing.


```bash
make pytest args="path/to/test.py --pdb"
```
If it's a `mock.assert_called_with`, you can look at the real data passed to a test case by calling mock.call_args in the pdb console.
If you need more precise control to see code path before it breaks, you can add the following lines in your function to find out what your code does and where it breaks.

```python
import pdb; pdb.set_trace()
```

and then run the `pytest`, with the `--pdb` option:
and then run the `pytest`, with the `--pdb` option (as above).

> **Note**
> we need the `--pdb` option,
to view the inputs and outputs captured by pytest
> and access the pdb console.
```
COMPOSE_PROJECT_NAME=robotoff_test docker-compose run --rm workers poetry run pytest path/to/test.py::test_xxx --pdb
```
Also runnning with `--pdb` flag will stop on every test failure, even if you didn't set any `pdb.set_trace()` this can be a good way to try to understand why a test is failing.

0 comments on commit 3618cb1

Please sign in to comment.