Development¶
Once you have installed the backend core, you can start working on it. This document will guide you through our development process.
When installing the package, you’ll want to change install to develop.
This will make sure that updates to any Python files are immediately available to
the project’s code. Otherwise it would be necessary to issue a install command on
each and every file change you make. That wouldn’t be much fun!
Migrate Mongodb¶
You can migrate data with /manage.py mongo migrate. This will check which scripts in the migrations/ folder are
already applied and which are new. The new ones will be executed. Generally migrations are idempotent (can be
executed several times without breaking things).
Using Git¶
The codebase is versioned using the Git version control software. Development follows a lenient branching structure, that you can easily follow.
Primary Branches¶
masteris the default branch in Git and this is where all work comes together, new features always land in this branch.stable/1.0releases are based on stable branches, which themselves are branched off themasterbranch. each major/minor version combination gets its own branch and will be maintained individually.
Feature development¶
To start on a new feature or a similar task, a branch is created off the current master
branch. Its name should follow a “category/description” convention, where you are free to
include a ticket number as well. Examples: feature/1288-feature-x, task/rename-thing.
To have your new code approved, push it to our GitHub repository and create a pull request
into master (the default). A fellow colleague will promptly review your changes and either
approve them or request alterations before being merged into the master branch.
When creating your pull request, provide any additional useful information not already provided by the commit message and please tag the PR with appropriate labels from the sidebar.
Bug fixes¶
Before fixing a bug, ensure which versions are affected by it. If the bug is only present
in the master branch, fixing the issue can be done the same as above.
Otherwise, create a bug fix from the original stable/x.x branch where it first occured
or whichever release branch is still being maintained. The pull request should be created
targetting the relevant stable release branch.
After review and a successful merge, the bug fix should also be made available to the latest
development version in master. This ususally means cherry-picking the fixing commit
from the release branch onto the master branch (via a pull request branch).
Releases¶
Releasing a new version involves updating the version numbers mentioned in the code files as well
as any possibly affected supporting files (such as this documentation). Then, those changes are
submitted as a pull request onto the desired stable/x.x branch, to complete the release.
Tagging this commit can be done via the GitHub “Releases” interface after merging.
You can do this automatically for xmm-core by running invoke release x.x, or invoke release x.x --nopush,
if you do want to generate local changes but not push to Github yet.
Code quality¶
Code quality is automatically verified using continuous integration. We use a sub- and
superset of common pep8 rules, as well as some other conventions. The current exact
configuration for each code analysis tool can be seen in the setup.cfg file.
To run the code checks locally on your machine, make sure to install the additional
build requirements found in the requirements/build.txt file. After installing
those, you can run flake8:
flake8 path/to/file.py
This will let you know of any code quality issues in your changes. We recommend
setting this up as a git pre-commit hook, which will automatically run every time
you commit your changes. To do this, create an executable file called
pre-commit in the directory .git/hooks:
#!/bin/bash
flake8 $(git status -s | cut -c 4- | sed -s 's/.*-> //')
Using git status as input will make sure you only get issues reported on
files you actually worked on!
Testing¶
Tests are written using py.test. Test files are located in the tests
directory at the root of the project. Each file containing tests should
start with the prefix test_ to make sure it will be discovered and run.
Running tests¶
Running the test suite is straightforward, simply execute
this command(in the root of the xmm-core project directory):
$ py.test
This will run all tests and report back to you with a success or failure message. Individual tests can also be run by appending their file name and identifier. Check the help available for further details.
If you want to see coverage data, you can run the tests with --cov=xmm,
our continuous integration environment will automatically do this for you.
Writing tests¶
A little bit more tricky, but just as easy once you get the hang of it: writing more tests.
There are two main types of tests, both of which we have separated in
their respective directory under the primary tests folder. Unit and
integration tests.
Unittests are simple and small tests that will test one single unit in the code. This can be a single class or even a single function. Writing methods or functions with a lot of side effects will make writing unittests a lot harder, so try to keep this in mind.
Integration tests on the other hand, can be considered “blackbox” tests. They will typically run a very toplevel function and check if the final output matches our expectations. In our example, we fire virtual HTTP requests to the Flask backend and check if the server responded with the proper answer.
Your first test¶
Create a file inside of the integration test folder, it should have a name
that looks like test_part_of_app.py, where “part_of_app” is whatever part
you want to test, easy!
Within this file, try to follow our general style guide and don’t forget the encoding declaration at the top of the file.
You can create one or more functions, each representing a single test case
and every function should also be prefixed with test_ so py.test knows
which functions to run. You may also use a class with many tests, should
you wish to have shared functionality between the test cases.
Each test should have one or more asserts to make sure, everything is
as expected. That’s it! There are no special testing methods to remember,
py.test will automatically figure out what to do with each assert statement.
Using fixtures¶
Todo
You probably want to use test fixtures.
Documentation¶
Todo
This section needs work.