.. Document discussing development workflow etc. .. _development: Development =========== Once you have :ref:`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: Using Git --------- The codebase is versioned using the `Git version control software`_. Development follows a lenient branching structure, that you can easily follow. .. _Git version control software: https://git-scm.com/ Primary Branches ^^^^^^^^^^^^^^^^ - ``master`` is the default branch in Git and this is where all work comes together, new features always land in this branch. - ``stable/1.0`` releases are based on stable branches, which themselves are branched off the ``master`` branch. each major/minor version combination gets its own branch and will be maintained individually. .. _feature_development: 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. .. _create a pull request: https://github.com/polynorm/poly-xmm-core/compare 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 :ref:`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 ------------ 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. .. _py.test: http://docs.pytest.org/en/latest/ 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 :ref:`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.