Project customization¶
A project file allows the customization of several behaviors of lemoncheesecake.
It consists of a project.py
file that resides in the project top directory (at the same level of the “suites” directory).
It is a module that provides a project
variable. This variable must be an instance (or a subclass) of a
Project
class.
A minimal project module looks like this:
# project.py:
from lemoncheesecake.project import Project
project = Project()
Note
The Project
constructor takes an optional project_dir
argument that is
used by lemoncheesecake to know where the suites, fixtures must be loaded from, where the report must be
written, etc…
By default, this directory is determined from the path of the module where the Project
constructor is called.
If the Project
class is instantiated in the project.py
module as described above, everything
will work as expected.
However, if the constructor of Project
is called outside of project.py
then the
project_dir
will have to be passed explicitly.
Changed in version 1.5.0.
Prior to 1.5.0, the project dir argument is required, such as:
# project.py:
import os
from lemoncheesecake.project import Project
project = Project(os.path.dirname(__file__))
Adding custom CLI arguments to lcc run¶
Custom command line arguments can be added to lcc run
:
# project.py:
from lemoncheesecake.project import Project
class CustomProject(Project):
def add_cli_args(self, cli_parser):
cli_parser.add_argument("--host", required=True, help="Target host")
cli_parser.add_argument("--port", type=int, default=443, help="Target port")
project = CustomProject()
And then accessed through the cli_args
fixture:
# fixtures/fixtures.py:
def target_url(cli_args):
return "https://%s:%s" % (cli_args.host, cli_args.port)
cli_parser
is an ArgumentParser
instance of the argparse module.
Running code before and/or after the test session¶
Hook methods can be defined to be run before and/or after the test session. Since the code of these methods is not run within
the context of a test session, all functions logging information (such as lcc.log_info
, check_that
, etc…)
into the report won’t be available (they will raise an exception):
# project.py:
from lemoncheesecake.project import Project
class CustomProject(Project):
def pre_run(self, cli_args, report_dir):
# do something before the tests are run
def post_run(self, cli_args, report_dir):
# do something after the tests are run
project = CustomProject()
An exception raised within the pre_run
method will prevent the tests from being run.
The lcc.UserError
exception class
can be used to show the user an error message. Any other exception will be considered as an unexpected error and a
full error stacktrace will be displayed to the user.
Regarding the previous example, please note that the pre_run
and post_run
methods can be defined independently.
Adding extra information in the report¶
Extra key/value pairs can be added to the “Information” section of the report:
# project.py:
from lemoncheesecake.project import Project
class CustomProject(Project):
def build_report_info(self):
return [
("info1", "value1"),
("info2", "value2")
]
project = CustomProject()
Setting a custom report tile¶
A custom report title can also be set:
# project.py:
import time
from lemoncheesecake.project import Project
class CustomProject(Project):
def build_report_title(self):
return "This is my test report at %s" % time.asctime()
project = CustomProject()
Customize suites and fixtures loading¶
The Project
class loads the suites and fixtures respectively from “suites” and “fixtures” directories relative to
the project directory.
Here is an example of project that loads suites and fixtures from alternate directories by overriding the
load_suites
and
load_fixtures
methods:
# project.py:
from lemoncheesecake.project import Project
from lemoncheesecake.suite import load_suites_from_directory
from lemoncheesecake.fixture import load_fixtures_from_directory
class CustomProject(Project):
def load_suites(self):
return load_suites_from_directory(os.path.join(self.dir, "my_suites"))
def load_fixtures(self):
return load_fixtures_from_directory(os.path.join(self.dir, "my_fixtures"))
project = CustomProject()
For more information, see:
load_suite*
functions fromlemoncheesecake.suite
moduleload_fixture*
functions fromlemoncheesecake.fixture
module
Metadata Policy¶
The project settings provides a metadata policy that can be used to add constraints to tests and suites concerning the usage of metadata.
The following example requires that every tests provide a property “priority” whose value is among “low”, “medium” and “high”:
# project.py:
from lemoncheesecake.project import Project
project = Project()
project.metadata_policy.add_property_rule(
"priority", ("low", "medium", "high"), required=True
)
In this other example set, the metadata policy makes two tags available (“todo” and “known_defect”) for both tests and suites while forbidding the usage of any other tag:
# project.py:
[...]
project = Project(project_dir)
project.metadata_policy.add_tag_rule(
("todo", "known_defect"), on_test=True, on_suite=True
)
project.disallow_unknown_tags()
See MetadataPolicy
for more information.