class TestEventViewSet(APIViewTest): url = static_fixture(reverse("api_v1:orders:event-list")) data = lambda_fixture(lambda order_with_item: { "order": order_with_item.pk, "limit": 10, "offset": 0 }) def test_response(self, order_with_item, json, response): # I use the direct status_code check because the DRF test is just an # abstraction for checking what the REST Framework returns. If I stop # using the tool, there will be less rewriting left for me. # For pytest_drf, we can use the Returns200 mixin to test the response code. assert response.status_code == HTTPStatus.OK assert json["count"] == order_with_item.events.count() > 0 assert_that( json["results"], only_contains( has_entries({ "id": instance_of(int), "event_type": instance_of(str), "subtype": any_of(instance_of(str), none()), "user": none(), "difference": any_of(instance_of(str), none()), })))
def __call__(cls, *args, **kwargs) -> Type['ReturnsStatus']: if cls is not ReturnsStatus: return super().__call__(*args, **kwargs) status_code, = args # We create a copy of this method, so we can change its name to # include the expected status code. def test_it_returns_expected_status_code(self, response, expected_status_code): expected = expected_status_code actual = response.status_code assert expected == actual test_it_returns_expected_status_code.__name__ = f'test_it_returns_{status_code}' returns_code_cls = type( f'Returns{status_code}', (), { f'test_it_returns_{status_code}': test_it_returns_expected_status_code, 'expected_status_code': static_fixture(status_code), # Disable the original method 'test_it_returns_expected_status_code': None, }) return returns_code_cls
class ContextSearch( Returns200, ): matching_movies = lambda_fixture( lambda: Movie.objects.bulk_create([ Movie(title='Forty-Two Monkeys', year=1997), ])) non_matching_movies = lambda_fixture( lambda: Movie.objects.bulk_create([ Movie(title="Alfred Hitchcock's The Byrds: A Biopic", year=1975), ])) movies = lambda_fixture( lambda matching_movies, non_matching_movies: (matching_movies + non_matching_movies), autouse=True, ) query_params = static_fixture({ 'q': 'monkey', }) def it_returns_only_matching_movies(self, matching_movies, results): expected = express_movies(matching_movies) actual = results assert expected == actual
class DescribeUpdate( UsesPatchMethod, UsesDetailEndpoint, Returns200, ): # NOTE: autouse=True is not used, because the detail_url requests this # fixture key_value = lambda_fixture(lambda: KeyValue.objects.create( key='apple', value='π', )) data = static_fixture({ 'key': 'banana', 'value': 'ρ', }) ### # precondition_fixture uses the pytest dependency graph to ensure that, # if requested, this fixture is *always* evaluated before our HTTP request # is made. # # Here, we record the existing KeyValue IDs, so we can verify that no # new rows are created by our endpoint. We request the `key_value` fixture, # to ensure it's included in this set. # initial_key_value_ids = precondition_fixture(lambda key_value: set( KeyValue.objects.values_list('pk', flat=True))) def it_updates_key_value(self, key_value, data): # After updating, refreshing our DB row is vital — otherwise, it # will appear as though our endpoint is not doing its job. key_value.refresh_from_db() expected = data assert_model_attrs(key_value, expected) def it_returns_key_value(self, key_value, json): # After updating, refreshing our DB row is vital — otherwise, it # will appear as though our endpoint is not doing its job. key_value.refresh_from_db() expected = express_key_value(key_value) actual = json assert expected == actual def it_doesnt_create_or_destroy_rows(self, initial_key_value_ids): expected = initial_key_value_ids actual = set(KeyValue.objects.values_list('pk', flat=True)) assert expected == actual
class DescribeHeaders( APIViewTest, UsesGetMethod, ): # NOTE: this view simply returns the request's headers as the response url = lambda_fixture(lambda: url_for('views-headers')) # This fixture supports passing headers (e.g. `Authorization: Api-Key 123`) in the request headers = static_fixture({ 'Custom-Header': 'abc', 'Head': 'Shoulders, Knees, Toes', }) def it_passes_headers(self, json, headers): expected = headers actual = json assert_dict_is_subset(expected, actual)
class DescribeData( APIViewTest, UsesPostMethod, ): # NOTE: this view simply returns the request's POST data as the response url = lambda_fixture(lambda: url_for('views-data')) # This fixture supports passing POST data in the request data = static_fixture({ 'post': 'malone', 'fizzbuzz': 'zibbzuff', }) def it_posts_data(self, json, data): expected = data actual = json assert expected == actual
class DescribeQueryParams( APIViewTest, UsesGetMethod, ): # NOTE: this view simply returns the request's query params as the response url = lambda_fixture(lambda: url_for('views-query-params')) # This fixture supports passing query params (e.g. ?key=val) with the requested URL query_params = static_fixture({ 'key': 'val', 'param': 'value', 'pink': 'floyd', }) def it_passes_query_params(self, json, query_params): expected = query_params actual = json assert expected == actual
class DescribeCreate( UsesPostMethod, UsesListEndpoint, Returns201, ): data = static_fixture({ 'key': 'apple', 'value': 'π', }) ### # precondition_fixture uses the pytest dependency graph to ensure that, # if requested, this fixture is *always* evaluated before our HTTP request # is made. # # Here, we record the existing KeyValue IDs, so we can verify that a # new row was indeed created by our endpoint. # initial_key_value_ids = precondition_fixture( lambda: set(KeyValue.objects.values_list('pk', flat=True))) def it_creates_key_value(self, initial_key_value_ids, json): expected = initial_key_value_ids | {json['id']} actual = set(KeyValue.objects.values_list('pk', flat=True)) assert expected == actual def it_returns_key_value(self, json): key_value = KeyValue.objects.get(pk=json['id']) expected = express_key_value(key_value) actual = json assert expected == actual def it_sets_model_fields(self, data, json): key_value = KeyValue.objects.get(pk=json['id']) expected = data assert_model_attrs(key_value, expected)
class Case204(Returns204): status_code = static_fixture(204)
class UsesPutMethod: http_method = static_fixture('put')
class UsesPatchMethod: http_method = static_fixture('patch')
class Case504(Returns504): status_code = static_fixture(504)
class Case429(Returns429): status_code = static_fixture(429)
class Case409(Returns409): status_code = static_fixture(409)
class UsesPostMethod: http_method = static_fixture('post')
class CaseArbitrary(ReturnsStatus(599)): status_code = static_fixture(599)
import logging import pytest from pytest_lambda import lambda_fixture, static_fixture from linked_list import BasicLinearLinkedList logger = logging.getLogger(__name__) nodes = lambda_fixture(lambda single_link_node_factory: single_link_node_factory.create_batch(size=10)) empty_list = lambda_fixture(lambda: BasicLinearLinkedList()) items_to_add = static_fixture([(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]) @pytest.fixture def list_with_nodes(nodes): for current, next_node in zip(nodes, nodes[1:]): current.next = next_node linear_linked_list = BasicLinearLinkedList() linear_linked_list.head = nodes[0] linear_linked_list.length = 10 return linear_linked_list class TestBasicLinearLinkedList: class ContextValidKey:
from pytest_lambda import lambda_fixture, static_fixture unique = lambda_fixture(lambda: 'unique') def it_processes_toplevel_lambda_fixture(unique): expected = 'unique' actual = unique assert expected == actual unique_static = static_fixture('unique') def it_processes_toplevel_static_fixture(unique_static): expected = 'unique' actual = unique_static assert expected == actual unique_alias = lambda_fixture('unique_static') def it_processes_toplevel_aliased_lambda_fixture(unique_alias): expected = 'unique' actual = unique_alias assert expected == actual a = static_fixture('a') b = static_fixture('b')
import pytest from pytest_lambda import static_fixture, lambda_fixture my_toplevel_static_fixture = static_fixture(123) @pytest.fixture def caret(my_toplevel_static_fixture): return 20 @pytest.mark.parametrize('v', [ pytest.param(1), ]) def test_stuff(v): a = v a = lambda_fixture(lambda : 123) class TestStuff: caret = lambda_fixture('caret') def test_it(self, caret, my_toplevel_static_fixture): assert caret a = caret b = my_toplevel_static_fixture def it_does_things(self, caret): pass
class UsesDeleteMethod: http_method = static_fixture('delete')
class Case308(Returns308): status_code = static_fixture(308)
class UsesGetMethod: http_method = static_fixture('get')