Test Generation Steps¶
This is a reference for instances of Step
used in test generation. They are used when implementing a step hook or a plan hook.
All steps can be imported from kolo.generate_tests.steps
.
AssertDelete
¶
The AssertDelete
step represents an assertion that no instances of a Django model exist.
AssertDelete.module
¶
The module where the Django model lives. For example, "django.contrib.auth.models"
.
AssertDelete.model
¶
The name of the Django model. For example, "User"
.
AssertDelete.fields
¶
A list of DjangoField
instances used to specify which model instances do not exist.
AssertEqual
¶
The AssertEqual
step represents an assertion that two values are equal.
AssertEqual.left
¶
The repr
of a Python object to compare. For example "user.username"
.
AssertEqual.right
¶
The repr
of a Python object to compare. For example '"admin"'
.
AssertEqual.imports
¶
A set
of Import
instances used to add required imports to the generated test. Defaults to an empty set.
AssertInsert
¶
The AssertInsert
step represents an assertion that a Django model instance has been created.
AssertInsert.module
¶
The module where the Django model lives. For example, "django.contrib.auth.models"
.
AssertInsert.model
¶
The name of the Django model. For example, "User"
.
AssertInsert.lookup_fields
¶
A list of DjangoField
instances used to retrieve the model instance from the database.
AssertInsert.assert_fields
¶
A list of DjangoField
instances used to assert the inserted model has the correct values.
AssertInsert.defines_variable_name
¶
A string representing the variable name created by this step. For example "user"
.
AssertResponseJson
¶
The AssertResponseJson
step represents an assertion that a response
created by a DjangoTestClient
step has a given json body.
AssertResponseJson.response_json
¶
The expected body of the response, decoded from json.
AssertStatusCode
¶
The AssertStatusCode
step represents an assertion that a response
created by a DjangoTestClient
step has a given status code.
AssertStatusCode.status_code
¶
The expected status code integer. For example, 200
.
AssertTemplateUsed
¶
The AssertTemplateUsed
step represents an assertion that a response
created by a DjangoTestClient
step was generated using a particular template.
AssertTemplateUsed.template_name
¶
The name of the template. For example, "users/profile.html"
.
AssertUpdate
¶
The AssertUpdate
step represents an assertion that a Django model instance has been updated.
AssertUpdate.model
¶
The name of the Django model. For example, "User"
.
AssertUpdate.fields
¶
A list of DjangoField
instances used to assert the updated model has the correct values.
AssertUpdate.references_variable_name
¶
A string representing the variable name used by this step. For example "user"
. This is expected to be created by an earlier step.
Code
¶
The Code
step represents an arbitrary chunk of code. It can be used when no other step is suitable.
Code.code
¶
A string representing the code.
Code.imports
¶
A set
of Import
instances used to add required imports to the generated test. Defaults to an empty set.
CodeComment
¶
The CodeComment
step represents a comment in the source code of the generated test.
CodeComment.comment
¶
The text of the comment. For example, "Generated by Kolo"
.
DjangoTestClient
¶
The DjangoTestClient
step represents a call to the Django test client.
DjangoTestClient.method
¶
The name of the http method used by the request. For example, get
or post
.
DjangoTestClient.path_info
¶
The url fragment for the view being called by the test client. For example, "/users/"
.
DjangoTestClient.query_params
¶
The request params used by a GET
call. For example, {"name": "Kolo"}
.
DjangoTestClient.request_body
¶
The request body used by a POST
, PUT
or PATCH
call. For example, {"name": "Kolo"}
.
DjangoTestClient.headers
.¶
A dictionary containing any request headers to include in the test client call. For example, {"user-agent": "curl/7.79.1"}
.
EmptyLine
¶
The EmptyLine
step represents an empty line of source code in the generated test.
FactoryCreate
¶
The FactoryCreate
step represents the creation of a Django model instance with a factory boy factory.
FactoryCreate.module
¶
The module where the factory lives. For example, "users.tests.factories"
.
FactoryCreate.factory
¶
The name of the factory. For example, "UserFactory"
.
FactoryCreate.fields
¶
A list of DjangoField
instances defining the created model instance.
FactoryCreate.defines_variable_name
¶
A string representing the variable name created by this step. For example "user"
.
ModelCreate
¶
The ModelCreate
step represents the creation of a Django model instance.
ModelCreate.module
¶
The module where the model lives. For example, "django.contrib.auth.models"
.
ModelCreate.model
¶
The name of the model. For example, "User"
.
ModelCreate.fields
¶
A list of DjangoField
instances defining the created model instance.
ModelCreate.defaults
¶
A list of DjangoField
instances passed as the defaults
argument to get_or_create
.
ModelCreate.defines_variable_name
¶
A string representing the variable name created by this step. For example "user"
.
ModelCreate.method
¶
The name of the Django manager method used to create the model. Defaults to get_or_create
.
ModelUpdate
¶
The ModelUpdate
step represents an update to an already created Django model.
ModelUpdate.model
¶
The name of the Django model. For example, "User"
.
ModelUpdate.fields
¶
A list of DjangoField
instances used to update the model.
ModelUpdate.references_variable_name
¶
A string representing the variable name used by this step. For example "user"
. This is expected to be created by a ModelCreate
step.
ModuleImports
¶
The ModuleImports
step represents a location in the generated test where imports defined by other steps should be placed.
RegisterMocket
¶
The RegisterMocket
step represents the configuration of mocket
to mock http calls.
RegisterMocket.method
¶
The http method of the mocked endpoint. For example, GET
.
RegisterMocket.url
¶
The url of the mocked endpoint. For example, "https://example.com"
.
RegisterMocket.status_code
¶
The status code for mocket to return. For example, 200
.
RegisterMocket.body
¶
The body of the mocked response. For example, "<p>Hello world!</p>"
. Defaults to None
.
RegisterMocket.json_body
¶
The body of the mocked response for a json endpoint. This should be a python object that can be serialized as json. For example, {"foo": False}
. Defaults to None
.
RegisterMocket.content_type
¶
The content type of the mocked response. For example, "text/plain"
. Defaults to ""
.
StartTimeTravel
¶
The StartTimeTravel
represents a context manager configuring time-machine
or freezegun
to mock time during the generated test. It must always be paired with an EndTimeTravel
step to mark the end of the indented block.
StartTimeTravel.call
¶
The time travel function to call. Either time_machine.travel
or freezegun.freeze_time
.
StartTimeTravel.args
¶
A tuple containing the function arguments to the time travel function. For example, ('"2024-05-29T12:54:42"',)
or ('"2024-05-29T12:54:42"', "tick=True")
.
StartTimeTravel.imports
¶
A set
of Import
instances used to add required imports to the generated test. Either {Import("import time_machine")}
or {Import("import freezegun")}
.
TestClass
¶
The TestClass
step represents a test class in the unittest
style. It must always be paired with an EndTestClass
step to mark the end of the indented block.
TestClass.name
¶
The name of the generated test class. For example, "MyTestCase"
.
TestClass.parents
¶
A tuple containing the parent classes of the generated test class. For example, ("TestCase",)
.
TestClass.imports
¶
A set
of Import
instances used to add required imports to the generated test. For example, {Import("from django.test import TestCase")}
.
TestFunction
¶
The TestFunction
step represents a test function in the pytest
style. It must always be paired with an EndTestFunction
step to mark the end of the indented block.
TestFunction.name
¶
The name of the test function. For example, "test_my_view"
.
TestFunction.fixtures
¶
A tuple containing any pytest fixtures for use in the test. For example, ("client",)
.
TestMethod
¶
The TestMethod
step represents a test method in the unittest
style. It must always be paired with an EndTestMethod
step to mark the end of the indented block.
TestMethod.name
¶
The name of the test method. Defaults to "test_my_view"
.
With
¶
The With
step represents a context manager. It must always be paired with an EndWith
step to mark the end of the indented block.
With.call
¶
The name of the context manager. For example, "pytest.raises"
.
With.args
¶
A tuple containing any arguments passed to the context manager. For example, ("ValueError", 'match="must be 0 or None"')
.
With.defines_variable_name
¶
A string representing the variable name created by this step. For example "exc_info"
.
With.imports
¶
A set
of Import
instances used to add required imports to the generated test. For example, {Import("import pytest")}
.
DjangoField
¶
The DjangoField
class is a helper class representing a Django field that is used by another step.
DjangoField.name
¶
The name of the field. For example, "username"
.
DjangoField.value
¶
The repr
of the value of the field. For example, '"admin"'
.
DjangoField.imports
¶
A set
of Import
instances used to add required imports to the generated test. For example, {Import("from decimal import Decimal")}
.
Import
¶
The Import
class is a helper class representing an import that will be included in the generated test by the ModuleImports
step.
Import.import_path
¶
The import to be include in the test. For example, "from datetime import date"
.
Step
¶
The Step
class can be subclassed to define a custom step.
Step.indent_delta
¶
This class attribute marks a change in the indentation level of the generated code. Steps that start an indented block should set this to 1
. Steps that end an indented block should set this to -1
. All other steps can inherit the default value of 0
.
Step.render
¶
A Step
subclass must define a render
method that defines how that step should be rendered in the generated test. This method takes a boolean pytest
argument to allow the rendered step to differ between pytest and unittest style tests. It must return a string.
For example:
from kolo.generate_tests.steps import Step
@dataclass()
class AssertGreater(Step):
left: str
right: str
def render(self, pytest):
if pytest:
return f"assert {self.left} > {self.right}\n"
return f"self.assertGreater({self.left}, {self.right})\n"
Step.get_imports
¶
A Step
subclass may define a get_imports
method that returns a set
of Import
instances for inclusion in the generated test. This method takes a boolean pytest
argument to allow different imports for pytest and unittest style tests.
For example:
from kolo.generate_tests.steps import Step
@dataclass()
class AssertTemplateNotUsed(Step):
template_name: str
def render(self, pytest):
if pytest:
assertTemplateNotUsed = "assertTemplateNotUsed"
else:
assertTemplateNotUsed = "self.assertTemplateNotUsed"
return f"{assertTemplateNotUsed}(response, {repr(self.template_name)})\n"
def get_imports(self, pytest):
if pytest:
return {Import("from pytest_django.asserts import assertTemplateNotUsed")}
return set()
Step.get_steps
¶
A Step
subclass that represents the start of a section should define a get_steps
classmethod that returns the start step, the end step and all steps in between. This is used to determine which steps are passed to a step_hook
targetting this start step. The get_steps_slice
helper function is available to make implementing this easy:
from kolo.generate_tests.steps import Step, get_steps_slice
@dataclass()
class Start(Step):
indent_delta = 1
@classmethod
def get_steps(cls, steps):
return get_steps_slice(cls, End, steps)
@dataclass()
class End(Step):
indent_delta = -1