# Testing

Warning

Work in progress. For now only Python testing is being added. Future coverage will include JavaScript code too.

Pootle tests use the full-featured pytest testing tool and its integration with Django via pytest-django.

The entire test suite can be executed from a checkout by running `make test`. This will create a new virtual environment, install the required dependencies and run the tests.

However, if you’re developing you can simply run

    $ py.test

from the root of the repository.

Note

Since the test runner automatically sets the `DEBUG` setting to `False`, the static assets need to be collected before running the view tests. You can run `make assets` for building them.

The `py.test` runner command offers several options which are extended by plugins as well. Check its documentation for further details.

## Settings for Tests

Some testing-specific settings are loaded from the tests/settings.py file and override any previous setting you might have set in the settings/*.conf files.

## Writing Tests

Writing new tests is easy. Just write a function whose name starts with `test_` and place it in an appropriate module under the tests/ subdirectory.

You’ll need to use plain Python assertions in test functions. Check pytest’s documentation for more information on assertions.

In order to use a fixture, you simply need to reference its name as a function argument. Pytest does the rest of the magic. There are other ways to reference and use fixtures as well, but most of the time you’ll find yourself passing them as function arguments.

### What to Test

You’ll usually want to test model behavior. These tests should test one function or method in isolation. If you end up needing to test for multiple things, then you might need to split the function/method into more specific units. This allows to structure the code better.

When testing models, it’s a suggested practice to avoid DB access because it makes the tests run slower, so think twice if your test actually needs DB access. At the same time, pytest-django encourages you to follow these best practices and disables DB access by default. If your test needs DB access, you need to explicitly request it by using the @`pytest.mark.django_db marker.

While testing views/integration tests can also help catch regressions, they’re slower to run and end up in less useful failures, so better to write fewer of these.

## Fixtures

Pootle tests include some pytest fixtures you can reuse. They’re located in tests/fixtures/ and are loaded when the test runner is being set up.

If you have a fixture which is very specific you can place it in a usual `conftest.py` file in its proper context, whereas the aforementioned directory is meant to be for storing shared or general-purpose fixtures.

### Model Fixtures

Model fixtures are stored under tests/fixtures/models/, and they are basically factory functions returning an instance of the desired model. Note that these might depend on other fixtures too.

For now these model fixtures require DB access, but since that’s not what every single test might need, we might want to combine this with other more complete solutions like factory_boy in the future.