Skip to content

Writing tests

This page shows how to write Python tests for a Lime CRM solution or package with lime-test. To find out where tests live and how to run them, see Running tests.

What is lime-test?

lime-test helps you write tests for code that makes use of the Lime CRM platform, such as plugins or non-core packages.
It's implemented as a plugin to pytest, which gives you a set of ready made fixtures that you can use for the more basic types of tests for Lime.
For more control, you are encouraged to use the available helper functions that allows you to create more pointed test code.

The following example uses the lime_app fixture, which loads a complete LimeApplication (lime_application.application.LimeApplication) with a set of lime types defined that closely matches the current state of the lime-core database.
It also loads a complete database to memory that is disregarded after the test ends to ensure that multiple tests don't interfere with each other.

The code we want to test:

def average(limeobjects, propname):
    values = [o.get_property(propname).value for o in limeobjects]
    return sum(values) / len(values)

The code we can use to test it:

def test_average(lime_app):
    Deal = lime_app.limetypes.deal
    deals = [
        Deal(value=2),
        Deal(value=4)
    ]
    assert average(deals, 'value') == 3

Fixtures

lime-test ships a large set of ready-made fixtures — see the Fixtures section for an overview, the conventions they follow, and a per-fixture reference.

In-memory Web Application

lime-test enables you to start up a complete web application in memory that you can make requests to, to ensure that your endpoints work as they should. It builds on the in-memory database to create a complete environment for your endpoints that is created for your specific test method, and torn down immediately afterwards.

It's an implementation of Flask's test client.

A simple example

Given the following endpoint in the acme_solution plugin:

class DealAverage(webserver.LimeResource):
    def get(self, companyid):
        company = self.application.limetypes.company.get(companyid)
        avg = averagelib.average(company.properties.deal.fetch(), 'value')

        return {'average': avg}


api.add_resource(DealAverage, '/dealaverage/<int:companyid>')

We can write the following test:

import json


def test_calculate_average_for_deals(
    web_client, lime_app, prefix_url, save_lime_objects
):
    company = lime_app.limetypes.company(name="acme")
    deals = [
        lime_app.limetypes.deal(name="deal1", value=42),
        lime_app.limetypes.deal(name="deal2", value=128),
    ]
    for deal in deals:
        company.properties.deal.attach(deal)

    company, *_ = save_lime_objects(company, *deals)

    response = web_client.get(prefix_url(f"acme_solution/dealaverage/{company.id}"))

    assert response.status_code == 200
    assert json.loads(response.data) == {"average": 85.0}