Contributing to the API

This article provides a high level overview of how to contribute changes to the DroneKit-Python source code.

Tip

We highly recommend that changes and ideas are discussed with the project team before starting work!

Submitting changes

Contributors should fork the main dronekit/dronekit-python/ repository and contribute changes back to the project master branch using pull requests

  • Changes should be tested locally before submission.
  • Changes to the public API should be documented (we will provide subediting support!)
  • Pull requests should be as small and focussed as possible to make them easier to review.
  • Pull requests should be rebased against the main project before submission to make integration easier.

Test code

Test code should be used to verify new and changed functionality. There are three test suites in DroneKit-Python:

  • Unit tests (tests/unit) — verify all code paths of the API.
  • Integration tests (tests/sitl) — verify real-world code, examples, and documentation as they would perform in a real environment.
  • Web client tests (tests/web) — specifically verify the Python library’s capability to talk to DroneKit Cloud.

Setting up local testing

The links below provide information on how to set up a development environment on your development computer. Changes to DroneKit can then be tested locally.

Several of the test suites use nose, a Python library for writing test scripts and a command line tool for running these. When setting up your dev environment, all test dependencies will have been installed (via requirements.txt).

For several tests, you may be required to set an environment variable. In your command line, you can set the name of a variable to equal a value using the following invocation, depending on your OS:

export NAME=VALUE      # works on OS X and Linux
set NAME=VALUE         # works on Windows cmd.exe
$env:NAME = "VALUE"    # works on Windows Powershell

Unit tests

Unit tests use nosetests. On any OS, enter the following command on a terminal/prompt to run the unit tests (and display a summary of the results):

cd dronekit-python
nosetests tests/unit

For unit tests, mock is used to simulate objects and APIs and ensure correct results.

Writing a new unit test

Good unit tests should:

  1. Accompany all new features that are written.
  2. Verify all code paths that code can take.
  3. Be concise and straightforward.

Create any file named test_XXX.py in the tests/unit folder to add it as a test. Feel free to copy from existing tests to get started. When nosetests is run, it will add your new test to its summary.

Tests names should refer directly to a Github issue (for example, test_12.py would refer to issue #12 or describe fully what functionality they encompass (for example, test_waypoints.py would describe a unit test for the waypoints API).

Avoiding printing any data from your test. Instead, use assertions to test your code is consistent. You can use the built-in Python assert macro as well as assert_equals from the nose.tools module:

from nose.tools import assert_equals

def test_this(the_number_two):
    assert the_number_two > 0, '2 should be greater than zero!'
    assert_equals(the_number_two, 2, '2 should equal two!'

Please add documentation to each test function describing what behavior it verifies.

Integration tests

Integrated tests use a custom test runner that is similar to nosetests. On any OS, enter the following command on a terminal/prompt to run all the integrated tests (and display summary results):

cd dronekit-python
python -um tests.sitl

Integrated tests use the SITL environment to run DroneKit tests against a simulated Copter. Because these tests emulate Copter in real-time, you can set several environment variables to tweak the environment that code is run in:

  1. TEST_SPEEDUP - Speedup factor to SITL. Default is TEST_SPEEDUP=1. You can increase this factor to speed up how long your tests take to run.
  2. TEST_RATE - Sets framerate. Default is TEST_RATE=200 for copter, 50 for rover, 50 for plane.
  3. TEST_RETRY - Retry failed tests. Default is TEST_RETRY=1. This is useful if your testing environment generates inconsistent success rates because of timing.

You can choose to test specific files by passing them as arguments:

python -um tests.sitl test_1.py test2_.py ...

Writing a new integration test

Integration tests should be written or improved whenever:

  1. New functionality has been added to encapsulate or abstract older methods of interacting with the API.
  2. Example code or documentation has been added.
  3. A feature could not be tested by unit tests alone (e.g. timing issues, mode changing, etc.)

You can write a new integrated test by adding a file with the naming scheme test_XXX.py to the tests/sitl directory. In this file, functions with the prefix test_ will be called with the local_connect parameter. For example:

from testlib import assert_equals

def test_parameters(local_connect):
    v = local_connect().get_vehicles()[0]

    # Simple parameter checks
    assert_equals(type(v.parameters['THR_MIN']), float)

This checks to see that the parameter object is of type float.

Tests names should refer directly to a Github issue (for example, test_12.py would refer to issue #12 or describe fully what functionality they encompass (for example, test_waypoints.py would describe a unit test for the waypoints API).

Avoiding printing any data from your test. Instead, use assertions to test your code is consistent. You can use the built-in Python assert macro as well as assert_equals from the testlib module:

from testlib import assert_equals

def test_this(the_number_two):
    assert the_number_two > 0, '2 should be greater than zero!'
    assert_equals(the_number_two, 2, '2 should equal two!'

Please add documentation to each test function describing what behavior it verifies.

Web client tests

Warning

The web client library is being rewritten. Please discuss with the project team if you intend to develop with or for the present version of the web client.

Web client tests use nosetests. To run these, you will need to sign up for API keys from cloud.dronekit.io. With these, export a variable named DRONEAPI_KEY with a value in the format <id>.<key> to your environment.

On any OS, enter the following command on a terminal/prompt to run the web-client tests (and display summary results):

cd dronekit-python
nosetests tests/web